【问题标题】:How to make my buttons respond to clicks?如何让我的按钮响应点击?
【发布时间】:2019-02-02 21:26:26
【问题描述】:

我想为桌面应用程序创建 Python GUI。我用 Tkinter 设计了这个:

两个按钮用于执行命令和退出应用程序,Button one 是继续执行代码,Button two 是退出。但 GUI 没有响应。

在执行进程时按下button two不会退出应用程序,按下button 1不会触发函数def clicked()中的代码。

有没有更好的方法可以在程序运行时退出(比如中断?)

在 Tkinter 中,我们可以在不按下按钮的情况下传递值。 (过程正在重复,但我只需要按一个按钮,需要在显示 GUI 时自动执行)

def GUI():

   window =Tk()
   window.title("Select First Color")
   selected = IntVar()   

   rad1 = Radiobutton(window, text='RED', value=1, variable=selected)     
   rad2 = Radiobutton(window, text='YELLOW', value=2, variable=selected)

        def clicked():   
             # Go to a function according to the selection of radio button

   button1 = Button(window, text="Select", command=clicked)                    
   button2 = Button(window, text="Quit", command=window.destroy)

   rad1.grid(column=0, row=0)              # GUI RadioButton Placement
   rad2.grid(column=1, row=0)
   button1.grid(column=6, row=0)               # GUI Button Placement
   button2.grid(column=6, row=1)

window.mainloop()

【问题讨论】:

  • 问题不清楚。能说清楚点吗?
  • 这用于图像处理。当从单选按钮中选择红色时,它将仅检测红色区域,而黄色仅检测黄色区域。但是当进程在def Clicked():最后很难退出(没有响应)时,如果系统检测到区域超过一定值,则应根据选择的单选按钮重复处理
  • 如果程序没有响应,您不能使用 tkinter GUI 退出它,即 GUI 中的按钮。因为那也将无响应。您必须在终端中通过 Ctrl + CCtrl + Z 将其关闭。如果你只想用一个按钮关闭程序。您可以将退出按钮的命令更改为sys.exit。也别忘了import sys

标签: python user-interface button tkinter


【解决方案1】:

Tkinter 是单线程的,这意味着它一次只能做一件事。如果您的函数 clicked 需要很长时间,则 tkinter 在运行时无法响应事件。

您唯一的选择是将clicked 完成的工作移到单独的线程或进程中,或者对其进行重构,以便它定期调用update 方法,让tkinter 有机会处理事件队列.

请参阅此问题以获得更多帮助:Tkinter: How to use threads to preventing main event loop from "freezing"

【讨论】:

    【解决方案2】:

    1- 你永远不会打电话给你的GUI
    2- 在函数内部定义的变量具有局部作用域,它们不能在外部访问,除非您在全局作用域中声明它们,并使用global 更改它们的值。

    以下内容符合您的预期:

    当没有选择单选按钮时,click 打印 0
    选择“红色”单选按钮时,click 987654326 @
    选择“黄色”按钮时,click打印2
    您可以使用这些值将调用重定向到另一个函数。

    import tkinter as tk
    
    
    def do_nothing():
        pass
    
    
    def do_red():
        print('doing the red thing')
    
    
    def do_yellow():
        print('doing the yellow thing')
    
    
    def clicked():
        print(f'clicked {selected.get()}')
        v = selected.get()
        if v == 0:
            do_nothing()
        elif v == 1:
            do_red()
        elif v == 2:
            do_yellow()
        else:
            print('an error occurred, the wrong value was recieved')
    
    
    def GUI():
    
        global rad1, rad2, selected
    
        window = tk.Tk()
        window.title("Select First Color")
        selected = tk.IntVar()   
    
        rad1 = tk.Radiobutton(window, text='RED', value=1, variable=selected)     
        rad2 = tk.Radiobutton(window, text='YELLOW', value=2, variable=selected)
    
        button1 = tk.Button(window, text="Select", command=clicked)                    
        button2 = tk.Button(window, text="Quit", command=window.destroy)
    
        rad1.grid(column=0, row=0)
        rad2.grid(column=1, row=0)
        button1.grid(column=6, row=0)
        button2.grid(column=6, row=1)
    
        window.mainloop()
    
    
    rad1, rad2, selected = None, None, None
    GUI()
    

    或者,您可以使用类来避免全局变量:

    import tkinter as tk
    
    
    def do_nothing():
        pass
    
    
    def do_red():
        print('doing the red thing')
    
    
    def do_yellow():
        print('doing the yellow thing')
    
    
    class GUI(tk.Tk):
    
        def __init__(self):
            super().__init__()
            self.title("Select First Color")
            self.selected = tk.IntVar()
            self.selected.set(0)
    
            self.rad1 = tk.Radiobutton(self, text='RED', value=1, variable=self.selected)     
            self.rad2 = tk.Radiobutton(self, text='YELLOW', value=2, variable=self.selected)
    
            self.button1 = tk.Button(self, text="Select", command=self.clicked)                    
            self.button2 = tk.Button(self, text="Quit", command=self.destroy)
    
            self.rad1.grid(column=0, row=0)
            self.rad2.grid(column=1, row=0)
            self.button1.grid(column=6, row=0)
            self.button2.grid(column=6, row=1)
    
            self.mainloop()
    
        def clicked(self):
            print(f'clicked {self.selected.get()}')
    
            v = self.selected.get()
            if v == 0:
                do_nothing()
            elif v == 1:
                do_red()
            elif v == 2:
                do_yellow()
            else:
                print('an error occurred, the wrong value was received')
    
    
    GUI()
    

    【讨论】:

    • 我担心实际的clicked() 比你编造的版本需要更多的时间来运行。添加time.sleep(60),看看是否可以在点击“选择”后不到一分钟的时间内关闭窗口..
    • 也许,谁知道呢?当它发布时,GUI 甚至都没有启动,更不用说响应事件了......此外,无论 clicked 操作没有以任何有用的方式发布、解释或描述。
    • @ReblochonMasque 谢谢。当然,我会很好地解释下一个问题。
    • @ReblochonMasque 谢谢你,我投了你的票,但不幸的是,我的投票不被认为是低声誉(因为是社区的新手)
    【解决方案3】:

    我想这就是你要找的东西

    button2 = Button(window, text="Quit", command=sys.exit)
    

    【讨论】:

    • 感谢@ruohola,但问题是,def clicked() 中的处理时 GUI 没有响应
    • @Sanjaya 那么你需要让 clicked() 函数在另一个线程中执行。
    猜你喜欢
    • 2017-10-13
    • 2011-11-01
    • 1970-01-01
    • 1970-01-01
    • 2019-06-18
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多