使用 Qthread-Qt5 创建新线程

creating new thread using Qthread-Qt5

本文关键字:线程 新线程 Qthread-Qt5 创建 使用      更新时间:2023-10-16

我正在尝试创建一个应该在后台运行的新线程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 threadn";
    QTimer *t = new QTimer(this);
     connect(t, SIGNAL(timeout()), this, SLOT(processgps()));
     t->start(10000);
    }
public slots:void processgps(){
    int status2;
    status2=gps_management();
}
};

我的主要课程是概览。

int main(int argc, char *argv[])
{
QString file = "qml/main.qml";
QApplication app(argc, argv);
TranslationTest myObj;
QuickView view;
subthread object;
gpsthread obj;
gprsthread gprs;
view.rootContext()->setContextProperty("rootItem", (QObject *)&myObj);
    obj.start();
//from subthread
QObject::connect(&object, SIGNAL(batterytoqml(QVariant,QVariant)),item, SLOT(frombattery(QVariant,QVariant)));
QObject::connect(&gprs, SIGNAL(gprstoqml(QVariant)),item, SLOT(fromgprs(QVariant)));
return app.exec();

}

我也试过这个

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 threadn";
    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 thread

如果我在构造函数中创建对象,那么它也会产生相同的错误,因为该对象将在主线程中创建。如何解决这个问题?

不建议使用从 QThread 继承。QThread 是一个运行事件循环的完整类,这通常是您需要的。该文档建议使用从 QObject 继承并在插槽中工作的工作器对象。工作线程被移动到 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();
}

如果您希望计时器也存在于另一个线程中,QTimer::start是一个插槽。

QObject: Cannot create children for a parent that is in a different thready

是因为run()中的t = new QTimer(this)是在子线程中创建一个对象,但this gpsthread点在主线程中。一个简单的解决方案是在没有父级的情况下t = new QTimer()并删除析构函数中的计时器。下面是一个示例:

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;
};

很快你会发现控制台打印:

Parent thread 0x3b28
inside gps thread 0x3f10
processgps() 0x3b28
processgps() 0x3b28
processgps() 0x3b28
processgps() 0x3b28

这意味着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;
};

这不是一个好的解决方案,一种建议的方法是创建一个worker来完成所有工作,然后使用QObject::moveToThread((,如QThread文档中所述