Python Tkinter Избегайте использования имени "root" в функции нижнего уровня - PullRequest
0 голосов
/ 07 января 2020

Вдохновленный этим 300+ голосованием, закрытым Q & A: Лучший способ структурировать приложение tkinter? , я стараюсь избегать явного использования root в функции внутри класса. Я думаю, что это должно быть неявно объявлено через self или parent или что-то в этом роде. Вот этот код:

У меня есть этот код ...

        self.label_this = tk.StringVar()
        self.label_last = tk.StringVar()
        self.label_total = tk.StringVar()

        tk.Label(count_frame, textvariable=self.label_this, \
                 font=(None, MON_FONTSIZE)).pack(anchor=tk.W)
        tk.Label(count_frame, textvariable=self.label_last, \
                 font=(None, MON_FONTSIZE)).pack(anchor=tk.W)
        tk.Label(count_frame, textvariable=self.label_total, \
                 font=(None, MON_FONTSIZE)).pack(anchor=tk.W)
        self.update_cnt_labels()

Потом ... ... 1011 *

        ''' Get list of Window ID's on monitor now '''
        new_windows = self.windows_on_monitor(new_windows)
        new_windows_cnt = len(new_windows) / WIN_CNT
        if self.old_windows_cnt == new_windows_cnt :
            FlashMessage (self.label_this, "No new windows to remove...", \
                          3, 750, 250)
            self.update_cnt_labels()
            return

Потом ...

class FlashMessage:
    def __init__(self, widget, message, count=5, on=500, off=300):

        self.delay_show (1, widget, message)
        for i in range(count):
            self.delay_show (on, widget, "")
            self.delay_show (off, widget, message)

    def delay_show(self, ms, widget, message):
        root.after(ms, widget.set(message))
        root.update_idletasks()

Я хочу не использовать root в последних двух строках и использовать self или что-то подобное.

Моя цепочка вызовов программ выглядит примерно так:

  • традиционный: root = tk.Tk()
  • куча вещей инициализации магистрали.
  • класс: ResizingCanvas(mycanvas)
  • функция магистрали: popup(event), которая связана с <ButtonPress-1>
  • Динамически отформатированный menu.tk_popup(event.x_root, event.y_root)
  • класс: RemoveNewWindows()
  • функция: remove()
  • класс: FlashMessage() (показать выше)
  • функция: self.delay_show() (показано выше)

Каждый класс и функция имеют случайные значения self, позиционные параметры, *args и **kwargs, которые в основном не служат цели. Действительно, даже __init__ выше может быть ненужным. Это результат копирования кода по всему переполнению стека.

Каждое второе слово в программе выглядит как self, но слово parent используется только в классе ResizingCanvas(). Нужно ли распространять parent по списку вызовов и как-то использовать его?

1 Ответ

1 голос
/ 07 января 2020

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

В вашем случае вам нужно будет передать какой-то виджет в конструктор FlashMessage и сохранить ссылку. Затем вы можете использовать ссылку для вызова функций.

Вы передаете то, что называется widget, которое на самом деле не содержит виджет. Вам нужно переименовать его в нечто более подходящее (например: var), а затем передать фактический виджет.

(Примечание: вы также неправильно набираете after, что я исправил в следующий пример)

Например:

class FlashMessage:
    def __init__(self, widget, var, message, count=5, on=500, off=300):
        self.widget = widget
        ...

def delay_show(self, ...):
    self.widget.after(ms, var.set, message)
    self.widget.update_idletasks()

Затем, когда вы создаете экземпляр FlashMessage, вам необходимо добавить виджет в качестве первого параметра.

Например, если предположить, что count_frame определено в контексте, где вы создаете экземпляр FlashMessage, и это фактический виджет, он может выглядеть примерно так:

if self.old_windows_cnt == new_windows_cnt :
    FlashMessage (count_frame, self.label_this, "No new windows to remove...", \
                  3, 750, 250)
    self.update_cnt_labels()
    return
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...