Russian Qt Forum
Ноябрь 11, 2024, 12:55 *
Добро пожаловать, Гость. Пожалуйста, войдите или зарегистрируйтесь.
Вам не пришло письмо с кодом активации?

Войти
 
  Начало   Форум  WIKI (Вики)FAQ Помощь Поиск Войти Регистрация  

Страниц: [1]   Вниз
  Печать  
Автор Тема: [РЕШЕНО] Зависание GUI  (Прочитано 8253 раз)
vizir.vs
Гость
« : Март 17, 2014, 14:03 »

у меня есть некая процедура, которая в цикле добавляет данные в таблицу. Для того, чтобы во время добавления данных интерфейс не тормозил, в цикл добавлена следующая строчка:
Код:
qApp->processEvents();
Так же на форме есть кнопка (QPushButton), у которого есть меню.

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

Вопрос, как сделать так, чтобы при появление меню добавление данных не прекращалось?
« Последнее редактирование: Март 25, 2014, 16:24 от vizir.vs » Записан
Old
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 4350



Просмотр профиля
« Ответ #1 : Март 17, 2014, 14:06 »

Запускайте процесс добавления в отдельном потоке.
Можно воспользоваться низкоуровневым решением - QThread или прикладным QtConcurent. Последнее значительно проще в использование.
Записан
vizir.vs
Гость
« Ответ #2 : Март 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.

В общем идея переноса добавления данных в другой поток мне не шибко нравится.
Записан
Old
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 4350



Просмотр профиля
« Ответ #3 : Март 17, 2014, 15:33 »

Вынес в QtConcurrent, в итоге при запуске в консоль пишется
Под "добавляет данных в таблицу" вы имеете ввиду в БД или виджет?
Если последнее, то с потоками не получиться, лучше использовать модели и вью (QTableView).
Записан
vizir.vs
Гость
« Ответ #4 : Март 18, 2014, 08:09 »

Хм... QTableView так же ругается, как и QTableWidget.

Попробую вынести модель в один поток, а сам QTableView оставить в родном потоке.
« Последнее редактирование: Март 18, 2014, 08:29 от vizir.vs » Записан
OKTA
Гость
« Ответ #5 : Март 18, 2014, 09:11 »

GUI должен быть всегда в главном потоке, так что выносите все, что не касается GUI.
Записан
Old
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 4350



Просмотр профиля
« Ответ #6 : Март 18, 2014, 10:46 »

Попробую вынести модель в один поток, а сам QTableView оставить в родном потоке.
Лучше в отдельный поток вынести "генератор" записей: при готовности новой записи, генератор посылает сигнал в параметрах передавая все данные о новой записи. А слот приемник должен быть в модели (главный поток), который и будет добавлять запись с переданными данными.

Ну и тип коннекта между объектами в разных потоками обязательно должен быть Queue.
« Последнее редактирование: Март 18, 2014, 10:47 от Old » Записан
Igors
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 11445


Просмотр профиля
« Ответ #7 : Март 18, 2014, 11:31 »

В общем идея переноса добавления данных в другой поток мне не шибко нравится.
Если не нужно выжимать скорость, то таймер с интервалом 0
Записан
vizir.vs
Гость
« Ответ #8 : Март 18, 2014, 13:26 »

Попробую вынести модель в один поток, а сам QTableView оставить в родном потоке.
Лучше в отдельный поток вынести "генератор" записей: при готовности новой записи, генератор посылает сигнал в параметрах передавая все данные о новой записи. А слот приемник должен быть в модели (главный поток), который и будет добавлять запись с переданными данными.

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

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

Пока сделал заполнение модели в отдельном потоке, вроде работает, но иногда бывают падения, ищу ошибки.
Записан
vizir.vs
Гость
« Ответ #9 : Март 18, 2014, 13:43 »

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

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

Сообщений: 4350



Просмотр профиля
« Ответ #10 : Март 18, 2014, 13:54 »

Имелось ввиду, запустить таймер QTimer с 0 интервалом, тогда будет генерироваться сигнал timeout в любой свободный момент между обработкой событий, а в уже в слоте обработчике таймаута добавлять строки.
Это все будет работать в одной нитке.
Записан
Igors
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 11445


Просмотр профиля
« Ответ #11 : Март 18, 2014, 14:23 »

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

Имелось ввиду, запустить таймер QTimer с 0 интервалом, тогда будет генерироваться сигнал timeout в любой свободный момент между обработкой событий, а в уже в слоте обработчике таймаута добавлять строки.
Это все будет работать в одной нитке.

Интересная идея, сей час попробую!
Записан
vizir.vs
Гость
« Ответ #13 : Март 19, 2014, 13:06 »

Все сработало, спасибо за помощь
Записан
Страниц: [1]   Вверх
  Печать  
 
Перейти в:  


Страница сгенерирована за 0.124 секунд. Запросов: 23.