Я начинающий в Qt. Разбираюсь с многопоточностью и не могу написать код, который одновременно менял значение QLCDNumber и постоянно нажимает кнопочку. Прошу помочь разобраться.
#ifndef LCDTHREAD_H
#define LCDTHREAD_H
#include <QThread>
class LCDThread : public QThread
{
Q_OBJECT
private:
int m_nValue;
public:
LCDThread(QObject *parent = 0);
void run();
signals:
void currentValue(int);
};
#endif // LCDTHREAD_H
#ifndef PBTHREAD_H
#define PBTHREAD_H
#include <QThread>
class PBThread : public QThread
{
Q_OBJECT
public:
PBThread(QObject *parent = 0);
void run();
signals:
void finished();
void click();
public slots:
void slotClick();
};
#endif // PBTHREAD_H
#include "lcdthread.h"
#include <QTimer>
LCDThread::LCDThread(QObject *parent) :
QThread(parent),
m_nValue(0)
{
}
void LCDThread::run()
{
while (true) {
emit currentValue(++m_nValue);
}
exec();
}
#include "pbthread.h"
PBThread::PBThread(QObject *parent) :
QThread(parent)
{
}
void PBThread::run()
{
while(true) {
emit click();
}
exec();
}
void PBThread::slotClick()
{
emit click();
}
#include <QtGui>
#include "lcdthread.h"
#include "pbthread.h"
int main(int argc, char** argv)
{
QApplication a(argc, argv);
QLCDNumber *plcd = new QLCDNumber(8);
LCDThread lcdThread;
plcd->setSegmentStyle(QLCDNumber::Flat);
QObject::connect(&lcdThread, SIGNAL(currentValue(int)), plcd, SLOT(display(int)));
QPushButton *ppbutton = new QPushButton("PUSH, FUCKING PSUH");
PBThread pbThread;
QObject::connect(&pbThread, SIGNAL(click()), ppbutton, SLOT(animateClick()));
QWidget wgt;
QHBoxLayout *l = new QHBoxLayout;
l->addWidget(plcd);
l->addWidget(ppbutton);
wgt.setLayout(l);
lcdThread.start();
pbThread.start();
wgt.show();
return a.exec();
}
виджеты могут находится только в главном потоке. Но ими можно управлять через сигналы и слоты из других потоков.
П.С.
виджеты создаются в главном потоке (по крайней мере в main.cpp), в run для каждого потока я написал только отправку сигналов, к которым в main.cpp коннектится соответствующий слот. здесь, думаю, я не ошибся. но при выполнении родительский виджет повисает и не дает себя ни перетаскивать ни закрывать, хотя по идее находится в отдельном потоке.
Чет мне подсказывает, что закидывать в while() сообщениями без пауз - это не лучший метод виджеты живут в основном потоке, но если они получают неприрывный поток сигналов, они это отрабатывают и не дают возможности сигналам и событиям перемещения прийти.
ufna, то есть, в принципе, написано все правильно, только надо usleep(100500) написать?
Вообще по-хорошему не так делается Можно сделать класс "посылатель сигналов" и пихать его в поток, при этом не переопределяя поток, а делая moveToThread - это будет более правильно.
А здесь я не уверен насчет сигналов до exec() в потоке.
ufna, можно поподробней?
Litkevich Yuriy, я имею ввиду, что этот отдельный поток, где создаются виджеты и есть главный.
franza, ту по-русски вообще понимаешь?
Litkevich Yuriy, понимаю. Можешь попробовать рассказать о моей ошибке не в одном предложении, а подробнее, так как видно, что я мало понимаю. Мне непонятно следующее: 3 виджета (лсд, кнопка, и базовый, куда они помещаются) создаются в main.cpp. При этом они создаются в главном потоке или нет? Если нет, то как создать их в главном потоке? Слоты, к которым происходит коннект вызываются в главном потоке или нет?
спасибо, вроде разобрался. напишу еще, если появятся вопросы.
Форум Invision Power Board (http://www.invisionboard.com)
© Invision Power Services (http://www.invisionpower.com)