簡體   English   中英

如何在QT GUI應用程序中執行適當的線程處理?

[英]How to do proper threading in QT GUI application?

我想同時運行兩個線程。 當我將程序作為QT控制台應用程序運行時,我成功地做了同樣的事情。 這是用於多線程的QT控制台應用程序的工作代碼:

myobject.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

main.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();
}

我的object.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應用程序運行時,線程不會並發運行,而是一個接一個地運行。 這是代碼:

主窗口

#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

main.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();
}

主窗口

#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都不能與其父代駐留在不同的線程中。 這是很自然的,因為父級是子級對象的所有者,最重要的是,它負責其子對象的銷毀。 要啟用此功能,子級不能處於其他線程中。 否則,例如,父母可能會破壞正在執行的孩子。

還有更多的收獲,例如,QPixmap不能位於主GUI等之外的其他線程中。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM