使用自己的 QTimer 和 QThread 自定义 class
custom class with its own QTimer and QThread
我想为 Robot 传感器的某些项目创建一个具有自己的 QTimer 和 QThread 的 class。经过一番搜索,这就是我想出的
#include <QCoreApplication>
#include <QTimer>
#include <QThread>
#include <QObject>
#include <QDebug>
//#####################( Robot Class )#########################3
class Robot : public QObject
{
public:
Robot(QObject *parent = 0);
~Robot();
private:
QTimer *mQTimer;
QThread *mQThread;
public slots:
void update();
};
Robot::Robot(QObject *parent)
: QObject(parent)
{
mQTimer = new QTimer(0);
mQThread = new QThread(this);
mQTimer->setInterval(1);
mQTimer->moveToThread(mQThread);
connect(mQTimer, SIGNAL(timeout()), this, SLOT(update()));
connect(mQThread, SIGNAL(started()), mQTimer, SLOT(start()));
mQThread->start();
//mQTimer->start();
}
Robot::~Robot()
{
delete mQTimer;
delete mQThread;
}
void Robot::update()
{
qDebug() << "Robot is updating ...";
}
//##################( Main )###########################
int main(int argc, char *argv[])
{
QCoreApplication a(argc, argv);
Robot *myRobot = new Robot(0);
return a.exec();
}
我遇到了这个错误
QObject::connect: No such slot QObject::update() in ..\untitled1\main.cpp:34
QObject::connect: No such slot QObject::update() in ..\untitled1\main.cpp:34
您在 class 中缺少 Q_OBJECT 宏也尽量避免这样命名方法,因为您可以将它与 Qt 方法名称混合使用。还要为每个 class 创建额外的头文件和 cpp 文件,在本例中创建 robtot.h 和 robot.cpp.
class Robot : public QObject
{
Q_OBJECT
public:
Robot(QObject *parent = 0);
~Robot();
...
以下适合我。您忘记了 Q_OBJECT
宏并包含为 Robot
.
定义静态元数据的 moc 输出
这段代码当然没有意义,因为 Robot::update
插槽将在主线程中执行。
您的代码有两个线程:Robot
对象所在的主线程,以及计时器所在的 robot.mThread
。计时器将在 mThread
中超时,并将在主线程上对插槽调用进行排队。该插槽调用最终将调用 robot.update
,堆栈上有 a.exec
。
请注意,无需使用 new
在堆上显式分配计时器和线程。他们应该是 Robot
或其 PIMPL 的直接成员。
main.cpp
#include <QCoreApplication>
#include <QTimer>
#include <QThread>
#include <QDebug>
class Robot : public QObject
{
Q_OBJECT
QTimer mTimer;
QThread mThread;
public:
Robot(QObject *parent = 0) : QObject(parent) {
connect(&mTimer, &QTimer::timeout, this, &Robot::update);;
mTimer.start(1000);
mTimer.moveToThread(&mThread);
mThread.start();
}
Q_SLOT void update() {
qDebug() << "updating";
}
};
int main(int argc, char *argv[])
{
QCoreApplication a(argc, argv);
Robot robot;
return a.exec();
}
#include "main.moc"
将整个机器人移动到它自己的线程会更有意义。请注意,当您这样做时,您需要在机器人拥有的所有对象上设置亲子关系,以便它们都与 Robot
对象一起切换线程。
Thread
class 修复了 QThread
长期存在的可用性错误 - 它将它变成了真正的 RAII class,可以随时安全地销毁。
main.cpp
#include <QCoreApplication>
#include <QTimer>
#include <QThread>
#include <QDebug>
class Thread : public QThread {
using QThread::run;
public:
~Thread() { quit(); wait(); }
};
class Robot : public QObject
{
Q_OBJECT
QTimer mTimer;
int mCounter;
public:
Robot(QObject *parent = 0) : QObject(parent), mTimer(this), mCounter(0) {
connect(&mTimer, &QTimer::timeout, this, &Robot::update);;
mTimer.start(1000);
}
Q_SLOT void update() {
qDebug() << "updating";
if (++mCounter > 5) qApp->exit();
}
};
int main(int argc, char *argv[])
{
QCoreApplication a(argc, argv);
Robot robot;
Thread thread;
robot.moveToThread(&thread);
thread.start();
return a.exec();
}
#include "main.moc"
我想为 Robot 传感器的某些项目创建一个具有自己的 QTimer 和 QThread 的 class。经过一番搜索,这就是我想出的
#include <QCoreApplication>
#include <QTimer>
#include <QThread>
#include <QObject>
#include <QDebug>
//#####################( Robot Class )#########################3
class Robot : public QObject
{
public:
Robot(QObject *parent = 0);
~Robot();
private:
QTimer *mQTimer;
QThread *mQThread;
public slots:
void update();
};
Robot::Robot(QObject *parent)
: QObject(parent)
{
mQTimer = new QTimer(0);
mQThread = new QThread(this);
mQTimer->setInterval(1);
mQTimer->moveToThread(mQThread);
connect(mQTimer, SIGNAL(timeout()), this, SLOT(update()));
connect(mQThread, SIGNAL(started()), mQTimer, SLOT(start()));
mQThread->start();
//mQTimer->start();
}
Robot::~Robot()
{
delete mQTimer;
delete mQThread;
}
void Robot::update()
{
qDebug() << "Robot is updating ...";
}
//##################( Main )###########################
int main(int argc, char *argv[])
{
QCoreApplication a(argc, argv);
Robot *myRobot = new Robot(0);
return a.exec();
}
我遇到了这个错误
QObject::connect: No such slot QObject::update() in ..\untitled1\main.cpp:34
QObject::connect: No such slot QObject::update() in ..\untitled1\main.cpp:34
您在 class 中缺少 Q_OBJECT 宏也尽量避免这样命名方法,因为您可以将它与 Qt 方法名称混合使用。还要为每个 class 创建额外的头文件和 cpp 文件,在本例中创建 robtot.h 和 robot.cpp.
class Robot : public QObject
{
Q_OBJECT
public:
Robot(QObject *parent = 0);
~Robot();
...
以下适合我。您忘记了 Q_OBJECT
宏并包含为 Robot
.
这段代码当然没有意义,因为 Robot::update
插槽将在主线程中执行。
您的代码有两个线程:Robot
对象所在的主线程,以及计时器所在的 robot.mThread
。计时器将在 mThread
中超时,并将在主线程上对插槽调用进行排队。该插槽调用最终将调用 robot.update
,堆栈上有 a.exec
。
请注意,无需使用 new
在堆上显式分配计时器和线程。他们应该是 Robot
或其 PIMPL 的直接成员。
main.cpp
#include <QCoreApplication>
#include <QTimer>
#include <QThread>
#include <QDebug>
class Robot : public QObject
{
Q_OBJECT
QTimer mTimer;
QThread mThread;
public:
Robot(QObject *parent = 0) : QObject(parent) {
connect(&mTimer, &QTimer::timeout, this, &Robot::update);;
mTimer.start(1000);
mTimer.moveToThread(&mThread);
mThread.start();
}
Q_SLOT void update() {
qDebug() << "updating";
}
};
int main(int argc, char *argv[])
{
QCoreApplication a(argc, argv);
Robot robot;
return a.exec();
}
#include "main.moc"
将整个机器人移动到它自己的线程会更有意义。请注意,当您这样做时,您需要在机器人拥有的所有对象上设置亲子关系,以便它们都与 Robot
对象一起切换线程。
Thread
class 修复了 QThread
长期存在的可用性错误 - 它将它变成了真正的 RAII class,可以随时安全地销毁。
main.cpp
#include <QCoreApplication>
#include <QTimer>
#include <QThread>
#include <QDebug>
class Thread : public QThread {
using QThread::run;
public:
~Thread() { quit(); wait(); }
};
class Robot : public QObject
{
Q_OBJECT
QTimer mTimer;
int mCounter;
public:
Robot(QObject *parent = 0) : QObject(parent), mTimer(this), mCounter(0) {
connect(&mTimer, &QTimer::timeout, this, &Robot::update);;
mTimer.start(1000);
}
Q_SLOT void update() {
qDebug() << "updating";
if (++mCounter > 5) qApp->exit();
}
};
int main(int argc, char *argv[])
{
QCoreApplication a(argc, argv);
Robot robot;
Thread thread;
robot.moveToThread(&thread);
thread.start();
return a.exec();
}
#include "main.moc"