为什么我的按钮只能在Python中使用一次?

时间:2014-01-14 15:23:53

标签: python button tkinter

我创建了一个按钮,可以在单击时调用main_menu函数,但只能单击一次。单击它时,它会将用户带回主菜单,但如果用户离开主菜单并再次单击它,它什么都不做。

def __init__(self):
    self.main = main
    self.main.grid()

    <Really long tuple declared here>

    self.main_menu()

def main_menu(self):
    self.main.grid_remove()
    main = Frame(root)
    self.main = main
    self.main.grid()

    self.sort_button = Tkinter.Button(main, text = "Sort the list using the bubble sort method", command = self.sort_choice)

    <Some more buttons coded here>

    self.sort_button.pack()


def sort_choice(self):
    self.main.grid_remove()
    main = Frame(root)
    self.main = main
    self.main.grid()

    <Some other buttons and messages coded here>

    self.main_menu.pack()

如何让按钮多次工作?

1 个答案:

答案 0 :(得分:1)

如评论中所述,发布的代码不表示预期的行为,并且可能应该更改代码的整个结构(以及要使用的正确命名)。我尝试清除一些概念,但是这个答案并没有使这段代码有效(甚至可能无法执行)。

如果您正在使用全局变量(我假设 main 应该是一个全局变量),当您想要在函数内更改它们的值时,您需要使用 global <声明它们/ em>构造。否则,更改函数中全局变量的值将创建一个具有相同名称的局部变量,并且不会影响全局变量。

以下是清除此内容的简单代码段:

val = "x"                                 

def use_global():                         
    print "Global value is: %s" % val        

def change_global_wrong():                
    print "changing global in change_global_wrong"
    val = "y"                             
    print "global in change_global_wrong is: %s" % val 

def change_global_correct():              
    global val                            
    print "changing global in change_global_correct"
    val = "y"                             
    print "global in change_global_correct is: %s" % val                                                                                                                                                                                                                       

use_global()
change_global_wrong()
use_global()                   
change_global_correct()
use_global()

因此,更改函数内 main 的值实际上是创建了在返回每个函数时将超出范围的局部变量。 这意味着您对框架的唯一引用是 self.main 。所以我建议将其注册为按钮的父级。

self.sort_button = Tkinter.Button(self.main, text = "Sort the list using the bubble sort method", command = self.sort_choice)

即使这样做,也可以通过调用self.main.grid_remove()来删除Frame对象。这会导致Frame(及其子窗口小部件)被删除。在这里,我为Tk应用程序添加了一个代码示例(并在评论中指定,包括一种打破它的方法):

#!/usr/bin/env python
import datetime
from Tkinter import *

class MyApp(object):
    def __init__(self):
        self.root = Tk()
        self.time_var = StringVar()
        self.time_var.set('...')
        self._init_widgets()

    def _init_widgets(self):
        self.label = Label(self.root, textvariable=self.time_var)
        frame = Frame(self.root)
        self.frame = frame
        self.button = Button(frame, text = "update time", command = self._on_button_click)
        self.frame.grid()
        self.button.grid()
        self.label.grid()

    def _on_button_click(self):
        self.time_var.set(str(datetime.datetime.now()))
        # uncomment these lines to get a broken code
        #self.frame.grid_remove()
        #self.frame = Frame(self.root)
        #self.frame.grid()

    def run(self):
        self.root.mainloop()

if __name__ == '__main__':
    app = MyApp()
    app.run()

现在,如果取消注释坏行,您会看到调用grid_remove()删除Frame但是创建一个新的Frame对象(并将其分配给相同的引用)并不能帮助我们恢复。因为旧框架上有一个漂亮的按钮就消失了。而更新时间的漂亮按钮也与父母一起消失了。

我不确定这个问题中的代码是否实际运行(因为它缺少上下文和其他行),但如果它运行,我希望通过单击按钮,框架小部件正在删除按钮也应该从小部件中删除(创建新框架不应该恢复按钮)。

由于没有发生这种情况(正如你所说按钮显示但没有动作),我在这里总结了已发布的代码行并没有正确表达你的情况。但我希望这些代码示例可以帮助您更好地了解您的应用程序。