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

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

Страниц: 1 [2] 3   Вниз
  Печать  
Автор Тема: Зависание GUI  (Прочитано 16471 раз)
mutineer
Гость
« Ответ #15 : Март 20, 2012, 13:00 »

Последовательно вряд ли получится - это ж разные потоки и общение между ними идет через eventLoop
Записан
Vladimir
Крякер
****
Offline Offline

Сообщений: 305



Просмотр профиля
« Ответ #16 : Март 20, 2012, 13:02 »

Если реализовать заполнение структуры в том же потоке, но не данными по сети, то работает все как надо! проблемы начинаются, когда инфа начинает приходить по сети.. может как-то нужно синхронизировать этот процесс??
Записан
Bepec
Гость
« Ответ #17 : Март 20, 2012, 13:31 »

Мб минимально компилируемый пример?
Записан
mutineer
Гость
« Ответ #18 : Март 20, 2012, 13:35 »

Последовательно вряд ли получится - это ж разные потоки и общение между ними идет через eventLoop

Пардон, скорее всего должен быть прямой вызов, а не через eventLoop
Записан
V1KT0P
Гость
« Ответ #19 : Март 20, 2012, 13:43 »

Последовательно вряд ли получится - это ж разные потоки и общение между ними идет через eventLoop

Пардон, скорее всего должен быть прямой вызов, а не через eventLoop
Так из не главного потока в графику лезть нельзя-же или я чего-то не знал? У меня кстати есть похожая ситуация, один поток принимает данные а второй обрабатывает. Так вот раньше было через слоты, я просто создавал новую структуру и указатель на нее через слот посылал второму а уж ее обрабатывал. Но у меня структуры маленькие и их много, а задержка должна быть минимальная, пришлось от слотов отказаться.
Записан
LisandreL
Птица говорун
*****
Offline Offline

Сообщений: 984


Надо улыбаться


Просмотр профиля
« Ответ #20 : Март 20, 2012, 13:46 »

А получается:
QDebug() << " в потоке сразу после приема данных";
QDebug() << " в слоте отрисовки";
QDebug() << " в слоте отрисовки";
QDebug() << " в слоте отрисовки";
QDebug() << " в слоте отрисовки";

QDebug() << " в потоке сразу после приема данных";
QDebug() << " в потоке сразу после приема данных";
QDebug() << " в слоте отрисовки";

В общем различные комбинации, но не последовательно одна за другой..
Возможно отрисовывать не успеваете с той скоростью, с которой получаете данные (да ещё за счёт глобальной переменной и перетираете одни другими).

Вот так же всё по очереди будет:
connect(tSignReceiv,SIGNAL(onRecvSignal()),indWin,SLOT(slotDrawIndicat()), Qt::BlockingQueuedConnection );
Записан
mutineer
Гость
« Ответ #21 : Март 20, 2012, 13:53 »

Последовательно вряд ли получится - это ж разные потоки и общение между ними идет через eventLoop

Пардон, скорее всего должен быть прямой вызов, а не через eventLoop
Так из не главного потока в графику лезть нельзя-же или я чего-то не знал? У меня кстати есть похожая ситуация, один поток принимает данные а второй обрабатывает. Так вот раньше было через слоты, я просто создавал новую структуру и указатель на нее через слот посылал второму а уж ее обрабатывал. Но у меня структуры маленькие и их много, а задержка должна быть минимальная, пришлось от слотов отказаться.

Ну вот если рассужадть логически. Принимающий объект живет в GUI-треде. Отправляющий объект кто? Наследник QThread. По идее он тоже живет в GUI-треде. Значит Qt должен использовать прямой вызов
Записан
V1KT0P
Гость
« Ответ #22 : Март 20, 2012, 13:57 »

Ну вот если рассужадть логически. Принимающий объект живет в GUI-треде. Отправляющий объект кто? Наследник QThread. По идее он тоже живет в GUI-треде. Значит Qt должен использовать прямой вызов
Ну так если обработчик слотов треда в главном треде то все что в нем будет выполняться будет тормозить GUI. А он хочет вынести его в отдельный.
Записан
arttr
Гость
« Ответ #23 : Март 20, 2012, 14:18 »

Да, да, да, вот в точности такая ситуация была QTcpSocket крутится в отдельном потоке, принимает данные, в этом же потоке происходит их (довольно сложное) преобразование, а потом они эмитятся в ГУИ-поток...головняка на неделю было...

