簡體   English   中英

Qt的簡單多線程:我做對了嗎?

[英]Simple multithreading with Qt: am I doing this right?

我是StackOverflow的新手,想知道我是否做對了:

我正在編寫一個簡單的Qt應用程序來測試多線程(這也是我的新手)。 我制作了一個包含小部件的MainWindow,以及一個MyThread類,該類繼承QThread並覆蓋run()方法。

該應用程序僅顯示兩個按鈕,“開始計數器”和“停止計數器”,以及一個文本字段。 當按下“啟動計數器”時,將創建一個工作線程並在后台運行,在while循環中不斷增加計數器,並用更新的值向主線程(GUI所在的位置)發出信號。 當按下“停止計數器”時,一個信號被發送到主線程,該線程停止while循環,並且計數器停止直到再次按下“啟動計數器”。

這工作得很好...但這是最好的方法嗎? 我是新來的人,讀過很多人說“不要把QThread子類化”,還有其他人說“不要把QThread子類化”,這有點令人困惑。 如果這不是實現這種事情的最佳方法(使用“開始”和“停止”按鈕在后台線程中運行計算密集型循環),那是什么? 如果我做錯了,該怎么做? 我不想學習錯誤的方法。

謝謝! 這是代碼:

MyThread.h

#ifndef MYTHREAD_H
#define MYTHREAD_H

#include <QThread>
#include <QMutex>

class MyThread : public QThread
{
   Q_OBJECT

public slots:
    void stopRunning();

protected:
   virtual void run();

signals:
   void signalValueUpdated(QString);

private:
    bool isRunning;

};

MyThread.cpp

#include "MyThread.h"
#include <QString>

void MyThread::run()
{
    qDebug("Thread id inside run %d",(int)QThread::currentThreadId());

    static int value=0; //If this is not static, then it is reset to 0 every time this function is called.
    isRunning = 1;
    while(isRunning == 1)
    {
        QString string = QString("value: %1").arg(value++);
        sleep(1/1000); //If this isn't here, the counter increments way too fast and dies, or something; the app freezes, anyway.

        emit signalValueUpdated(string);       
    }            
}

void MyThread::stopRunning()
{
    isRunning = 0;
}

MainWindow.h

#ifndef MAINWINDOW_H
#define MAINWINDOW_H

#include <QApplication>
#include <QPushButton>
#include <QHBoxLayout>
#include <QLineEdit>
#include "MyThread.h"

class MainWindow : public QWidget
{
  Q_OBJECT

  public:
    MainWindow(QWidget *parent = 0);

  private:
    //Widgets
    QHBoxLayout * boxLayout;
    QPushButton * startButton;
    QPushButton * stopButton;
    QLineEdit * lineEdit;

    MyThread thread;
};

#endif

MainWindow.cpp

#include "MainWindow.h"

MainWindow::MainWindow(QWidget *parent) : QWidget(parent)
{
    boxLayout = new QHBoxLayout(this);
    startButton = new QPushButton("Start Counter", this);
    stopButton = new QPushButton("Stop Counter", this);
    lineEdit = new QLineEdit(this);

    boxLayout->addWidget(startButton);
    boxLayout->addWidget(stopButton); 
    boxLayout->addWidget(lineEdit);

    qDebug("Thread id %d",(int)QThread::currentThreadId());

    //When the start button is pressed, invoke the start() method in the counter thread
    QObject::connect(startButton,SIGNAL(clicked()),&thread,SLOT(start()), Qt::QueuedConnection);

    //When the stop button is pressed, invoke the stop() method in the counter thread
    QObject::connect(stopButton,SIGNAL(clicked()),&thread,SLOT(stopRunning()), Qt::QueuedConnection);

    //When the counter thread emits a signal saying its value has been updated, reflect that change in the lineEdit field.
    QObject::connect(&thread,SIGNAL(signalValueUpdated(const QString&)),lineEdit,SLOT(setText(const QString&)), Qt::QueuedConnection);
}

大多數時候,QThread子類化是在Qt中進行線程化的錯誤方法。 我建議您閱讀有關線程,事件循環和其他內容的文章,這可以使您了解如何以更好的方式在Qt中使用線程。 但是,不要聽任何人爭論使用QThread是唯一正確的方法。 有兩種方法,雖然通常不需要子類化,但有時它可能很有用。 您只需要使用非子類化方式,直到真正需要子類化為止。 在您的特定情況下,您不需要子類化。

替換sleep(1/1000); msleep(100); 一切都會好起來的:)

暫無
暫無

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

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