Попытка включить кнопку с помощью виджета ввода - PullRequest
0 голосов
/ 28 июня 2019

У меня есть два набора кода. Один работает, другой нет, и я не знаю почему. В первом наборе кода я храню свое приложение в классе и ссылаюсь на все там. Во втором я храню все в основной функции и использую ее там.

Основные детали проблемы здесь:

Я использую виджет ввода и виджет кнопки, который изначально отключен. Я хочу, чтобы состояние кнопки было нормальным, когда в текстовом поле виджетов ввода есть текст.

Я искал в Интернете много ответов на первый набор кода, но самый близкий, который я получил, - второй набор кода. Сначала я попытался интегрировать его в мой код, однако это не сработало. Поэтому я взял код, обрезал его до минимума и поместил все в основную функцию.

Основное различие между ними состоит в том, что один находится в классе, а другой - в главной функции.

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 ]

1 голос
/ 28 июня 2019

Вы должны использовать self. для создания переменных класса, чтобы они были доступны во всех методах класса.В настоящее время вы создаете локальную переменную something в __init__, и она удаляется, когда Python завершает __init__ - так, наконец, он удаляет something.trace() и не проверяет значение в записи.

В этом коде яиспользуйте self.something и self.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()
0 голосов
/ 28 июня 2019

Как указал @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()
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...