Python и Tkinter: как установить StringVar из другого класса - PullRequest
0 голосов
/ 09 мая 2019

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

Графический интерфейс tkinter, метка, отображающая текст, и 2 кнопки ниже. Эти кнопки предназначены для изменения текста в метке, так как он связан с StringVar через параметр textvariable ...

Что должно произойти, просто: Нажмите кнопку «А» и «А» будет показано на этикетке Нажмите кнопку «B», и «B» будет отображаться на этикетке

Но когда я нажимаю кнопку «A», программа выдает мне NameError: имя 'display_frame' не определено.

Не могу понять, что происходит. Я получаю доступ к атрибуту объекта ...

obs: поскольку кнопка A является проблематичной, не пытались настроить функцию для кнопки B


import tkinter

class TkinterWindow(tkinter.Tk):
    def __init__(self):
        super().__init__()
        self.rowconfigure(0, weight=1)
        self.columnconfigure(0, weight=1)
        self.configure(background='orange')



class DisplayFrame(tkinter.Frame):
    def __init__(self, parent):
        super().__init__(parent)
        self.rowconfigure(0, weight=1)
        self.columnconfigure(0, weight=1)
        self.configure(background='cyan')
        self.grid(row=0, column=0, pady=5, padx=5, sticky='nsew')

        self.text = tkinter.StringVar()
        self.text.set('Hello')
        self.display = tkinter.Label(self, textvariable=self.text, font=15, bg="#bebebe", relief="groove", bd=5, height=5 )
        self.display.grid(sticky='nsew')

class ButtonsFrame(tkinter.Frame):
    def __init__(self, parent):
        super().__init__(parent)
        self.rowconfigure(0, weight=1)
        self.columnconfigure(0, weight=1)
        self.columnconfigure(1, weight=1)
        self.configure(background='green')
        self.grid(row=1, column=0, pady=5, padx=5, sticky='nsew')

        self.button_A = tkinter.Button(self, text='A', command=self.write_A)
        self.button_A.grid(row=0, column=0, padx=15, sticky='nsew')

        self.button_B = tkinter.Button(self, text='B')
        self.button_B.grid(row=0, column=1, padx=15, sticky='nsew')

    def write_A(self):
        display_frame.text.set('A')


def main():
    window = TkinterWindow()
    display_frame = DisplayFrame(window)
    buttons_frame = ButtonsFrame(window)
    window.mainloop()


main()

1 Ответ

1 голос
/ 09 мая 2019

Основная проблема, с которой вы столкнулись - это атрибут класса self.text, который не виден другим классам.Один из способов исправить это - переместить эту переменную в основной класс tk, а затем просто сослаться на нее.Это самое быстрое исправление вашего кода.

import tkinter

class TkinterWindow(tkinter.Tk):
    def __init__(self):
        super().__init__()
        self.rowconfigure(0, weight=1)
        self.columnconfigure(0, weight=1)
        self.configure(background='orange')
        self.text = tkinter.StringVar()
        self.text.set('Hello')


class DisplayFrame(tkinter.Frame):
    def __init__(self, parent):
        super().__init__(parent)
        self.rowconfigure(0, weight=1)
        self.columnconfigure(0, weight=1)
        self.configure(background='cyan')
        self.grid(row=0, column=0, pady=5, padx=5, sticky='nsew')


        self.display = tkinter.Label(self, textvariable=self.master.text, font=15, bg="#bebebe", relief="groove", bd=5, height=5 )
        self.display.grid(sticky='nsew')

class ButtonsFrame(tkinter.Frame):
    def __init__(self, parent):
        super().__init__(parent)
        self.rowconfigure(0, weight=1)
        self.columnconfigure(0, weight=1)
        self.columnconfigure(1, weight=1)
        self.configure(background='green')
        self.grid(row=1, column=0, pady=5, padx=5, sticky='nsew')

        self.button_A = tkinter.Button(self, text='A', command=self.write_A)
        self.button_A.grid(row=0, column=0, padx=15, sticky='nsew')

        self.button_B = tkinter.Button(self, text='B')
        self.button_B.grid(row=0, column=1, padx=15, sticky='nsew')

    def write_A(self):
        self.master.text.set('A')


def main():
    window = TkinterWindow()
    display_frame = DisplayFrame(window)
    buttons_frame = ButtonsFrame(window)
    window.mainloop()

main()

Тем не менее, в вашем коде есть несколько вещей, о которых следует помнить.Чрезмерное использование self., когда оно не нужно, и применение управления геометрией внутри класса фреймов также является плохой идеей.

Лично я бы построил все это в одном классе.

import tkinter as tk


class TkinterWindow(tk.Tk):
    def __init__(self):
        super().__init__()
        self.rowconfigure(0, weight=1)
        self.columnconfigure(0, weight=1)
        self.configure(background='orange')

        self.text = tk.StringVar()
        self.text.set('Hello')

        display_frame = tk.Frame(self, background='cyan')
        ButtonsFrame = tk.Frame(self, background='green')
        display_frame.rowconfigure(0, weight=1)
        display_frame.columnconfigure(0, weight=1)
        ButtonsFrame.rowconfigure(0, weight=1)
        ButtonsFrame.columnconfigure(0, weight=1)
        ButtonsFrame.columnconfigure(1, weight=1)

        display_frame.grid(row=0, column=0, pady=5, padx=5, sticky='nsew')
        ButtonsFrame.grid(row=1, column=0, pady=5, padx=5, sticky='nsew')

        tk.Label(display_frame, textvariable=self.text, font=15,
                 bg="#bebebe", relief="groove", bd=5).grid(row=0, column=0, sticky='nsew')

        tk.Button(ButtonsFrame, text='A',
                  command=lambda: self.update_text('A')).grid(row=0, column=0, padx=15, sticky='nsew')
        tk.Button(ButtonsFrame, text='B',
                  command=lambda: self.update_text('B')).grid(row=0, column=1, padx=15, sticky='nsew')

    def update_text(self, value):
        self.text.set(value)

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