Russian Qt Forum

Qt => Общие вопросы => Тема начата: Gorin от Сентябрь 20, 2008, 09:45



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

Подскажите пож-ста как бороться с этой проблемой.


Название: Re: Обработка сообщений главным GUI потоком
Отправлено: ритт от Сентябрь 20, 2008, 10:45
ммм...перейти на линукс? )

проблема известная и к кутям отношения не имеет - где-то в настройках венды нужно включить какую-то галочку (то ли "Отображать содержимое окна при перетаскивании", то ли ещё что - не помню точно). и, кстати, существует похожая проблема с тяни-бросаем...мастдай, х?ле?


Название: Re: Обработка сообщений главным GUI потоком
Отправлено: Tonal от Сентябрь 21, 2008, 10:22
2 GorinЭлементарно: обрабатывать данные в дополнительном потоке, а в главный просто слать уведомления (сигналя или события) о том, что очередную порцию можно показывать. :)


Название: Re: Обработка сообщений главным GUI потоком
Отправлено: Gorin от Сентябрь 23, 2008, 05:24
Работаю в windows.
Галочка "Отображать содержимое окна при перетаскивании" не помогла = эффект тот же.
Буду пробовать по варианту Tonal.

ИНтересный момент: при перемещении формы таймер внутри потока приостанавливается и не генерит сообщения.


Название: Re: Обработка сообщений главным GUI потоком
Отправлено: Alex03 от Сентябрь 23, 2008, 06:30
ИНтересный момент: при перемещении формы таймер внутри потока приостанавливается и не генерит сообщения.
Как узнаёте? Код в студию плиз...


Название: Re: Обработка сообщений главным GUI потоком
Отправлено: Gorin от Сентябрь 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();
}




Название: Re: Обработка сообщений главным GUI потоком
Отправлено: Alex03 от Сентябрь 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() - емитится через очередь.