проблему решили так: отказались от переопределения метода run в классе треда. Написали свой класс Thread, в котором был указатель на QThread как приватное поле QThread* thread. Написали слот
Код:
void Thread::start()
{
    thread = new QThread();
    moveToThread(thread);
    thread->moveToThread(thread);

    connect(thread, SIGNAL( started() ),
            this,     SLOT( _threadStarted() ) );


    thread->start();

}
реализовали слот threadStarted(). В этом слоте прописали весь код который должен выполняться в нашем потоке. Так же сделали слот quit (хотя может Вам и метода достаточно будет), к котором разрываем подключение, делаем deleteLater() всем полям класса нашего потока, а потом отстанавливаем поток. Выглятит это примерно так
Код:
    this->deleteLater();
    thread->quit();
Более подробно см. http://labs.qt.nokia.com/2006/12/04/threading-without-the-headache/

Еще про "сеть в отдельном потоке". Cетевые сокеты (QTcpSocket точно) являются асинхронными девайсами, это значит им для нормальной работы нужен работающий цикл обработки событий, а это в свою очередь значит, что создавать/удалять, создавать подключение/разрывать подключение, считывать/записывать нужно в работающем потоке. Поэтому и пришлось делать метод threadStarted.

Теперь структуру Вашу, объявленную extern'ом, если я правильно понял, то она же живет в главном потоке, а заполняется в дочернем данными по сети, еще бы ГУЙ не повис...делайте структуру в своем дочернем потоке и эмитируйте куда хотите...никакие blockingConnection не нужны будут

Дополнение: всем полям класса Thread обязательно делать moveToThread(thread)
« Последнее редактирование: Март 20, 2012, 14:22 от arttr » Записан
Vladimir
Крякер
****
Offline Offline

Сообщений: 305



Просмотр профиля
« Ответ #24 : Март 20, 2012, 15:05 »

Вроде выше писали, что moveToThread не есть хорошее решение.. что-то я по ходу жестко тупанул) зачем мне вообще отсылать сигнал, что данные пришли.. в глобальную структуры я эти данные записываю, а когда нужно отрисовать просто считываю! без всякого сигнала.. вроде так и работает! рисуется по данным из сети, но интерфейс всеравно притормаживает.. не так жестко конечно, но есть еще..
Записан
Bepec
Гость
« Ответ #25 : Март 20, 2012, 15:24 »

Код в студию! Тогда и тормоза уберём. Причёску сделаем, автомат выдадим и на окопы ЗА РОДИНУУУ!!!!
Записан
arttr
Гость
« Ответ #26 : Март 20, 2012, 15:49 »

Цитировать
Вроде выше писали, что moveToThread не есть хорошее решение..
moveToThread - это хорошее решение, если понимать зачем оно нужно.
Цитировать
интерфейс всеравно притормаживает.. не так жестко конечно, но есть еще..
интерфейс и будут замораживаться, именно для этого весь ресурсоемкий код выносят в отдельный поток. Получение данных по сети всяко происходит медленнее, чем отрисовка ГУИ => ГУИ притормаживает
Записан
mutineer
Гость
« Ответ #27 : Март 20, 2012, 15:50 »

Вроде выше писали, что moveToThread не есть хорошее решение..

moveToThread хорошее решение, moveToThread(this) нехорошее
Записан
Bepec
Гость
« Ответ #28 : Март 20, 2012, 15:56 »

Чем? Улыбающийся

mutineer - Если ты точно незнаешь, то не советуй Улыбающийся А спор у нас таки пришёл к тому, что это РАВНОПРАВНОЕ решение Подмигивающий
Записан
mutineer
Гость
« Ответ #29 : Март 20, 2012, 15:59 »

Чем? Улыбающийся

mutineer - Если ты точно незнаешь, то не советуй Улыбающийся А спор у нас таки пришёл к тому, что это РАВНОПРАВНОЕ решение Подмигивающий

Ваш спор пришел к тому, что "я 50 раз запускал, у меня ниче не крешится, так что способ хороший", а с потоками так нельзя. Так что ты тоже точно не знаешь что это нормальное решение
Записан
Страниц: 1 [2] 3   Вверх
  Печать  
 
Перейти в:  


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