【发布时间】:2021-12-25 06:30:40
【问题描述】:
我在一个线程中创建了一个计时器,在这个计时器中,char 值从 0 计数到 10。 我想在 GUI 上显示这个 char 值。我没有收到任何错误,但我启动时 GUI 冻结。
你能帮我看看我哪里做错了吗?
main.cpp
#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));
}
mythread.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;
};
mythread.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()
{
}
【问题讨论】:
-
MyThread将QTimer设置为每10 毫秒调用一次update(),但在update()内你调用msleep(500)10 次,这意味着update()将花费超过5 秒返回。其中一件事必须要完成;如果您想经常拨打update(),则需要快速返回。 -
请阅读 Qt 中的线程和线程亲和性。您的代码清楚地表明您正在使用试错法来了解线程。虽然这种方法可能适用于 Qt 的某些其他领域,但它绝对不适用于线程......原因是线程可能经常看起来正常工作,即使它们没有正常工作。对于线程,您需要了解机制的逻辑。您需要了解线程对象“存在”在主 GUI 线程中,但它的
run()方法是在线程本身中执行的。顺便提一句。为什么你的run()是空的?这没有任何意义。 -
顺便说一句。不要再使用带有
SIGNAL和SLOT宏的旧式连接。它已经过时了很长时间。我敢打赌你不使用 Qt4,对吗? -
也不要使用全局变量...(除非你真的必须)
-
@JeremyFriesner 好的,如果我删除
msleep(500),一切都好吗? @V.K.谢谢你,我会读的。我在run()中初始化、连接并启动了计时器,它仍然无法正常工作。我正在使用 Qt 5。我不知道用什么来代替SIGNAL和SLOT这就是我使用的原因。我可以用什么代替?