Einfache multithreading mit Qt: Tue ich das richtige?
Ich bin neu auf StackOverflow und Frage mich, ob ich das Tue Recht:
Schreibe ich eine einfache Qt-Anwendung zum testen von multi-threading (etwas, was ich bin auch ganz neu). Ich machte eine MainWindow enthält widgets, und eine Klasse MyThread, dass Unterklassen QThread und überschreibt die run () - Methode.
Die Anwendung zeigt einfach zwei Schaltflächen, "Start-Zähler" und "Stop-Counter", und ein text Feld. Wenn "start-Zähler" gedrückt wird, wird ein worker-thread erstellt wird und im hintergrund ausgeführt wird und kontinuierlich Inkrementieren eines Zählers in einer while-Schleife und somit den Haupt-thread (wo die GUI ist) mit dem aktualisierten Wert. Wenn "Stop-Zähler" gedrückt wird, wird ein signal an den Haupt-thread, der beendet die while-Schleife, und der Zähler wird angehalten, bis "Start-Zähler" erneut gedrückt wird.
Dieser funktioniert einwandfrei in Ordnung ... aber es ist der beste Weg? Ich bin neu in diesem, und Lesen eine Menge Leute sagen, "nicht-Unterklasse QThread" und andere Menschen, die sagen "Unterklasse " QThread", und es ist ein bisschen verwirrend. Wenn dies nicht der beste Weg, um zu implementieren, die diese Art der Sache (ausführen einer rechenintensiven Schleife in einem hintergrund-thread mit "start" und "stop" - Tasten), was ist? Wenn ich mache es falsch, wie mache ich es richtig? Ich will nicht zu lernen der falsche Weg.
Danke! Und hier der code:
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);
}
- Seien Sie vorsichtig
sleep(1/1000)
bedeutetsleep(0)
. - M. Guter Fang
- Erweitern @ixSci die Antwort, Lesen Sie den folgenden link. Es gibt einige subtile Hinweise: mayaposch.wordpress.com/2011/11/01/...
- Guter Fang, vielen Dank! Es geändert sleep(0.001).
- und Sie haben immer noch 0.
sleep
akzeptiert integral, ich habe nicht gesehen, allesleep
nimmt der gebrochenen Zahl. Verwendenmsleep(1)
zu erreichen, was Sie wollen.
Du musst angemeldet sein, um einen Kommentar abzugeben.
Meiste Zeit QThread sub-classing ist eine falsche Art und Weise zu tun threading in Qt. Ich schlage vor, Sie Lesen ein Artikel über threads, event-loops und andere könnte Ihnen eine Idee geben, wie die Verwendung von threads in Qt in einer besseren Art und Weise. Aber nicht auf niemanden hören, die argumentieren, dass es der einzige richtige Weg, um QThread. Es gibt 2 Möglichkeiten, und zwar das erstellen von Unterklassen ist nicht erforderlich, im Allgemeinen, könnte es sinnvoll sein, manchmal. Sie brauchen nur zu verwenden nicht-Unterklassen Weg, bis Sie wirklich brauchen, um eine Unterklasse. In Ihrem Fall brauchen Sie nicht Erben.
Ersetzen
sleep(1/1000);
mitmsleep(100);
Dinge werden nur in Ordnung 🙂