gpt4 book ai didi

c++ - 多线程应用程序中的 QTimer

转载 作者:太空宇宙 更新时间:2023-11-03 10:44:07 26 4
gpt4 key购买 nike

好吧,我已经完全迷失在 QTimer 中了。问题是:我有多线程应用程序,我需要对 QTimer 的超时做一些处理。我这样做过:

QTimer* timer = new QTimer();
timer->setSingleShot(true);
connect(timer, SIGNAL(timeout()), someObject, SLOT(work()));

但这并没有奏效。有时根本不调用work(),有时关闭程序时调用,有时一切正常。
所以我开始想到计时器需要线程。提供 MCV 示例:

class Tester : public QObject
{
Q_OBJECT
public:
Tester(QObject* par = 0) : QObject(par)
{
}
public slots:
void greet()
{
qDebug()<<"hello";
}
};

int main(int argc, char *argv[])
{
QCoreApplication a(argc, argv);

QTimer* timer1 = new QTimer();

QThread* thread = new QThread();
Tester* tester = new Tester();

timer1->setInterval(500);
timer1->setSingleShot(false);
timer1->moveToThread(thread);


QObject::connect(thread, SIGNAL(started()), timer1, SLOT(start()));

QObject::connect(timer1, SIGNAL(timeout()), tester, SLOT(greet()));

QObject::connect(timer1, SIGNAL(timeout()), timer1, SLOT(deleteLater()));
QObject::connect(timer1, SIGNAL(destroyed()), thread, SLOT(quit()));

thread->start();

thread->wait();

delete thread;
delete tester;

return a.exec();
}

而这个例子什么也没做。它没有问候我,所以没有调用超时,也没有结束,所以线程没有停止。所以问题是:
1.这段代码有什么问题?
2. 在多线程环境下如何正确使用QTimer?

最佳答案

只需调用 QTimer::setInterval不启动 QTimer。它只是设置 QTimer::timeout 的间隔发出信号。你没有启动 QTimer。使用 QTimer::start .

我认为你在这里犯了几个错误。建立所有连接后,您需要将计时器移至线程。不确定在线程启动时启动计时器有多安全,因为此时计时器将在一个线程中,而线程对象将在另一个线程中。 QTimer 必须从创建它的同一个线程启动。 QThread 对象只是一个线程处理程序,它存在于创建的线程中。查看我对您的示例所做的修改:

#include <QCoreApplication>
#include <QThread>
#include <QDebug>
#include <QTimer>
#include <QObject>

//#include "tester.h"

class Tester : public QObject
{
Q_OBJECT

public:
Tester(QObject* par = 0) : QObject(par)
{
}

public slots:
void greet()
{
qDebug()<<"hello";
}
};

int main(int argc, char *argv[])
{
QCoreApplication a(argc, argv);

QTimer* timer1 = new QTimer();

QThread* thread = new QThread();
Tester* tester = new Tester();

timer1->setInterval(500);
timer1->setSingleShot(false);
timer1->start();

QObject::connect(timer1, SIGNAL(timeout()), tester, SLOT(greet()));

timer1->moveToThread(thread);

thread->start();

return a.exec();
}

这不是最安全/最好的修复(内存泄漏和其他),但我希望它是您可以构建的示例。

在我看来,这是在另一个 QThread 中使用 QTimer 的正确且没有内存泄漏的方法:

handler.h

#ifndef HANDLER_H
#define HANDLER_H

#include <QObject>

class QTimer;
class QThread;
class Tester;

class Handler : public QObject
{
Q_OBJECT

public:
explicit Handler(QObject *parent = 0);
~Handler();

void exec();

private:
QTimer* timer;
QThread* thread;
Tester* tester;
};

#endif // HANDLER_H

handler.cpp

#include "handler.h"
#include "tester.h"

#include <QThread>
#include <QDebug>
#include <QTimer>
#include <QObject>
#include <QCoreApplication>

Handler::Handler(QObject *parent) :
QObject(parent)
{
timer = new QTimer;
thread = new QThread(this);
tester = new Tester(this);

timer->setInterval(500);
timer->setSingleShot(false);

QObject::connect(timer, SIGNAL(timeout()), tester, SLOT(greet()));
QObject::connect(thread, SIGNAL(destroyed()), timer, SLOT(deleteLater()));
}

Handler::~Handler()
{
thread->wait();
}

void Handler::exec()
{
timer->start();

timer->moveToThread(thread);

thread->start();
}

tester.h

#ifndef TESTER_H
#define TESTER_H

#include <QObject>

class Tester : public QObject
{
Q_OBJECT

public:
Tester(QObject* par = 0);

public slots:
void greet();
};


#endif // TESTER_H

tester.cpp

#include "tester.h"

#include <QDebug>

Tester::Tester(QObject *parent) :
QObject(parent)
{
}

void Tester::greet()
{
qDebug()<<"hello";
}

main.cpp

#include <QCoreApplication>

#include "handler.h"

int main(int argc, char *argv[])
{
QCoreApplication a(argc, argv);

Handler handler;
handler.exec();

return a.exec();
}

关于c++ - 多线程应用程序中的 QTimer,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/26369904/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com