尝试使用输入小部件启用按钮

时间:2019-06-27 22:55:16

标签: python tkinter

我有两组代码。一个有效,另一个无效,我也不知道为什么。在第一组代码中,我将应用程序存储到一个类中,并在其中引用所有内容。在第二个中,我将所有内容存储在main函数中并在其中使用。

问题的主要细节在这里:

我正在使用一个入口小部件和一个最初禁用的按钮小部件。我希望输入小部件文本字段中有文本时按钮的状态正常。

我在网上搜索了第一组代码的许多答案,但我得到的最接近的是第二组代码。首先,我尝试将其集成到我的代码中,但这没有用。所以我要做的就是拿代码,将其剥离到最低限度,然后将所有内容放入主函数中。

两者之间的主要区别是,一个是在类中,另一个是在主函数中。

import tkinter as tk

class Aplication(tk.Frame):
    def __init__(self, master):
        tk.Frame.__init__(self,master)
        self.grid()
        self.button_clicks = 0

        something = tk.StringVar()
        button3 = tk.Button(self, text="Print entry", padx = 10, height = 2, bg = "blue", state = "disabled")

        entry = tk.Entry(self, textvariable = something)
        something.trace('w', self.ActivateButton)     #need this to always be exsecuted
        entry.grid(column = 2, row = 1)

        button3["command"] = lambda: self.PrintEntry(entry.get())
        button3.grid(padx = 10, pady = 10)

    def PrintEntry (self, entry):
            print(entry)
        def ActivateButton(self, *_):
            if something.get():
                button3['state'] = "normal"
            else:
                button3['state'] = "disabled"

if __name__ == '__main__':
    top= tk.Tk()
    top.title("Simple Button")
    top.geometry("500x300")

    app = Aplication(top)

    top.mainloop()

def PrintEntry (entry):
    print(entry)

def ActivateButton(*_):
    if entry.get():
        button3['state'] = "normal"
    else:
        button3['state'] = "disabled"

if __name__ == '__main__':
    top= tk.Tk()
    top.title("Simple Button")
    top.geometry("500x300")

    something = tk.StringVar()
    button3 = tk.Button(top, text="Print entry", padx = 10, height = 2, bg = "blue", state = "disabled")

    entry = tk.Entry(top, textvariable = something, bd = 2)
    something.trace('w', ActivateButton)
    entry.grid(column = 2, row = 3)

    button3["command"] = lambda: PrintEntry(entry.get())
    button3.grid(row = 3, column = 1, padx = 10, pady = 10)

    top.mainloop()

没有错误消息;但是在第一组中,按钮的状态永远不会设置为正常。有第一种方法吗?两者之间有什么区别?如果不可能,我无法在第一个按钮中启用该按钮?

2 个答案:

答案 0 :(得分:1)

您必须使用self.创建类变量,这样它们才能在类中的所有方法中使用。当前,您在something中创建了局部变量__init__,并在Python结束__init__时删除了该变量,因此最终它删除了something.trace(),并且不检查输入值。

在此代码中,我使用self.somethingself.button3,它可以正常工作。

import tkinter as tk

class Aplication(tk.Frame):
    def __init__(self, master):
        tk.Frame.__init__(self,master)
        self.grid()
        self.button_clicks = 0

        self.something = tk.StringVar()
        self.button3 = tk.Button(self, text="Print entry", padx = 10, height = 2, bg = "blue", state = "disabled")

        entry = tk.Entry(self, textvariable = self.something)
        self.something.trace('w', self.ActivateButton)     #need this to always be exsecuted
        entry.grid(column = 2, row = 1)

        self.button3["command"] = lambda: self.PrintEntry(entry.get())
        self.button3.grid(padx = 10, pady = 10)
    def PrintEntry (self, entry):
        print(entry)
    def ActivateButton(self, *_):
        if self.something.get():
            self.button3['state'] = "normal"
        else:
            self.button3['state'] = "disabled"

if __name__ == '__main__':
    top= tk.Tk()
    top.title("Simple Button")
    top.geometry("500x300")

    app = Aplication(top)

    top.mainloop()

编辑:相同之处略有不同-没有lambda。我直接在self.entry中使用print_entry(作为类变量)。

import tkinter as tk

class Aplication(tk.Frame):

    def __init__(self, master):
        super().__init__(master)#tk.Frame.__init__(self,master)
        self.grid()
        self.button_clicks = 0

        self.something = tk.StringVar()

        self.entry = tk.Entry(self, textvariable=self.something)
        self.entry.grid(column=2, row=1)

        self.button3 = tk.Button(self, command=self.print_entry, text="Print entry", padx=10, height=2, bg="blue", state="disabled")
        self.button3.grid(padx=10, pady=10)

        self.something.trace('w', self.activate_button) #need this to always be exsecuted

    def print_entry(self):
        print(self.entry.get())

    def activate_button(self, *_):
        if self.something.get():
            self.button3['state'] = "normal"
        else:
            self.button3['state'] = "disabled"

if __name__ == '__main__':
    top= tk.Tk()
    top.title("Simple Button")
    top.geometry("500x300")

    app = Aplication(top)

    top.mainloop()

答案 1 :(得分:0)

正如@furas指出的那样,您需要在构造函数方法def __init__中的变量前面加上self.,以便可以访问属性和方法,因为它从字面上表示该类的实例。该链接对其进行了更详细的说明https://stackoverflow.com/a/2709832/7585554

import tkinter as tk


class Application(tk.Frame):
    def __init__(self, master):
        tk.Frame.__init__(self, master)
        self.grid()
        self.button_clicks = 0

        self.something = tk.StringVar()
        self.button3 = tk.Button(self, text="Print entry", padx=10, height=2, bg="blue", state="disabled")

        self.entry = tk.Entry(self, textvariable=self.something)
        self.something.trace('w', self.ActivateButton)
        self.entry.grid(column=2, row=1)

        self.button3["command"] = lambda: self.PrintEntry()
        self.button3.grid(padx=10, pady=10)

    def PrintEntry (self):
        print(self.entry.get())

    def ActivateButton(self, *_):
        if self.something.get():
            self.button3['state'] = "normal"
        else:
            self.button3['state'] = "disabled"


if __name__ == '__main__':
    top = tk.Tk()
    top.title("Simple Button")
    top.geometry("500x300")
    app = Application(top)
    top.mainloop()