Wx в режиме ожидания и обновления пользовательского интерфейса в PyQt - PullRequest
2 голосов
/ 08 марта 2009

У wx (и wxPython) есть два события, которые я пропускаю в PyQt:

  • EVT_IDLE это отправляется во фрейм. Может использоваться для обновления различных виджетов в соответствии с состоянием приложения
  • EVT_UPDATE_UI это отправляется виджету, когда его нужно перекрасить и обновить, чтобы я мог вычислить его состояние в обработчике

Теперь у PyQt их нет, и книга PyQt предлагает написать метод updateUi и вызвать его вручную. Я даже заканчивал тем, что вызывал его из таймера один раз в 0,1 секунды, чтобы избежать многих ручных вызовов методов, которые могут обновить GUI. Я что-то пропустил? Есть ли лучший способ добиться этого?


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

У моего приложения есть состояния:

  1. Перед открытием файла (в этом состоянии строка состояния показывает что-то особенное, а кнопка запуска отключена)
  2. Файл был открыт, а обработка не началась: кнопка пуска активирована, в строке состояния отображается что-то еще
  3. Обработка выполняется: кнопка пуска теперь говорит «Стоп», а строка состояния сообщает о прогрессе

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

В Qt мне нужно обновить кнопку несколькими методами, которые могут повлиять на состояние, или просто создать метод update_ui и периодически вызывать его в таймере. Какой более QT-иш-способ?

Ответы [ 4 ]

5 голосов
/ 09 марта 2009

Использование EVT_UPDATE_UI в wxWidgets, кажется, подчеркивает одно из фундаментальных различий в том, как wxWidgets и Qt ожидают, что разработчики будут обрабатывать события в своем коде.

С помощью Qt вы соединяете сигналы и слоты между виджетами в пользовательском интерфейсе, либо обрабатывая «бизнес-логику» в каждом слоте, либо делегируя ее выделенному методу. Обычно вы не беспокоитесь о внесении отдельных изменений в каждый виджет в вашем графическом интерфейсе, потому что любые запросы на перерисовку будут помещены в очередь событий и доставлены, когда управление вернется в цикл событий. Некоторые события рисования могут даже быть объединены ради эффективности.

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

Вы должны были бы рассказать немного больше о том, что вы делаете, чтобы объяснить, почему вам нужен эквивалент этого события в Qt.

2 голосов
/ 09 марта 2009

Я бы отправил сигналы Qt, чтобы указать изменения состояния (например, fileOpened, processingStarted, processingDone). Слоты в объектах, управляющих кнопкой запуска и виджетом строки состояния (или подклассами), могут быть связаны с этими сигналами, а не "опрашивать" текущее состояние в событии простоя.

Если вы хотите, чтобы сигнал позже откладывался в цикле событий, а не сразу (например, потому что для выполнения чего-то потребуется немного времени), вы можете использовать соединение «сигнальный слот в очереди» вместо нормальный вид.

http://doc.trolltech.com/4.5/signalsandslots.html#signals

Тип подключения является необязательным параметром для функции connect (): http://doc.trolltech.com/4.5/qobject.html#connect, http://doc.trolltech.com/4.5/qt.html#ConnectionType-enum

1 голос
/ 09 марта 2009

В общем, чем больше Qt-иш путь для обновления кнопки / панели инструментов по мере необходимости в любой функции требуют обновления, или объединить некоторые функции и непосредственно вызывать эту функцию, когда программа его потребности (например, updateUi функция).

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

Что касается многочисленных изменений, касающегося состояния, взглянуть на этом блоге о, надеюсь, предстоящее дополнение к Qt более легко обрабатывать состояния. Похоже, что это будет заботиться о многих ваших жалоб, потому что в ваших многочисленных функций, можно просто перейти на переменную состояния, и другие части пользовательского интерфейса необходимо обновить, чтобы соответствовать. Это не положительное это сделает его в следующий Qt выпуска (хотя я бы поставил на него, или что-то подобное), и я понятия не имею, насколько тесно PyQt отслеживает Qt релизы. Или поочередно, вы могли бы использовать концепцию и создать свой собственный класс для отслеживания состояния по мере необходимости.

1 голос
/ 09 марта 2009

Насколько я понимаю, EVT_IDLE отправляется, когда очередь сообщений приложения пуста. В Qt такого события нет, но если вам нужно выполнить что-то в Qt, когда нет ожидающих событий, вы должны использовать QTimer с таймаутом 0.

...