ich wollte mich bischen in Qthreads einarbeiten und habe mir dafür ein simples Beispiel (starte thread per button und arbeite nebenlaeufig die schleife ab -Gui soll funktionsfaehig bleiben) ausgedacht. Nur irgendwie möchte das nicht so wie ich mir das vorstelle
leider hat mir google und die sufu nicht weiter geholfen
kurz als Übersicht für euch: Ich erstelle ein Widget, dieses Widget startet per Button einen Thread und in diesem Thread läuft eine relativ lange schleife. Die schleife macht nichts anderes wie ein directory durchzusuchen (hab nur was gebraucht was laenger dauert;). Anbei mein Code danach das Problem
widget.h
Code: Alles auswählen
#ifndef WIDGET_H
#define WIDGET_H
#include <threadTest.h>
#include <QWidget>
namespace Ui {
class Widget;
}
class Widget : public QWidget
{
Q_OBJECT
public:
explicit Widget(QWidget *parent = 0);
~Widget();
private slots:
void on_pushButton_clicked();
void on_commandLinkButton_clicked();
private:
Ui::Widget *ui;
threadTest *tt;
};
#endif // WIDGET_H
Code: Alles auswählen
#include "widget.h"
#include "ui_widget.h"
#include <QtGui>
#include <QtCore>
Widget::Widget(QWidget *parent) :
QWidget(parent),
ui(new Ui::Widget)
{
ui->setupUi(this);
ui->lineEdit->setText(QDir::currentPath());
tt = new threadTest(ui);
}
Widget::~Widget()
{
delete tt;
delete ui;
}
void Widget::on_pushButton_clicked()
{
QString directory = QFileDialog::getExistingDirectory(this,
tr("Search Directory"), QDir::currentPath());
ui->lineEdit->setText(directory);
}
void Widget::on_commandLinkButton_clicked()
{
tt->start();
}
Code: Alles auswählen
#ifndef THREADTEST_H
#define THREADTEST_H
#include <QThread>
#include <QWidget>
#include "ui_widget.h"
class threadTest : public QThread
{
Q_OBJECT
public:
threadTest(Ui::Widget *ui2){
ui = ui2;
}
~threadTest(){
delete ui;
}
void start();
protected:
void run();
private:
Ui::Widget *ui;
};
#endif // THREADTEST_H
Code: Alles auswählen
#include "threadTest.h"
#include <QtCore>
#include <QtGui>
void threadTest::run(){
QString dirStr = ui->lineEdit->text().trimmed();
if (!dirStr.isEmpty()){
QDirIterator it(dirStr, QDirIterator::Subdirectories | QDirIterator::FollowSymlinks);
while (it.hasNext()) {
it.next();
//FollowSymlinks falsch verstanden ? daher selber "." und ".." abfangen...
if (it.fileName() == QLatin1String(".") || it.fileName() == QLatin1String("..")){
} else{
if(!it.fileInfo().isDir()) {
qDebug() << it.filePath();
ui->lbStatus->setText(it.filePath());
qApp->processEvents();
}
}
}
} else {
qDebug() << "dir is empty";
}
//exec();
}
void threadTest::start(){
run();
}
Code: Alles auswählen
#include <QtGui/QApplication>
#include "widget.h"
int main(int argc, char *argv[])
{
QApplication a(argc, argv);
Widget w;
w.show();
return a.exec();
}
Wenn ich nun den das programm starte und den thread laufen lasse, kann ich das Fenster bewegen, dann pausiert die Ausgabe(label wird nicht mehr geupdated) was wohl daran liegt, dass die eventloop nun das fenster-wird-verschoben event hat und somit das andere event hinten anfuegt bzw ein update-paused?(meine vermutung). Ich erreiche ein Update des labels auch nur dann wenn ich qApp->processEvents() aufrufe, mit exec() funktioniert es leider nicht.
Wenn ich das Programm nun schliesse, laeuft der thread weiter, d.h qDebug gibt fröhlich weiter Infos aus. Wäre es möglich sobald der Thread gestartet wird, dass im mainprogramm ein Cancel button erscheint, dieser soll wenn man drauf klickt den thread zerstören bzw automatisch ausgeführt werden, wenn das Widget geschlossen wird.
Ich vermute ich hab einen ganz schlechten Stil/weg gewählt und daher freue ich mich über eure Ratschläge/Verbesserungen.
Merci im Voraus.
Grüsse