【问题标题】:Multiple operations from a single button tkinter来自单个按钮 tkinter 的多项操作
【发布时间】:2012-07-09 05:39:44
【问题描述】:

我一直在使用 matplotlib 和 tkinter 为基于 GUI 的绘图仪编写程序。我为一些选项添加了一个顶层窗口。我想在单击按钮后执行一个函数并退出顶层窗口。这可能吗?


我面临的问题是我使用了一个必须从主窗口调用的顶级窗口。所以我定义了一个包含这个顶层窗口的函数。如果我定义了另一个可以执行多项操作的函数,它就无法识别顶层窗口。我可以在一个类下定义它,但不确定它是否有效。这是我的代码的一部分,其中包含顶层窗口。

def plt_options(arg):
    global lg_var,col_var,line_type_var,marker_var

    plt_opt = Toplevel(app)

    lg_var = StringVar(None)
    lg_text = Label(plt_opt,text='Legend').grid(row=0,column=0,sticky=E)
    lg_box = Entry(plt_opt,textvar=lg_var)
    lg_box.grid(row=0,column=1,sticky=W)

    col_var = StringVar(None)
    col_var.set('blue')
    col_text = Label(plt_opt,text='Color').grid(row=1,column=0)
    col_chooser = OptionMenu(plt_opt,col_var,'blue','green','red','cyan',\
           'magneta','yellow','black','white')
    col_chooser.grid(row=1,column=1)

    line_type_var = StringVar(None)
    line_type_var.set('Solid')
    line_type_text = Label(plt_opt,text='Line type').grid(row=2,column=0)
    line_chooser = OptionMenu(plt_opt,line_type_var,'Solid','Dashed',\
                          'Dotted','Dash-Dotted','None')
    line_chooser.grid(row=2,column=1)

    marker_var = StringVar(None)
    marker_var.set('None')
    marker_text = Label(plt_opt,text='Marker').grid(row=3,column=0)
    marker_chooser = OptionMenu(plt_opt,marker_var,'Plus','Dot','Circle',\
        'Star','Pentagon','Square','Cross','Diamond','Hexagon','Triangle')
    marker_chooser.grid(row=3,column=1)    

    ok_btn = Button(plt_opt,text='OK',command=testing).grid()

【问题讨论】:

    标签: python tkinter


    【解决方案1】:

    按钮的command 选项可让您指定按下按钮时将调用的函数/方法/可调用对象。

    from Tkinter import *
    
    def buttonClicked(event):
        do_a_thing()
        do_another_thing()
        do_a_third_thing()
        #etc
    
    root = Tk()
    
    myButton = Button(root, text="Do Some Things", command=buttonClicked)
    myButton.pack()
    
    root.mainloop()
    

    您可以通过调用其destroy 方法来退出窗口。

    您似乎还有另一个问题,即如果您不在创建窗口的范围内,则无法从回调函数内部销毁顶级窗口。如果你不想定义一个完整的类来保存对窗口的引用,你可以嵌套你的函数定义:

    from Tkinter import *
    
    def makeMyWindow():
        root = Tk()
        def buttonClicked():
            print "Reticulating Splines..."
            print "Done. Goodbye!"
            #we can access root since we're inside the right scope, 
            #even if this function gets passed somewhere else as a callback
            root.destroy()
        myButton = Button(root, text="Do Some Things", command=buttonClicked)
        myButton.pack()
    
        root.mainloop()
    
    makeMyWindow()
    

    【讨论】:

    • 在按钮的情况下,这更容易:myButton = Button(root, text="Do Some Things",command=buttonClicked)(看妈妈,不是bind!)
    • 您不应该在按钮上设置<1> 绑定;使用内置的command 属性。否则,您将绕过 Tkinter 的一些功能,例如使用键盘导航应用程序并通过按下按钮调用按钮(等等)
    • @Kevin:现在您的第一句话说您可以添加绑定,但您的示例与绑定没有任何关系。对于刚接触 Tkinter 的人来说,这可能有点令人困惑。
    【解决方案2】:

    按钮正是为此而设计的。通常你会定义一个函数或方法来做任何你想做的事情,然后将该方法分配给按钮的command 属性:

    import Tkinter as tk
    import tkMessageBox
    
    class SampleApp(tk.Tk):
        def __init__(self):
            tk.Tk.__init__(self)
            button = tk.Button(text="Press me!", command=self.on_button)
            button.pack()
        def on_button(self):
            tkMessageBox.showinfo(message="Good-bye!")
            self.destroy()
    
    app = SampleApp()
    app.mainloop()
    

    【讨论】:

    • 我可以构造一个定义顶层窗口的类和一个可以同时执行多个操作的函数吗?那就是没有为父窗口构建一个单独的类。
    • @gaurabrimal:是的,当然。按钮可以调用函数,函数的作用没有限制。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-11-29
    • 1970-01-01
    • 2012-03-26
    • 2021-12-30
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多