我有两个类:A和B,它们都是QObject的子类。
function click(click_id)
{
alert(click_id);
}
我刚才提到this article。 然后在GUI(比如主线程)中,我尝试使用
在不同的线程中在A和B之间交换数据class A:public QObject
{
Q_OBJECT
public:
A();
~A();
}
sigProduce(double)是A对象中定义的信号,slotConsume(double)是公共插槽: B级标题:
pA = new A();
QThread *workerThread = new QThread;
pA->moveToThread(workerThread);
connect(workerThread , SIGNAL(started()), pA, SLOT(doWork()));
connect(pA, SIGNAL(finished()), workerThread , SLOT(quit()));
connect(pA, SIGNAL(finished()), pA, SLOT(deleteLater()));
connect(workerThread , SIGNAL(finished()), workerThread , SLOT(deleteLater()));
workerThread ->start();
pB = new B();
connect(pA,SIGNAL(sigProduce(double)),pB,SLOT(slotConsume(double)));//I just don't know where to put this line
QThread *workerThread = new QThread;
pB ->moveToThread(workerThread);
connect(workerThread , SIGNAL(started()), pB , SLOT(doWork()));
connect(pB , SIGNAL(finished()), workerThread , SLOT(quit()));
connect(pB , SIGNAL(finished()), pB , SLOT(deleteLater()));
connect(workerThread , SIGNAL(finished()), workerThread , SLOT(deleteLater()));
workerThread ->start();
所以在程序启动后obj B无法从obj获取双重数据A.连接(pA,pB)代码位置是否重要?有人可以帮助我吗?谢谢。
答案 0 :(得分:0)
在详细介绍如何解决问题之前,请先确保问题是有效的。如果你使用线程的唯一原因是因为你想要一个无限循环,那么你可能根本不需要线程。如果循环内的工作很轻,那么你可以在主线程中使用QTimer
来完成它。请阅读this article以了解有关此内容的更多信息。
无论如何,你遇到的问题是你的doWork
方法中有一个无限循环,它会阻塞线程的事件循环。因此,你不得不求助于processEvents
。然而,这不是一个好的设计。更好的方法是通过从doWork
中删除无限循环让线程返回到事件循环。
然后,您可以使用计时器模拟循环,并在想要停止线程时停止计时器。或者,您可以使用QMetaObject::invokeMethod
和Qt::QueuedConnection
来调用事件循环中的doWork
方法,并使用bool
条件停止工作。在此示例中,我使用了invokeMethod
选项:
#include <QCoreApplication>
#include <QThread>
#include <QTimer>
#include <QDebug>
class Worker : public QObject
{
Q_OBJECT
public:
Worker(QObject *parent = 0) : QObject(parent), _stop(false) {}
public slots:
void doWork()
{
if(_stop)
return;
QThread::sleep(1); // simulating some heavy work here
emit calculationComplete(1564);
QMetaObject::invokeMethod(this, "doWork", Qt::QueuedConnection);
}
void stop()
{
_stop = true;
}
signals:
void calculationComplete(int result);
private:
bool _stop;
};
class ResultHandler : public QObject
{
Q_OBJECT
public:
ResultHandler(QObject *parent = 0) : QObject(parent) {}
public slots:
void handleResult(int result)
{
// do something with result
qDebug() << Q_FUNC_INFO << "Result:" << result;
}
};
int main(int argc, char *argv[])
{
QCoreApplication a(argc, argv);
QThread thread_a;
Worker worker;
ResultHandler handler;
QObject::connect(&worker, &Worker::calculationComplete, &handler, &ResultHandler::handleResult);
QObject::connect(&thread_a, &QThread::started, &worker, &Worker::doWork);
QObject::connect(&thread_a, &QThread::finished, &worker, &Worker::stop);
worker.moveToThread(&thread_a);
thread_a.start();
QTimer::singleShot(5000, &thread_a, &QThread::quit); // just simulating an exit
int result = a.exec();
thread_a.quit();
thread_a.wait(5000);
return result;
}
#include "main.moc"