gpt4 book ai didi

c++ - 如何在 QT GUI 应用程序中进行正确的线程处理?

转载 作者:行者123 更新时间:2023-11-28 00:36:13 26 4
gpt4 key购买 nike

我想同时运行两个线程。当我将程序作为 QT 控制台应用程序运行时,我成功地做了同样的事情。这是用于多线程的 QT 控制台应用程序的工作代码:-

我的对象.h

#ifndef MYOBJECT_H
#define MYOBJECT_H

#include <QObject>
#include <QDebug>
#include <QThread>

class MyObject : public QObject
{
Q_OBJECT
public:
explicit MyObject(QObject *parent = 0);
void doSetup(QThread &cThread);
void doSetup2(QThread &cThread2);
signals:

public slots:
void doWork();
void doWork2();
};

#endif // MYOBJECT_H

主要.cpp:

#include <QtCore/QCoreApplication>
#include <QThread>
#include <myobject.h>
int main(int argc, char *argv[])
{
QCoreApplication a(argc, argv);

QThread cThread, cThread2;
MyObject cObject, cObject2;

cObject.doSetup(cThread);
cObject.moveToThread(&cThread);
cObject2.doSetup2(cThread2);
cObject2.moveToThread(&cThread2);
cThread.start();
cThread2.start();
qDebug()<<"hello there ";
return a.exec();
}

我的对象.cpp

#include "myobject.h"
#include <QThread>
#include "tftpServer.h"

MyObject::MyObject(QObject *parent) :
QObject(parent)
{
}

void MyObject::doSetup(QThread &cThread)
{
connect(&cThread, SIGNAL(started()), this, SLOT(doWork()));
}

void MyObject::doSetup2(QThread &cThread2)
{
connect(&cThread2, SIGNAL(started()), this, SLOT(doWork2()));
}
void MyObject::doWork()
{
for(int i=0; i<1000; i++)
{
qDebug()<<"******************Thread 1";


}

}
void MyObject::doWork2()
{
for(int i=1000; i<2000; i++)
{
qDebug()<<"Thread 2************************";


}

}

这是输出:

******************Thread 1
Thread 2************************
******************Thread 1
Thread 2************************
******************Thread 1
Thread 2************************
******************Thread 1
Thread 2************************

..等等

现在,当我使用这段几乎相同的代码并作为 QT GUI 应用程序运行时,线程不会同时运行,而是一个接一个地运行。这是代码:

主窗口.h

#ifndef MAINWINDOW_H
#define MAINWINDOW_H

#include <QMainWindow>
#include <QDebug>
#include <QThread>

namespace Ui {
class MainWindow;
}

class MainWindow : public QMainWindow
{
Q_OBJECT

public:
explicit MainWindow(QWidget *parent = 0);
~MainWindow();
void doSetup(QThread &cThread);
void doSetup2(QThread &cThread2);
private:
Ui::MainWindow *ui;

public slots:
void doWork();
void doWork2();
};

#endif // MAINWINDOW_H

主要.cpp

#include <QtGui/QApplication>
#include "mainwindow.h"
#include <QThread>
int main(int argc, char *argv[])
{
QApplication a(argc, argv);

QThread cThread, cThread2;
MainWindow cObject, cObject2;

cObject.doSetup(cThread);
cObject.moveToThread(&cThread);
cObject2.doSetup2(cThread2);
cObject2.moveToThread(&cThread2);
cThread.start();
cThread2.start();

MainWindow w;
w.show();

return a.exec();
}

主窗口.cpp

#include "mainwindow.h"
#include "ui_mainwindow.h"
#include <QThread>
#include <qthread.h>

MainWindow::MainWindow(QWidget *parent) :
QMainWindow(parent),
ui(new Ui::MainWindow)
{
ui->setupUi(this);
qDebug()<<"gui running";
}

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

void MainWindow::doSetup(QThread &cThread)
{
connect(&cThread, SIGNAL(started()), this, SLOT(doWork()));
}

void MainWindow::doSetup2(QThread &cThread2)
{
connect(&cThread2, SIGNAL(started()), this, SLOT(doWork2()));
}
void MainWindow::doWork()
{
//QThread::sleep(100);
for(int i=0; i<1000; i++)
{
qDebug()<<"******************Thread 1";
// qDebug()<<i;

}

}
void MainWindow::doWork2()
{
for(int i=1000; i<2000; i++)
{
qDebug()<<"Thread 2************************";
// qDebug()<<i;

}

}

这是输出:

gui running 
gui running
QObject::moveToThread: Widgets cannot be moved to a new thread
QObject::moveToThread: Widgets cannot be moved to a new thread
gui running
******************Thread 1
******************Thread 1
******************Thread 1
******************Thread 1

(等等……)

******************Thread 1
Thread 2************************
Thread 2************************
Thread 2************************
Thread 2************************
Thread 2************************
Thread 2************************

(等等……)请注意,我制作的黑白控制台和 gui 应用程序的唯一区别是将基类 QObject 更改为 QMainWindow,因此对于控制台和 GUI 应用程序,如此创建的线程对象分别是 QObject 和 QMainWindow 的对象。

希望我足够清楚,你能告诉我我犯了什么错误吗?它让线程一个接一个地运行,而不是像控制台应用程序那样同时运行?

谢谢。

最佳答案

任何继承自 QWidget 的类都不能驻留在主 GUI 线程之外的线程中。实际上这就是输出所说的。您的解决方案是一个糟糕的设计。分离工作对象(继承自QObject,驻留在另一个线程)和可视对象(继承自QWidget,驻留在GUI线程),遵循“一类一责”的原则。

Qt 中多线程的另一个问题是任何 QObject 都不能驻留在与其父线程不同的线程中。这是很自然的,因为父对象是子对象的所有者,最重要的是它负责销毁子对象。要启用此功能, child 不能在其他线程中。否则,例如, parent 可能会破坏正在执行的 child 。

还有更多问题,例如 QPixmap 不能在主 GUI 以外的其他线程中等。

关于c++ - 如何在 QT GUI 应用程序中进行正确的线程处理?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/20855527/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com