Метка Tkinter, ссылающаяся на переменную, не обновляется при изменении переменной - PullRequest
0 голосов
/ 08 января 2019

У меня проблема с tkinter, когда метка ссылается на значение, и я обновляю значение, нажимая кнопку. Значение действительно обновлено, но текст метки, ссылающийся на это значение, не является.

Как изменить этот код, чтобы кнопка обновляла значение, а метка, ссылающаяся на это значение, обновлялась и отображалась в root?

import tkinter

root = Tk()
root.title('Test Button')
root.geometry('600x450')


class Letter:
    def __init__(self, value):
        self.value = value


class Label:
    def __init__(self, master):
        self.a_label = tkinter.Label(root, text=current_letter.value)
        self.a_label.grid(row=2, column=1)

class Button:
    def __init__(self, master):

    self.Button1 = tkinter.Button(master, height = 12, width = 24,
                                  command= self.update_letter)
    self.Button1.grid(row=1, column=1)

    def update_letter(self):
        current_letter.value
        print("current_letter.value before: " + str(current_letter.value))
        current_letter.value += 1
        print("current_letter.value now: " + str(current_letter.value))
        root.update

#initialize a
a = Letter(0)
current_letter = a

b = Button(root)
l = Label(root)


root.mainloop()

Ответы [ 3 ]

0 голосов
/ 08 января 2019

Боже, какая у тебя большая кнопка.

Если вы используете tkinter Variable, то его обновление автоматически изменит то, что есть в любых виджетах, которые ссылаются на один из них. Вот некоторые документы , описывающие их, и вот некоторые другие , описывающие, как их использовать.

Вот как это можно сделать с кодом в вашем вопросе:

import tkinter

root = tkinter.Tk()
root.title('Test Button')
root.geometry('600x450')


class Letter:
    def __init__(self, value):
        self.value = tkinter.IntVar(value=value)  # Store in a tkinter Variable.


class Label:
    def __init__(self, master, letter):
        self.a_label = tkinter.Label(master, textvariable=letter.value)
        self.a_label.grid(row=2, column=1)


class Button:
    def __init__(self, master, letter):
        self.letter = letter
        self.Button1 = tkinter.Button(master, height=12, width=24,
                                      command=self.update_letter)
        self.Button1.grid(row=1, column=1)

    def update_letter(self):
        current_value = self.letter.value.get()
        print("letter.value before: " + str(current_value))
        self.letter.value.set(self.letter.value.get() + 1)
        print("letter.value now: " + str(self.letter.value.get()))


# initialize a
a = Letter(0)

b = Button(root, a)
l = Label(root, a)

root.mainloop()

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

0 голосов
/ 08 января 2019

Это потому, что вы не обновили метку l после того, как обновили current_letter. Простое решение состоит в том, чтобы изменить current_letter на IntVar и обновить класс Label и Button, как показано ниже:

class MyLabel:
    def __init__(self, master):
        self.a_label = tkinter.Label(root, textvariable=current_letter)
        self.a_label.grid(row=2, column=1)

class MyButton:
    def __init__(self, master):
        self.Button1 = tkinter.Button(master, height = 12, width = 24,
                                      command= self.update_letter)
        self.Button1.grid(row=1, column=1)

    def update_letter(self):
        value = current_letter.get()
        print("current_letter.value before: ", value)
        value += 1
        print("current_letter.value now: ", value)
        current_letter.set(value)

current_letter = tkinter.IntVar(0)

b = MyButton(root)
l = MyLabel(root)

Обратите внимание, что я удалил класс Letter, так как он не нужен. Я также переименую класс Label и Button в MyLabel и MyButton соответственно, поскольку они являются классами в tkinter.

0 голосов
/ 08 января 2019

Добро пожаловать в Stackoverflow. Прежде всего, вам не нужно создавать отдельные классы для метки и кнопки в вашей программе. Вы можете создать их внутри основного класса как tkinter виджеты. Затем, если вы хотите передать переменную экземпляра некоторого класса, вам нужно инициализировать ее и правильно передать функцию update_letter, которую вы можете использовать lambda. Вот пример кода, с которым вы можете работать:

import tkinter as tk


class UpdateLabel:


  def __init__(self, master):
      self.master = master
      # Create instance of Letter class
      a = Letter(value=0)
      current_letter = a
      self.update_button = tk.Button(master, text='Update', command=lambda:self.update_letter(current_letter))
      self.update_button.grid(row=0, column=0)

      self.label = tk.Label(master, text='No Value')
      self.label.grid(row=1, column=0)

  def update_letter(self, current_letter):
      print("current_letter.value before: " + str(current_letter.value))
      current_letter.value += 1
      print("current_letter.value now: " + str(current_letter.value))
      self.label.configure(text='Value: {}'.format(current_letter.value))

class Letter:
     def __init__(self, value):
         self.value = value


if __name__ == '__main__':
    root = tk.Tk()
    app = UpdateLabel(master=root)
    root.mainloop()

В этой ссылке Как изменить текст метки , вы можете найти другие варианты для изменения текста в tkinter label виджете. Я надеюсь, что это поможет

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...