Как я могу настроить виджет, который находится в другом классе? - PullRequest
0 голосов
/ 09 сентября 2018

Мне нужно, чтобы кнопки внутри LeftFrame меняли свой внешний вид при нажатии. В классе AccOne я попытался сделать left_frame.acc1.config(releif='SUNKEN'), но я получил NameError: имя 'left_frame' не определено. Я пытался сделать left_frame глобальным, но безуспешно.

Вот сценарий.

class MainApp(Tk):
    def __init__(self, *args, **kwargs):
        Tk.__init__(self, *args, **kwargs)



        container = Frame(self)
        container.pack()

        container.rowconfigure(4, weight=1)
        container.columnconfigure(2, weight=1)

        right_frame = RightFrame(container, self)
        left_frame = LeftFrame(container, right_frame)

        left_frame.pack(side=LEFT)
        right_frame.pack()

class RightFrame(Frame):
    def __init__(self, parent, controller, *args, **kwargs):
        Frame.__init__(self, parent, *args, **kwargs)

        self.frames = {}
        for F in (Welcome, AccOne, AccTwo, AccThree, AccFour, AccFive):
            frame = F(self, self)
            self.frames[F] = frame

        self.show_frame(Welcome)

    def show_frame(self, cont):
        frame = self.frames[cont]
        frame.grid(row=0, column=0)
        frame.tkraise()

class LeftFrame(Frame):
    def __init__(self, parent, controller, *args, **kwargs):
        Frame.__init__(self, parent)

        acc1 = Button(self, text="Account 1", width=12, height=3, command=lambda: controller.show_frame(AccOne))
        acc1.pack()

Я подумал, что имеет смысл настроить кнопку под def show_frame(self,cont):, но я не знаю, с чего начать, так как этот метод не находится под LeftFrame.

1 Ответ

0 голосов
/ 10 сентября 2018

При создании окон tkinter с классами попробуйте подумать о создании «дерева виджетов», которое представляет собой путь, по которому вы можете получить доступ ко всем вашим виджетам. В этом простом примере MainWindow и SubWindow могут получить доступ ко всем виджетам друг друга:

class MainWindow(tk.Tk):
    def __init__(self):
        tk.Tk.__init__(self)

        # widget
        self.lbl = tk.Label(self, text='Title')
        self.lbl.pack()

        # create child window, as class attribute so it can access all
        # of the child's widgets
        self.child = SubWindow(self)
        self.child.pack()

        # access child's widgets
        self.child.btn.config(bg='red')


class SubWindow(tk.Frame):
    def __init__(self, parent):
        tk.Frame.__init__(self, parent)

        # can use this attribute to move 'up the tree' and access
        # all of mainwindow's widgets
        self.parent = parent

        # widget
        self.btn = tk.Button(self, text='Press')
        self.btn.pack()

        # access parent's widgets
        self.parent.lbl.config(text='Changed')

Что нужно изменить в вашем коде

Во-первых, каждый раз, когда вы создаете виджет, к которому вам может понадобиться доступ позже, присваивайте его переменной класса. Например (это является частью причины вашей проблемы):

self.left_frame
self.acc1

не

left_frame
acc1

Во-вторых, правильно используйте аргументы вашего родителя и контроллера. Вы делаете это, но вы никогда не используете их и не присваиваете их атрибуту, так что их может и не быть. Присвойте их атрибуту self.parent или self.controller, поэтому, если вам понадобится доступ к ним позже, вы можете.

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

Удачи!

...