C++ 使用Qthread-Qt5创建新线程
我正在尝试创建一个新线程C++ 使用Qthread-Qt5创建新线程,c++,multithreading,qt5,qthread,C++,Multithreading,Qt5,Qthread,我正在尝试创建一个新线程gpsthread,它应该在后台运行,并存储该值 class gpsthread: public QThread{ Q_OBJECT private:nrega_status_t status2; public: explicit gpsthread(QObject *parent = 0):QThread(parent) { // QTimer *t = new QTimer(this); // connect(t, SIGNAL(timeo
gpsthread
,它应该在后台运行,并存储该值
class gpsthread: public QThread{
Q_OBJECT
private:nrega_status_t status2;
public:
explicit gpsthread(QObject *parent = 0):QThread(parent) {
// QTimer *t = new QTimer(this);
// connect(t, SIGNAL(timeout()), this, SLOT(processgps()));
// t->start(10000);
}
void run(){
qDebug()<<"inside gps thread\n";
QTimer *t = new QTimer(this);
connect(t, SIGNAL(timeout()), this, SLOT(processgps()));
t->start(10000);
}
public slots:void processgps(){
int status2;
status2=gps_management();
}
};
}
我也试过这个
class gpsthread: public QThread{
Q_OBJECT
private:nrega_status_t status2;
public:QTimer* t;
explicit gpsthread(QObject *parent = 0):QThread(parent) {
// QTimer *t = new QTimer(this);
// connect(t, SIGNAL(timeout()), this, SLOT(processgps()));
// t->start(10000);
}
void run(){
qDebug()<<"inside gps thread\n";
t = new QTimer(this);
connect(t, SIGNAL(timeout()), this, SLOT(processgps()));
t->start(10000);
exec();
}
public slots:void processgps(){
int status2;
status2=gps_management();
}
};
如果我在构造函数中创建对象,那么它也会给出相同的错误,因为该对象将在主线程中创建。
如何解决这个问题
QObject: Cannot create children for a parent that is in a different thready
因为run()
中的t=new QTimer(this)
正在子线程中创建对象,但是this
位于gpsthread
的点在主线程中。一个简单的解决方案是在没有父对象的情况下删除析构函数中的计时器。以下是一个例子:
class gpsthread : public QThread {
Q_OBJECT
public:
explicit gpsthread(QObject *parent = 0):
QThread(parent)
,timer(NULL) {
qDebug() << "Parent thread" << QThread::currentThreadId();
}
~gpsthread() {
quit();
wait();
delete timer;
}
protected:
void run() {
qDebug() << "Inside gps thread" << QThread::currentThreadId();
timer = new QTimer; // no parent
connect(timer, SIGNAL(timeout()), this, SLOT(processgps()));
timer->start(1000);
exec();
}
public slots:
void processgps() {
qDebug() << "processgps()" << QThread::currentThreadId();
}
private:
QTimer *timer;
};
这意味着processgps()
在子线程中不起作用。这是因为此插槽是主线程中的gpsthread
的成员。一个简单的解决方案是直接调用processgps()
,并使用sleep()
作为计时器:
class gpsthread : public QThread
{
Q_OBJECT
public:
explicit gpsthread(QObject *parent = 0):
QThread(parent)
, abort(false) {
qDebug() << "Parent thread" << QThread::currentThreadId();
}
~gpsthread() {
abort = true;
wait();
}
protected:
void run() {
while(!abort) {
sleep(1);
processgps();
}
}
public slots:
void processgps() {
qDebug() << "processgps()" << QThread::currentThreadId();
}
private:
bool abort;
};
类gpsthread:publicqthread
{
Q_对象
公众:
显式gpsthread(QObject*parent=0):
QThread(父线程)
,中止(错误){
qDebug()不建议使用从QThread继承。QThread是运行事件循环的完整类,这通常是您需要的。建议使用从QObject继承并在插槽中工作的worker对象。worker被移动到QThread中。当发送连接的信号时,插槽将在正确的线程中运行
class gpsworker: public QObject
{
Q_OBJECT
public:
explicit gpsworker(QObject *parent = 0):
QObject(parent)
{}
public slots:
void processgps() {
qDebug() << "processgps()" << QThread::currentThreadId();
}
}
void OwnerClass::startWorker() {
QTimer *timer = new QTimer(this);
QThread *thread = new QThread(this);
this->worker = new gpsworker();
this->worker->moveToThread(thread);
connect(timer, SIGNAL(timeout()), this->worker, SLOT(processgps()) );
connect(thread, SIGNAL(finished()), this->worker, SLOT(deleteLater()) );
thread->start();
timer->start();
}
gpsworker类:公共QObject
{
Q_对象
公众:
显式gpsworker(QObject*parent=0):
QObject(父对象)
{}
公众时段:
void processgps(){
qDebug()辅助程序->移动到线程(线程);
连接(计时器,信号(timeout()),此->工作,插槽(processgps());
连接(线程,信号(finished()),此->工作线程,插槽(deleteLater());
线程->开始();
定时器->启动();
}
如果您想让计时器也存在于另一个线程中,
QTimer::start
是一个插槽。感谢您的解释……这确实是使用线程的正确方法。您是否缺少timer->setSingleShot(true)
在那里?@Jack single shot不在问题中,因此我没有在我的回答中添加它。考虑到很长的超时时间,我们可以合理地假设工人应该在这个固定的时间间隔内处理GPS
。
Parent thread 0x3b28
inside gps thread 0x3f10
processgps() 0x3b28
processgps() 0x3b28
processgps() 0x3b28
processgps() 0x3b28
class gpsthread : public QThread
{
Q_OBJECT
public:
explicit gpsthread(QObject *parent = 0):
QThread(parent)
, abort(false) {
qDebug() << "Parent thread" << QThread::currentThreadId();
}
~gpsthread() {
abort = true;
wait();
}
protected:
void run() {
while(!abort) {
sleep(1);
processgps();
}
}
public slots:
void processgps() {
qDebug() << "processgps()" << QThread::currentThreadId();
}
private:
bool abort;
};
class gpsworker: public QObject
{
Q_OBJECT
public:
explicit gpsworker(QObject *parent = 0):
QObject(parent)
{}
public slots:
void processgps() {
qDebug() << "processgps()" << QThread::currentThreadId();
}
}
void OwnerClass::startWorker() {
QTimer *timer = new QTimer(this);
QThread *thread = new QThread(this);
this->worker = new gpsworker();
this->worker->moveToThread(thread);
connect(timer, SIGNAL(timeout()), this->worker, SLOT(processgps()) );
connect(thread, SIGNAL(finished()), this->worker, SLOT(deleteLater()) );
thread->start();
timer->start();
}