繁体   English   中英

QTimer不调用超时槽

[英]QTimer doesn't call timeout slot

我试图在不同的QThread使用QTimer ,但无法连接到QTimertimeout()插槽。

我究竟做错了什么?

这是我的代码:

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();

}

这是因为您试图从与创建它的线程不同的线程中启动QTimer。 使用QTimer和线程时,应该非常小心在将控制它的线程中创建QTimer。

QTimer类文档

在多线程应用程序中,可以在具有事件循环的任何线程中使用QTimer。 要从非GUI线程启动事件循环,请使用QThread :: exec()。 Qt使用计时器的线程关联性来确定哪个线程将发出timeout()信号。 因此, 您必须在其线程中启动和停止计时器 无法从另一个线程启动计时器。

在您的情况下, percentTimer = new QTimer(); 从主线程执行(即使您之前使用过moveToThread ,但仍是执行它的主线程),而doWorkstart信号是从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()));
}

首先,您应该使用workerThread来让myObj在其上下文中工作( 创建所需的连接启动它因为连接到start信号的插槽可能不会执行)。 而不是使用QThread::sleepFor您应该使用这样的东西:

QEventLoop loop;
QTimer::singleShot(60000, &loop, SLOT(exit()));
loop.exec();

创建延迟,因为QThread::sleepFor冻结了整个线程的执行。 因此,绑定到该线程的事件都不会被处理。

这里的workerThread.exec()是没有用的。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM