2009-03-08 2 views
1

WX (и WxPython) имеет два события, я скучаю в PyQt:WX и UI события обновления в PyQt

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

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


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

Мое приложение имеет состояния:

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

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

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

ответ

5

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

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

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

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

+0

спасибо. Я привел пример и хотел бы услышать мнение –

+0

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

+0

Вы можете найти полезные примеры Qt FTP и Find Files. –

1

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

+0

Да, но EVT_IDLE отправляется только один раз. Как я могу сделать такой таймер, который отправляется только один раз, когда нет других событий? Я не думаю, что могу (ни один снимок здесь не помогает, потому что я хочу, чтобы это все время не было других событий) –

2

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

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

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

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

1

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

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

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