Tkinter иногда зависает, когда я вызываю update_idletasks () - PullRequest
1 голос
/ 22 апреля 2019

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

def _handle_events_button(self):
    ntbk = self.find_notebook()
    print("1: " + str(int(time.time())))
    w = EventListDetailsCombo(ntbk)
    print("2: " + str(int(time.time())))
    w.load()
    print("3: " + str(int(time.time())))
    w.add_to_notebook(ntbk)
    print("4: " + str(int(time.time())))
    # clipboard.root.update_idletasks()
    print("5: " + str(int(time.time())))
    ntbk.select(w)
    print("6: " + str(int(time.time())))

Вывод отпечатков выглядит так:

# Working correctly 
1: 1555952235
2: 1555952235
3: 1555952235
4: 1555952235
5: 1555952237
6: 1555952237

# Hang / Delay
1: 1555952240
2: 1555952240
3: 1555952240
4: 1555952240
5: 1555952266
6: 1555952266

То есть с update_idletasks () без update_idletasks () все эти выходные данные находятся в пределах 1-2 секунд друг от друга. Вместо этого происходит зависание в mainloop update_idletasks

Некоторые заметки:

  • Он не останавливается постоянно, кажется довольно случайным, но, похоже, это происходит каждые 4-5 попыток.
  • Продолжительность замораживания также кажется случайной, иногда ее 30 секунд, иногда несколько минут.
  • Если я нажму другие кнопки, пока они заморожены, они выполнят эти действия после остановки остановки
  • обычно, если я прекращаю приложение из pycharm, кадр загружается за секунду до завершения приложения.

Я не уверен, куда идти отсюда, какие-нибудь указатели на вещи, которые я мог бы изучить?

Edit: Итак, я прошел и удалил все вызовы для обновления, и теперь он просто зависает после этого кода, я предполагаю, что на этапе обновления основного цикла, но я не совсем уверен, как проверить это предположение, эта функция _handle_events_button вызывается непосредственно с кнопки событий, поэтому после этого момента моего кода больше не должно быть.

Редактировать 2: Если я оставлю update_idletasks и запусту на нем профилировщик, то при правильной работе он будет выглядеть так:

enter image description here

На прогонах, где он зависает, все выглядит одинаково, за исключением того, что вместо вызова метода «около 1000 мс» требуется 25000 мс или более с примерно одинаковым количеством вызовов «вызова».

Редактировать 3: я добавил в выводе операторов печати. Также я не могу выбросить любую из этих функций в отдельный поток, так как все это только готовит виджеты.

Ответы [ 2 ]

0 голосов
/ 23 апреля 2019

Так что после того, как я сильно ударился головой о стол, я понял, что понял это.Для начала кажется, что tkinter просто медленно загружает виджеты, не уверен, что это из-за того, сколько у меня есть виджетов (не так много, вероятно, меньше 100, может быть меньше 50 в каждом загружаемом фрейме) или из-завсе подклассы я делаю (вероятно, больше, чем я должен).Это раздражает, но пока работает.

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

0 голосов
/ 22 апреля 2019

Вы не хотите вызвать update / update_idletasks, если у вас запущен постоянный цикл обработки событий. Эти функции являются альтернативой постоянному циклу событий.

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

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