gpt4 book ai didi

c++ - QThread 和 QTimer

转载 作者:太空狗 更新时间:2023-10-29 19:44:04 27 4
gpt4 key购买 nike

我正在开发一个使用 Qt 4.6 开发的应用程序。

我想创建一个在单独线程中计数的自定义计时器。但是,我希望这个计时器能够向主线程发送信号。

我对 QThread 进行了子类化,但它似乎不起作用。

这是 Timer.h:

#ifndef TIMER_H
#define TIMER_H

#include <QtCore/QObject>
#include <QtCore/QThread>
#include <QtCore/QTimer>

class Timer : public QThread
{
Q_OBJECT
public:
explicit Timer(QObject *parent = 0);
~Timer();

// true if the timer is active
bool isCounting();

// start the timer with a number of seconds
void startCounting(int value = 300);
void stopCounting();

// the number of seconds to reach
int maximum();

// the current value of the timer
int value();

// elapsed time since the timer has started
int elapsedTime();

signals:
// sent when the timer finishes to count
void timeout();
// an event is emited at each second when the timer is active
void top(int remainingSeconds);

protected:
// launch the thread
//virtual void run();

private slots:
// decrements the remaining time at each second and emits top()
void timerEvent();

private:
QTimer* _timer;
// remaining time
int _left;
// number of seconds at timer startup
int _maximum;
};

#endif // TIMER_H

和Timer.cpp:

#include "Timer.h"

Timer::Timer(QObject *parent) :
QThread(parent)
{
_timer = new QTimer(this);
_maximum = 0;
_left = 0;
connect(_timer, SIGNAL(timeout()), this, SLOT(timerEvent()));
}

Timer::~Timer()
{
delete _timer;
}

bool Timer::isCounting()
{
// test if timer still active
return _timer->isActive();
}

void Timer::startCounting(int value)
{
qDebug() << QString("Start timer for %1 secs").arg(QString::number(value));
if(_left != 0 || _timer->isActive())
{
_timer->stop();
}

_maximum = value;
_left = value;

// emit the first top
emit top(_left);

// start the timer: 1000 msecs
_timer->start(1000);

// start the thread
start();
}

void Timer::stopCounting()
{
qDebug() << QString("Stopping timer at %1 secs => %2 secs remaining.").arg(QString::number(elapsedTime()), QString::number(_left));
// stop timer
_timer->stop();
_left = 0;
_maximum = 0;
// kill thread
terminate();
}

int Timer::maximum()
{
return _maximum;
}

int Timer::value()
{
return _left;
}

void Timer::timerEvent()
{
qDebug() << "Timer event";
if(--_left == 0)
{
// stop timer
_timer->stop();
// emit end of timer
emit timeout();
// stop thread
terminate();
}
else
{
// emit a signal at each second
emit top(_left);
}
}

int Timer::elapsedTime()
{
return (_maximum - _left);
}

编辑

我意识到我试图移动到另一个线程的对象实际上是一个单例。这可能会导致问题 ( see here )。

最佳答案

在这种特殊情况下,您不需要子类化 QThread。通常,除非您确定它是您所需要的,否则不要对 QThread 进行子类化。

这是一个简单的示例,说明如何在线程中设置工作程序和计时器并启动它:

worker 类(Class):

class Worker : public QObject
{
Q_OBJECT
public:
explicit Worker(QObject *parent = 0) : QObject(parent) {}

signals:
void doSomething();

public slots:
void trigger() {
emit doSomething();
}
};

主要.cpp

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

MainThreadObject o;

QThread *thread = new QThread;
Worker w;
QTimer timer;
timer.setInterval(1000);

timer.moveToThread(thread);
w.moveToThread(thread);

QObject::connect(thread, SIGNAL(started()), &timer, SLOT(start()));
QObject::connect(&w, SIGNAL(doSomething()), &o, SLOT(doSomething()));
QObject::connect(&timer, SIGNAL(timeout()), &w, SLOT(trigger()));

thread->start();

return a.exec();
}

因此,我们有 MainThreadObject,它表示派生在主线程中的 QObject。我们创建定时器和 Worker 对象,它只是用来包装信号和槽以避免子类化 QThread 的需要。计时器已设置,它和工作人员被移动到新线程,线程 started() 信号连接到计时器 start() 槽,工作人员 doSomething()信号连接到主线程对象doSomething()槽,最后定时器timeout()信号连接到workertrigger() 插槽。然后启动线程,启动事件循环中的整个链。

因此,每秒都会调用 MainThreadObject::doSomething(),并从辅助线程发出信号。

关于c++ - QThread 和 QTimer,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/15835267/

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