Как я могу привязать обратный вызов к событию изменения размера Tkinter, не вызывая его несколько раз излишне? - PullRequest
0 голосов
/ 03 апреля 2020

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

self.parent.bind("<Configure>", self.onsize)

Однако всякий раз, когда размер окна изменяется, self.onsize() вызывается ~ 100 раз , замедляя все и в некоторых случаях вызывая cra sh после превышения максимальной глубины рекурсии. Я предполагаю, что это потому, что он вызывается, так как каждый отдельный виджет перераспределяется индивидуально в процессе изменения размера родительского окна.

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

в качестве альтернативы, как я могу узнать из информация, содержащаяся в передаваемом параметре event, соответствует ли событие родительскому окну или дочернему элементу родительского?

1 Ответ

1 голос
/ 03 апреля 2020

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

Может быть, а может и нет. Это зависит от того, кто является родителем, и что вы делаете в связанной функции. Если связанный виджет (self.parent в вашем примере) является окном root или экземпляром Toplevel, привязка будет применяться ко всем дочерним элементам windows. В противном случае событие сработает только для виджета, с которым оно связано.

Скорее всего, ваша функция что-то делает для изменения размера виджета, когда он реагирует на событие. Это вызовет новое событие, и именно поэтому вы получите ошибку рекурсии. Короче говоря, вы не должны делать что-то в связанной функции, чтобы заставить виджет, который получил событие, изменить размер.

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

Одно из решений заключается в том, чтобы связанная функция планировала другую функцию, которая будет вызвана после перерисовки tkinter, используя after_idle. Трудно сказать, сработает ли это в вашем конкретном случае c, поскольку ваш вопрос не показывает, почему вы на самом деле это делаете. Если ваша функция сама вызывает update или update_idletasks, она, вероятно, не будет работать, так как эти функции обрабатывают события простоя.

в качестве альтернативы, как я могу узнать из информации, содержащейся в параметре события, что передается, соответствует ли событие родительскому окну или дочернему элементу родительского?

Атрибут widget объекта события сообщит вам, какой виджет получил событие.

...