Seite 1 von 1

Threads, Signale und Slots

Verfasst: 24. September 2010 09:53
von Metzlmane
Hallo,


ich versuche mich zur Zeit mit Threads und bin auf folgendes Problem gestoßen:
Man kann keine Signale oder Slots in eine Threadklasse einbauen?

folgendes habe ich gefunden:
http://labs.qt.nokia.com/2010/06/17/you ... -it-wrong/
und
http://labs.qt.nokia.com/2006/12/04/thr ... -headache/

Nach ein bisschen Googln fand ich heraus dass man mit
->workerThread
diesen Eventloop an den Thread übergeben kann, was aber laut dem Blogeintrag nicht sinnvoll ist.


Ich möchte nur einen Thread erstellen der von 1-20 zählt und diese aktuelle Zahl dann im Hauptfenster aktualisiert wird und ich bekomme es einfach nicht hin!
Ein Beispiel aus dem Buch von Jürgen Wolf habe ich Probiert, bei dem man einfach die Adresse eines Textfeldes übergibt und somit dann auf dieses zugreifen kann. Wenn ich dieses aber nur abtippe, wird es zwar richtig ausgeführt, stürzt aber am Ende ab da eine Fehlermeldung kommt, dass kein QTextEdit übergeben werden kann :?:

Ich würde mich freuen wenn mir das jemand nochmal auf deutsch erklären könnte :D

Re: Threads, Signale und Slots

Verfasst: 24. September 2010 10:14
von franzf
Metzlmane hat geschrieben:Ich möchte nur einen Thread erstellen der von 1-20 zählt und diese aktuelle Zahl dann im Hauptfenster aktualisiert wird und ich bekomme es einfach nicht hin!
Dafür brauchst du keinen eigenen Thread. SIGNAL/SLOT alleine tut es vollkommen. Am besten verwendest du gleich ordentlich einen QTimer. Denn was bringt dir ein Hochzählen, wenn das abhängig von Rechnerstärke oder Systemauslastung abhängig ist, und damit nie reproduzierbare Ergbenisse liefern kann?

Wenn du nur mal in Threads reinschnuppern willst, dann poste doch mal Code, wie du es bisher gelöst hast, was dir daran nicht gefällt, dann kann man diskutieren ohne gleich eine komplette Lösung zu posten, für die du dich nicht hast anstrengen müssen :P

Verfasst: 24. September 2010 10:55
von Metzlmane
Hehe, schon verstanden :wink:

Ich weiß, dass das unsinnig erscheint, aber ich wollte es eigentilch nur zum testen benutzen, da ich später den Thread dazu verwenden will um z.B. eine Datei zu kopieren und zurückgeben will, wieviel schon kopiert wurde...

Hier mal das was ich zum laufen gebracht habe:
(es heißt nur ftp, hat aber damit nix zu tun, ich weiß dass ftp asynchron ist)


mainwindow.h

Code: Alles auswählen

class MainWindow : public QMainWindow
{
    Q_OBJECT
private:
    QTextEdit *editor;
    FTPThread thread1;
private slots:
    void startThread();
    void Threadredy();
public:
    MainWindow(QMainWindow *parent = 0, Qt::WindowFlags = 0);
};
mainwindow.cpp

Code: Alles auswählen

MainWindow::MainWindow(QMainWindow *parent, Qt::WindowFlags flags) : QMainWindow(parent,flags)
{
    qDebug("Konstruktor");
    editor = new QTextEdit(this);
    resize(600,500);
    editor->setGeometry(100,100,300,200);
    setWindowTitle("FFFUU");
    startThread();
}
void MainWindow::startThread()
{
    if (thread1.isRunning()) return;
    thread1.SetValues(0,20);
    editor->insertPlainText("Thread start");

    qDebug("Thread Started");
    connect(&thread1,SIGNAL(finished()),this,SLOT(Threadredy()));

    thread1.start();
}
void MainWindow::Threadredy()
{
    qDebug("Thread finished");
}
ftp.h

Code: Alles auswählen

class FTPThread : public QThread
{
private:
    int qmin, qmax;
    int zahl;
public:
    FTPThread();
    void SetValues(int min, int max);
protected:
    void run();

};
ftp.cpp

Code: Alles auswählen

FTPThread::FTPThread()
{
    qmin = 0;
    qmax = 0;

}
void FTPThread::SetValues(int min, int max)
{
    qmin = min;
    qmax = max;
}
void FTPThread::run()
{
    for(int i = 0; i < qmax; i++)
    {
        qDebug("count");

    }
}
Das funktioniert soweit und die Debugmeldung lasse ich in der Konsole ausgeben.
Jetzt dachte ich mir erstelle ich einfach im Thread eine Methode oder Singal und rufe es in der for-schleife auf um es mit einem Slot den ich im MainWindow erstelle zu verbinden.
Dann stelle ich fest, wenn ich connect() benutze wird das singal nicht gelistet. Nun stehe ich auf dem Schlauch.
Soweit ich herausgefunden habe, hat es damit zu tun, dass dieser EventLoop im Mainwindow läuft und ich deshalb nicht mit einem Thread welcher seperat läuft verbinden kann? (habe da so meine Zweifel :lol: )

Gehe ich das ganze falsch an?

Verfasst: 27. September 2010 12:25
von RHBaum
Generell:

nur fuer das ausloesen von Slots mittels eines connects braucht man die eventloop, wenn das signal in nem anderen thread laeuft.

das senden von signalen aus threads heraus ist eigentlich problemlos möglich. Das connect erkennt das und macht daraus eine queued connection, ergo es macht ein mapping auf den thread des zielobjects über die eventloop, aka das zielobject muss in einem thread erstellt werden, der eine Eventloop hat. Der Mainthread hat meistens (bei standard QT apps) eine Eventloop die eh in der main mittels QCoreApplication::exec aufgerufen wurde.
Dann stelle ich fest, wenn ich connect() benutze wird das singal nicht gelistet.
Erklaer das mal genauer. wo wird nen Signal nicht gelistet ? wer listet ueberhaupt signale ?
der QTCreator ???

Ciao ...