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

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

Страниц: [1]   Вниз
  Печать  
Автор Тема: Обработка сообщений главным GUI потоком  (Прочитано 4551 раз)
Gorin
Гость
« : Сентябрь 20, 2008, 09:45 »

Делаю класс на основе Qextserialport c функциональностью асинхронного обмена.
Для опроса количества байт в порту использую поток со msleep(1) (пробовал также с таймером), обработку новых данных произвожу при помощи SIGNAL SLOT (пробовал также с     QEvent).
Класс работает как надо, но если зажать левую клавишу мыши на верхней части окна (типа перемещение) - то SLOT (а так же и event) перестает обрабатываться главной формой а сваливается в очередь обработки сообщений которая не обрабатывается, пока кнопочку не отпустишь, а для приложения работающего с com портом это недопустимо.
В принципе можно посадить таймер на главную форму и в нем опрашивать порт - но это не удобно.
для SIGNAL SLOT попробовал Directconnection, для QEvent postevent - результата одинаковый, неудовлетворительный, описанный выше.

Подскажите пож-ста как бороться с этой проблемой.
Записан
ритт
Гость
« Ответ #1 : Сентябрь 20, 2008, 10:45 »

ммм...перейти на линукс? )

проблема известная и к кутям отношения не имеет - где-то в настройках венды нужно включить какую-то галочку (то ли "Отображать содержимое окна при перетаскивании", то ли ещё что - не помню точно). и, кстати, существует похожая проблема с тяни-бросаем...мастдай, х?ле?
Записан
Tonal
Гость
« Ответ #2 : Сентябрь 21, 2008, 10:22 »

2 GorinЭлементарно: обрабатывать данные в дополнительном потоке, а в главный просто слать уведомления (сигналя или события) о том, что очередную порцию можно показывать. Улыбающийся
Записан
Gorin
Гость
« Ответ #3 : Сентябрь 23, 2008, 05:24 »

Работаю в windows.
Галочка "Отображать содержимое окна при перетаскивании" не помогла = эффект тот же.
Буду пробовать по варианту Tonal.

ИНтересный момент: при перемещении формы таймер внутри потока приостанавливается и не генерит сообщения.
Записан
Alex03
Гость
« Ответ #4 : Сентябрь 23, 2008, 06:30 »

ИНтересный момент: при перемещении формы таймер внутри потока приостанавливается и не генерит сообщения.
Как узнаёте? Код в студию плиз...
Записан
Gorin
Гость
« Ответ #5 : Сентябрь 23, 2008, 09:19 »

Насчет таймера я все таки ошибся.
При помощи qtdebug смотрю время отправки приема.
Но не могу объяснить некоторые вещи, они закоментированы в коде.
Код:
//************************ H file***************
#include <QtGui>
#include <QtDebug>

class MainWindow : public QMainWindow{
protected:
QTime time;
};

class MyThread : public QThread{
Q_OBJECT
private:
int m_nValue;
QTime time;
public:
MyThread() : m_nValue(100){}
void run(){
QTimer timer;
connect(&timer, SIGNAL(timeout()),SLOT(slotNextValue()));
connect(this,SIGNAL(currentValue(int)),this,SLOT(getValue(int)));
timer.start(100);
exec();
}

signals:
void finished();
void currentValue(int);

public slots:
void slotNextValue(){
--m_nValue;
qDebug() << "signal Counter= " <<m_nValue<< " time= "<<QTime(time.currentTime()).msec();
emit currentValue(m_nValue);
if (!m_nValue) emit finished();//1)не вызывается при перемещении формы,копится в очереди
}

void getValue (int value){//2)не вызывается при перемещении формы,копится в очереди
qDebug() << "slot Counter= " <<value<< " time= "<<QTime(time.currentTime()).msec();
}
};

//************************ CPP file***************
#include <QtGui>
#include "thr.h"



int main(int argc, char *argv[]) {
QApplication app(argc, argv);
MainWindow mw;
mw.setWindowTitle("Application");
mw.resize(400, 300);

MyThread thread;
QLCDNumber lcd(&mw);

QObject::connect(&thread, SIGNAL(currentValue(int)), &lcd, SLOT(display(int)),Qt::DirectConnection);
QObject::connect(&thread, SIGNAL(finished()), &app, SLOT(quit()),Qt::DirectConnection);

lcd.setSegmentStyle(QLCDNumber::Filled);
lcd.display(100);
lcd.resize(220, 90);
lcd.show();

thread.start();
    mw.show();

return app.exec();
}


Записан
Alex03
Гость
« Ответ #6 : Сентябрь 23, 2008, 10:15 »

Код:
	void run(){
QTimer timer;
connect(&timer, SIGNAL(timeout()),SLOT(slotNextValue()));
connect(this,SIGNAL(currentValue(int)),this,SLOT(getValue(int)));
timer.start(100);
exec();
}
connect по дефолту - Qt::AutoConnection.
Цитировать
Qt::AutoConnection If the signal is emitted from the thread in which the receiving object lives, the slot is invoked directly, as with Qt::DirectConnection; otherwise the signal is queued, as with Qt::QueuedConnection.
timer - у Вас "живёт" в порождённом MyThread потоке.
А вот сам MyThread - "живёт" в главном потоке.
Соответственно при
Код:
connect(&timer, SIGNAL(timeout()),SLOT(slotNextValue()));
MyThread::slotNextValue() будет вызываться в главном потоке, или др. словами вообще все слоты у Вас работают в главном потоке, а QTimer::timeout() - емитится через очередь.
Записан
Страниц: [1]   Вверх
  Печать  
 
Перейти в:  


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