Суть проблемы
Есть дерево (QTreeWidget) элементов (QTreeWidgetItem). По событию некоторые элементы нужно скрыть, а скрытые отобразить, для чего используется функция setHidden у QTreeWidgetItem. После фильтрации это все сортируется:def add_subitems(self, root_item):
'''Добавить элементы к корневому элементу'''
def add(text, hide=False):
sub_item = QtGui.QTreeWidgetItem(root_item)
sub_item.setText(0, text)
sub_item.setHidden(hide)
map(lambda val: add(*val), ( ('one',),
('two', True),
('three',) ))
def update_subitems(self, root_item):
'''Обновить под-элементы - скрыть или отобразить'''
for index in range(root_item.childCount()):
item = self.root_item.child(index)
# для упрощения скрываются видимые элементы,
# а скрытые отображаются
item.setHidden(not item.isHidden())
self.treeWidget.sortItems(0, QtCore.Qt.AscendingOrder)
Если update_subitems вызывается когда окно скрыто (свернуто в трей), часть вызовов setHidden отрабатывается не правильно и при восстановлении окна из трея пользователь видит не то, что должен видеть. Если убрать сортировку или не скрывать окно - все работает как надо.
Решение
Единственное решение, которое я нашел - отлавливать момент, когда окно отображается (QShowEvent) и обновлять дерево еще раз:def event(self, ev):
if ev.type()==QtCore.QEvent.Show:
#....
self.update_subitems(root_item)
среда, 14 января 2009 г.
Трабла setHidden у QTreeWidgetItem
Автор: sash_ko на 18:00 0 коммент.
воскресенье, 21 декабря 2008 г.
Qt Creator
Qt Software (так называется Trolltech после покупки компанией Nokia) выпустили бету новой кросс-платформенной IDE для работы с Qt - Qt Creator. На данном этапе среда поддерживает только компилятор gcc и дебагер gdb. Можно так же использовать Microsoft Visual Studio компилятор, но тогда не получится дебажить.
Qt Creator - это не попытка заменить Eclipse и Visual Studio: Qt Creator is not an Eclipse replacement, but instead a lightweight IDE designed specifically for cross-platform Qt development.
Qt Creator is not a Visual Studio replacement, but instead a lightweight IDE designed specifically for cross-platform Qt development.
Финальный релиз намечается на начало 2009 года. Подробнее можно почитать здесь.
Выглядит это так:
Самореклама: мой второй блог
Автор: sash_ko на 10:39 0 коммент.
Ярлыки: Qt
четверг, 16 октября 2008 г.
PyQt in-depth: типы signal-slot соединений
В Qt слоты и сигналы являются платформенно-независимым средством обмена сообщениями между объектами. Подробнее писать о них я не собираюсь, так это хорошо сделали до меня прямо в документации Qt или, например, вот здесь. Я хочу выделить некоторые особенности их использования, с которыми мне удалось столкнуться.
Signal-slot механизм - это не просто вызов колбеков в чистом виде. Между сигналом и слотом устанавливается соединение, которое может быть 4-х типов:
- DirectConnection - прямое соединение, когда сигнал моментально обрабатывается слотом;
- QueuedConnection - сигнал добавляется в очередь и ожидает своего "выхода" в очереди сообщений, при этом поток, в котором возник сигнал не блокируется;
- BlockingQueuedConnection - то же, что и QueuedConnection, но вызывающий поток блокируется, пока сигнал не будет обработан;
- AutoConnection - автоматически выбирается DirectConnection, если сигнал вызывается из того же потока, в котором живет приемник, и QueuedConnection, если используются разные потоки.
Как видно, два соединения являются синхронными, одно асинхронным и одно автоматически выбирает себе соответствующий тип в зависимости от внешнего окружения.
Тип соединения указывается как параметр QObject.connect:
QObject.connect(doer, SIGNAL('event'), self.handle, Qt.DirectConnection)
Теперь, как это все работает на примере. Пусть есть задача, которую надо выполнить в отдельном потоке (класс Doer) и обработчик, который должен узнать о результате выполнения (класс Handler).
На это примере можно проследить где и когда будет отрабатываться слот в зависимости типа соединения.
В случае DirectConnection, сигнал обрабатывается синхронно, в потоке, где выполнялась задача:
task in thread < Thread(Thread-1, started) >
handle in thread < Thread(Thread-1, started) >
handle finish
after notify
При QueuedConnection, сигнал обрабатывается асинхронно в главном потоке приложения:
task in thread < Thread(Thread-1, started) >
after notify
handle in thread < _MainThread(MainThread, started) >
handle finish
BlockingQueuedConnection заставляет поток, вызывающий сигнал, ждать обработки, которая происходит в главном потоке приложения:
task in thread < Thread(Thread-1, started) >
handle in thread < _MainThread(MainThread, started) >
handle finish
after notify
При AutoConnection ситуация такая же как и при QueuedConnection, так как сигнал и приемник в разных потоках:
task in thread < Thread(Thread-1, started) >
after notify
handle in thread <_MainThread(MainThread, started)>
handle finish
Но если изменить одну строчку кода результат будет таким же как при DirectConnection:
task in thread <_MainThread(MainThread, started)>
handle in thread <_MainThread(MainThread, started)>
handle finish
after notify
Тип соединения BlockingQueuedConnection стоит использовать только в многопоточных приложениях, так как в одном потоке может привести к dead lock'у, о чем Qt должно предупредить ворнингом:
Qt: Dead lock detected while activating a BlockingQueuedConnection
Таким образом, Qt позволяет гибко настраивать обработку сигналов в синхронном и асинхронном режиме, в одном или нескольких потоках.
Автор: sash_ko на 11:19 2 коммент.
Ярлыки: Программизм, python, Qt