C++ QTimer不';t呼叫超时槽
我试图在不同的C++ QTimer不';t呼叫超时槽,c++,qt,qt4,qthread,qtimer,C++,Qt,Qt4,Qthread,Qtimer,我试图在不同的QThread中使用QTimer,但无法连接到QTimer的timeout()插槽 我做错了什么 这是我的密码: extern MainWindow *mainClass; class myObj : public QObject { Q_OBJECT public: explicit myObj(QObject *parent = 0); ~myObj(); QThread workerThread; int percent;
QThread
中使用QTimer
,但无法连接到QTimer
的timeout()
插槽
我做错了什么
这是我的密码:
extern MainWindow *mainClass;
class myObj : public QObject
{
Q_OBJECT
public:
explicit myObj(QObject *parent = 0);
~myObj();
QThread workerThread;
int percent;
QTimer *percentTimer;
public slots:
void doWork();
void percentUpdate();
void startFunction();
signals:
void start();
void UpdateResult();
};
myObj::myObj(QObject *parent) : QObject(parent)
{
moveToThread(&workerThread);
connect(&workerThread, SIGNAL(finished()), this, SLOT(deleteLater()));
connect(this, SIGNAL(UpdateResult()), mainClass, SLOT(on_UpdateResult()));
connect(&workerThread, SIGNAL(started()), this, SLOT(doWork()));
connect(this, SIGNAL(start()), this, SLOT(startFunction()));
percent++;
percentTimer = new QTimer();
percentTimer->moveToThread(&workerThread);
percentTimer->setInterval(1000);
connect(percentTimer, SIGNAL(timeout()), this,SLOT(percentUpdate()));
}
myObj::~myObj() {
workerThread.quit();
workerThread.wait();
if (percentTimer) percentTimer->deleteLater();
}
void myObj::doWork()
{
emit start();
workerThread.exec();
}
void myObj::startFunction()
{
percentTimer->start();
QThread::sleep(60);
percentTimer->stop();
}
void myObj::percentUpdate()
{
qDebug() << "In Timer" << percent++;
emit UpdateResult();
}
extern主窗口*mainClass;
MyObject类:公共QObject
{
Q_对象
公众:
显式myObj(QObject*parent=0);
~myObj();
QThread-workerThread;
整数百分比;
QTimer*percentTimer;
公众时段:
无效销钉();
void percentUpdate();
void startFunction();
信号:
void start();
void UpdateResult();
};
myObj::myObj(QObject*父对象):QObject(父对象)
{
moveToThread(&workerThread);
连接(&workerThread,SIGNAL(finished()),this,SLOT(deleteLater());
连接(此,信号(UpdateResult()),main类,插槽(在_UpdateResult()上);
连接(&workerThread,SIGNAL(started()),this,SLOT(doWork());
连接(这个,信号(start()),这个,插槽(startFunction());
百分比++;
percentTimer=新的QTimer();
percentTimer->moveToThread(&workerThread);
百分比计时器->设置间隔(1000);
连接(百分比计时器,信号(超时()),此,插槽(百分比更新());
}
myObj::~myObj(){
workerThread.quit();
workerThread.wait();
如果(percentTimer)percentTimer->deleteLater();
}
void myObj::doWork()
{
发射开始();
workerThread.exec();
}
void myObj::startFunction()
{
百分比计时器->开始();
QThread::sleep(60);
百分比计时器->停止();
}
void myObj::percentUpdate()
{
qDebug()首先,您应该共享workerThread
,让myObj
在其上下文中工作(在创建所需的连接后启动,因为连接到start
信号的插槽可能不会被执行)。
您不应该使用QThread::sleepFor
而是应该使用如下内容:
QEventLoop loop;
QTimer::singleShot(60000, &loop, SLOT(exit()));
loop.exec();
创建延迟,因为QThread::sleepFor
会冻结整个线程执行。因此,不会处理绑定到此线程的任何事件
workerThread.exec()
在这里是无用的。首先,您应该共享workerThread
,让myObj
在其上下文中工作(在创建所需的连接后启动它,因为连接到start
信号的插槽可能不会被执行)。
您不应该使用QThread::sleepFor
而是应该使用如下内容:
QEventLoop loop;
QTimer::singleShot(60000, &loop, SLOT(exit()));
loop.exec();
创建延迟,因为QThread::sleepFor
会冻结整个线程执行。因此,不会处理绑定到此线程的任何事件
workerThread.exec()
在这里是无用的。这是因为您试图从创建QTimer的线程以外的其他线程启动QTimer。使用QTimer和线程时,应非常小心地在将控制它的线程中创建QTimer
发件人:
在多线程应用程序中,可以在具有事件循环的任何线程中使用QTimer。若要从非GUI线程启动事件循环,请使用QThread::exec()。Qt使用计时器的线程关联来确定哪个线程将发出超时()信号。因此,必须在其线程中启动和停止计时器;无法从其他线程启动计时器
myObj::myObj(QObject *parent) : QObject(parent), percentTimer(nullptr)
{
moveToThread(&workerThread);
connect(&workerThread, SIGNAL(finished()), this, SLOT(deleteLater()));
connect(this, SIGNAL(UpdateResult()), mainClass, SLOT(on_UpdateResult()));
connect(&workerThread, SIGNAL(started()), this, SLOT(init()));
connect(&workerThread, SIGNAL(started()), this, SLOT(doWork()));
connect(this, SIGNAL(start()), this, SLOT(startFunction()));
percent++;
}
void myObj::init() {
percentTimer = new QTimer();
percentTimer->setInterval(1000);
connect(percentTimer, SIGNAL(timeout()), this, SLOT(percentUpdate()));
}
在您的情况下,percentTimer=new QTimer();
是从主线程执行的(即使您以前使用过moveToThread
,这仍然是执行它的主线程),而doWork
和start
信号是从workerThread
发出的
例如,您可以从workerThread
调用的void init()
插槽执行new QTimer
,而不是在构造函数中,以确保QTimer
由正确的线程创建和拥有
myObj::myObj(QObject *parent) : QObject(parent), percentTimer(nullptr)
{
moveToThread(&workerThread);
connect(&workerThread, SIGNAL(finished()), this, SLOT(deleteLater()));
connect(this, SIGNAL(UpdateResult()), mainClass, SLOT(on_UpdateResult()));
connect(&workerThread, SIGNAL(started()), this, SLOT(init()));
connect(&workerThread, SIGNAL(started()), this, SLOT(doWork()));
connect(this, SIGNAL(start()), this, SLOT(startFunction()));
percent++;
}
void myObj::init() {
percentTimer = new QTimer();
percentTimer->setInterval(1000);
connect(percentTimer, SIGNAL(timeout()), this, SLOT(percentUpdate()));
}
这是因为您试图从创建QTimer的线程以外的其他线程启动QTimer。使用QTimer和线程时,应非常小心地在将控制它的线程中创建QTimer
发件人:
在多线程应用程序中,可以在具有事件循环的任何线程中使用QTimer。若要从非GUI线程启动事件循环,请使用QThread::exec()。Qt使用计时器的线程关联来确定哪个线程将发出超时()信号。因此,必须在其线程中启动和停止计时器;无法从其他线程启动计时器
myObj::myObj(QObject *parent) : QObject(parent), percentTimer(nullptr)
{
moveToThread(&workerThread);
connect(&workerThread, SIGNAL(finished()), this, SLOT(deleteLater()));
connect(this, SIGNAL(UpdateResult()), mainClass, SLOT(on_UpdateResult()));
connect(&workerThread, SIGNAL(started()), this, SLOT(init()));
connect(&workerThread, SIGNAL(started()), this, SLOT(doWork()));
connect(this, SIGNAL(start()), this, SLOT(startFunction()));
percent++;
}
void myObj::init() {
percentTimer = new QTimer();
percentTimer->setInterval(1000);
connect(percentTimer, SIGNAL(timeout()), this, SLOT(percentUpdate()));
}
在您的情况下,percentTimer=new QTimer();
是从主线程执行的(即使您以前使用过moveToThread
,这仍然是执行它的主线程),而doWork
和start
信号是从workerThread
发出的
例如,您可以从workerThread
调用的void init()
插槽执行new QTimer
,而不是在构造函数中,以确保QTimer
由正确的线程创建和拥有
myObj::myObj(QObject *parent) : QObject(parent), percentTimer(nullptr)
{
moveToThread(&workerThread);
connect(&workerThread, SIGNAL(finished()), this, SLOT(deleteLater()));
connect(this, SIGNAL(UpdateResult()), mainClass, SLOT(on_UpdateResult()));
connect(&workerThread, SIGNAL(started()), this, SLOT(init()));
connect(&workerThread, SIGNAL(started()), this, SLOT(doWork()));
connect(this, SIGNAL(start()), this, SLOT(startFunction()));
percent++;
}
void myObj::init() {
percentTimer = new QTimer();
percentTimer->setInterval(1000);
connect(percentTimer, SIGNAL(timeout()), this, SLOT(percentUpdate()));
}
当您在调试器中单步执行此操作时会发生什么情况?首先在每个方法中放置一个断点。调用哪些断点,顺序如何?一切正常,除了在超时时从不调用插槽百分比更新@MrEricSir@MrEricSir,尝试在percentTimer->moveToThread(…)之前移动connect(percentTimer…
);
相同的结果@RealFresh、connect(&workerThread、SIGNAL(started())、percentTimer、SLOT(start())工作正常,但在我的应用程序中不起作用,因为我必须在某些时间间隔内启动、停止和更改间隔当问题陈述只是“它不起作用”时,很难提供解决方案。请回答您的问题,以便更完整地描述您预期会发生什么,以及这与实际结果之间的差异。请参阅,以获取有关什么是好的解释的提示。在调试器中单步执行此操作时会发生什么情况?从开始