首页 > 解决方案 > QThread 中的 Qt C++ 计时器并将数据从 QThread 发送到 GUI 线程

问题描述

我在一个线程中创建了一个计时器,在这个计时器中,char 值从 0 计数到 10。我想在 GUI 上显示这个 char 值。我没有收到任何错误,但我开始时 GUI 冻结。

你能帮我看看我在哪里做错了吗?

主文件

#include "mainwindow.h"
#include <QApplication>

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

MainWindow w;
w.show();
return a.exec();
}

主窗口.h

#ifndef MAINWINDOW_H
#define MAINWINDOW_H

#include "mythread.h"
#include <QMainWindow>

QT_BEGIN_NAMESPACE
namespace Ui { class MainWindow; }
QT_END_NAMESPACE

class MainWindow : public QMainWindow
{
    Q_OBJECT

public:
    explicit MainWindow(QWidget *parent = nullptr);
    ~MainWindow();
    MyThread *mThread;

private:
    Ui::MainWindow *ui;

public slots:
    void onNumberChanged(char);
};

#endif // MAINWINDOW_H

主窗口.cpp

#include "mainwindow.h"
#include "ui_mainwindow.h"

MainWindow::MainWindow(QWidget *parent)
    : QMainWindow(parent)
    , ui(new Ui::MainWindow)
{
    ui->setupUi(this);

    mThread = new MyThread(this);
    connect(mThread,SIGNAL(NumberChanged(char)), this, SLOT(onNumberChanged(char)));
    mThread->start();
}

MainWindow::~MainWindow()
{
    delete ui;
}

void MainWindow::onNumberChanged(char Number)
{
    ui->label->setText(QString::number(Number));
}

我的线程.h

#include <QThread>
#include <QTimer>
#include <QObject>

class MyThread : public QThread
{
    Q_OBJECT
public:
    explicit MyThread(QObject *parent = 0);
    void run();

signals:
    void NumberChanged(char);

public slots:
    void update();

private:
    QTimer *timer;

};

我的线程.cpp

#include "mythread.h"
#include <QtCore>

char i=45;
QString mystr = "mytext";

MyThread::MyThread(QObject *parent) :
    QThread(parent)
{
    timer= new QTimer();
    connect(timer,SIGNAL(timeout()),this,SLOT(update()));
    timer->start(10);
}

void MyThread::update()
{
    for( i = 0; i<10; i++){
    emit NumberChanged(i);
    this->msleep(500);
    }
    if (i>0)
        i=0;
}

void MyThread::run()
{
}

标签: c++qtqt5qthreadqtimer

解决方案


您需要在 run() 函数中创建计时器,而不是在构造函数中。因为在 GUI 线程中调用构造函数,并且在此函数中创建的每个对象都在 GUI 线程中。或者您可以调用 moveToThread 让您的计时器移动到您的线程。


推荐阅读