Russian Qt Forum

Qt => Пользовательский интерфейс (GUI) => Тема начата: vizir.vs от Март 17, 2014, 14:03



Название: [РЕШЕНО] Зависание GUI
Отправлено: vizir.vs от Март 17, 2014, 14:03
у меня есть некая процедура, которая в цикле добавляет данные в таблицу. Для того, чтобы во время добавления данных интерфейс не тормозил, в цикл добавлена следующая строчка:
Код:
qApp->processEvents();
Так же на форме есть кнопка (QPushButton), у которого есть меню.

Если во время добавления данных в таблицу нажать на кнопку, то появляется меню кнопки, при этом процесс добавления данных в таблицу прекращается.
Пока меню отображается данные не добавляются, как только меню убирается, данные продолжают добавляться.

Вопрос, как сделать так, чтобы при появление меню добавление данных не прекращалось?


Название: Re: Зависание GUI
Отправлено: Old от Март 17, 2014, 14:06
Запускайте процесс добавления в отдельном потоке.
Можно воспользоваться низкоуровневым решением - QThread или прикладным QtConcurent. Последнее значительно проще в использование.


Название: Re: Зависание GUI
Отправлено: vizir.vs от Март 17, 2014, 14:35
Вынес в QtConcurrent, в итоге при запуске в консоль пишется
QPixmap: it is not safe to use pixmap outside the GUI thread
Иногда проскакивает текст
QPainter::begin: Paint device returned == 0, type: 2
QPainter::setRenderHint: Painter must be active to set rendering hints
Qpainter::end: Painter not active, aborted.

В общем идея переноса добавления данных в другой поток мне не шибко нравится.


Название: Re: Зависание GUI
Отправлено: Old от Март 17, 2014, 15:33
Вынес в QtConcurrent, в итоге при запуске в консоль пишется
Под "добавляет данных в таблицу" вы имеете ввиду в БД или виджет?
Если последнее, то с потоками не получиться, лучше использовать модели и вью (QTableView).


Название: Re: Зависание GUI
Отправлено: vizir.vs от Март 18, 2014, 08:09
Хм... QTableView так же ругается, как и QTableWidget.

Попробую вынести модель в один поток, а сам QTableView оставить в родном потоке.


Название: Re: Зависание GUI
Отправлено: OKTA от Март 18, 2014, 09:11
GUI должен быть всегда в главном потоке, так что выносите все, что не касается GUI.


Название: Re: Зависание GUI
Отправлено: Old от Март 18, 2014, 10:46
Попробую вынести модель в один поток, а сам QTableView оставить в родном потоке.
Лучше в отдельный поток вынести "генератор" записей: при готовности новой записи, генератор посылает сигнал в параметрах передавая все данные о новой записи. А слот приемник должен быть в модели (главный поток), который и будет добавлять запись с переданными данными.

Ну и тип коннекта между объектами в разных потоками обязательно должен быть Queue.


Название: Re: Зависание GUI
Отправлено: Igors от Март 18, 2014, 11:31
В общем идея переноса добавления данных в другой поток мне не шибко нравится.
Если не нужно выжимать скорость, то таймер с интервалом 0


Название: Re: Зависание GUI
Отправлено: vizir.vs от Март 18, 2014, 13:26
Попробую вынести модель в один поток, а сам QTableView оставить в родном потоке.
Лучше в отдельный поток вынести "генератор" записей: при готовности новой записи, генератор посылает сигнал в параметрах передавая все данные о новой записи. А слот приемник должен быть в модели (главный поток), который и будет добавлять запись с переданными данными.

Ну и тип коннекта между объектами в разных потоками обязательно должен быть Queue.

Собственно у меня так и сделано было, данные генерируются в одном потоке, а заполняются в другом, проблема в том, что самая долгая операция - добавление данных в QTableWidget/QTableView в это время интерфейс и виснет.

Пока сделал заполнение модели в отдельном потоке, вроде работает, но иногда бывают падения, ищу ошибки.


Название: Re: Зависание GUI
Отправлено: vizir.vs от Март 18, 2014, 13:43
В общем идея переноса добавления данных в другой поток мне не шибко нравится.
Если не нужно выжимать скорость, то таймер с интервалом 0

Если имеется ввиду
Код:
qApp->processEvents(QEventLoop::AllEvents, 0)
то не прокатило, все равно интерфейс виснет.


Название: Re: Зависание GUI
Отправлено: Old от Март 18, 2014, 13:54
Имелось ввиду, запустить таймер QTimer с 0 интервалом, тогда будет генерироваться сигнал timeout в любой свободный момент между обработкой событий, а в уже в слоте обработчике таймаута добавлять строки.
Это все будет работать в одной нитке.


Название: Re: Зависание GUI
Отправлено: Igors от Март 18, 2014, 14:23
Если имеется ввиду
Код:
qApp->processEvents(QEventLoop::AllEvents, 0)
то не прокатило, все равно интерфейс виснет.
Нет, таймер с интервалом 0 (как уже ответили). Вообще processEvents годится только если выставлен модальный диалог (типа QProgressDialog). А так - напр событие взяло и убило таблицу что заполняется, или изменило еще какие-то данные.


Название: Re: Зависание GUI
Отправлено: vizir.vs от Март 18, 2014, 14:56
Имелось ввиду, запустить таймер QTimer с 0 интервалом, тогда будет генерироваться сигнал timeout в любой свободный момент между обработкой событий, а в уже в слоте обработчике таймаута добавлять строки.
Это все будет работать в одной нитке.

Интересная идея, сей час попробую!


Название: Re: Зависание GUI
Отправлено: vizir.vs от Март 19, 2014, 13:06
Все сработало, спасибо за помощь