QTimer不呼叫超时插槽
我试图在QThread
不同的QThread
内使用QTimer
,但我无法连接到QTimer
的timeout()
插槽。QTimer不呼叫超时插槽
我在做什么错?
这里是我的代码:
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();
}
首先,你应该SHART workerThread
让在其上下文myObj
工作(创建所需的连接后启动因为插槽连接到start
信号可能不会否则执行)。 而不是使用QThread::sleepFor
的你应该使用这样的事情:
QEventLoop loop;
QTimer::singleShot(60000, &loop, SLOT(exit()));
loop.exec();
创建延迟,因为QThread::sleepFor
冻结整体线程执行。所以你的任何事件都不会被绑定到这个线程。
workerThread.exec()
这里没用。
感谢作品(y)@RealFresh –
这是因为您试图从不同于创建QTimer的线程启动QTimer。当使用QTimer和线程时,您应该非常小心地在将控制它的线程中创建您的QTimer。
在多线程应用程序,你可以在有事件循环任何线程使用QTimer。要从非GUI线程启动事件循环,请使用QThread :: exec()。 Qt使用计时器的线程关联来确定哪个线程将发出timeout()信号。因此,您必须在其线程中启动和停止计时器;不可能从另一个线程启动一个定时器。
在你的情况percentTimer = new QTimer();
从主线程(即使你使用moveToThread
之前,这仍然是执行它的主线程)执行,而你doWork
和start
信号从发射workerThread
。
例如你可以做你的new QTimer
从void init()
插槽从workerThread
调用,而不是在构造函数中,以确保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
一切工作正常,除了插槽percentUpdate永远不会在超时时调用@MrEricSir –
@MrEricSir,尝试在'percentTimer-> moveToThread(...)之前移动'connect(percentTimer ...)'' –