Seite 1 von 1

[gelöst]Thread oder Process ?

Verfasst: 27. August 2007 14:20
von dl4dz
Hallo Zusammen,

Habe ein kleines Problem....

Ich schreibe an einem Morse-Übungsprogramm. Während die Morsezeichen über die
Soundkarte ausgegeben werden sollen, möchte ich die gehörten Zeichen wieder über
ein "lineEdit" GLEICHZEITIG eingeben.

Die Ausgabe der Morsezeichen über die Soundkarte funktioniert, aber ich bekomme
erst "einen Focus" für meinen "lineEdit" nachdem die Soundausgabe beendet ist.

Code: Alles auswählen

....

 lineEditInput->setFocus();
 morse(text,speed,freq);   // hier wird der "Morsezeichen-Generator" aufgerufen   

.....


Was kann ich wie tun?

Vielen Dank im Vorraus

Olaf

Verfasst: 27. August 2007 16:49
von Volker
Die Soundausgabe in einen eigenen Thread auslagern?

Verfasst: 27. August 2007 19:27
von dl4dz
Hallo Volker,

Ja, ... oder als Process? Ich weiss es nicht. Vielleicht gibt es ja auch eine andere Lösung???

Situation ist im Moment, dass ich im "lineEdit" erst was eingeben kann, wenn die Soundausgabe beendet ist.
Das muss doch irgendwie gleichzeitig gehen, oder?

Gruss

Olaf

Verfasst: 27. August 2007 20:49
von Volker
Kommt darauf an. Ich nehme an, dass deine morse(text,speed,freq); Funktion so lange blockiert, bis der gesamte Text über die Soundkarte abgespielt wurde. So lange blockiert damit logischerweise auch die Eventloop deines Qt Programms. Also entweder baust du in die morse Funktion einen Aufruf von qApp->processEvents() ein z.B. nach jedem über die Soundkarte ausgegebenem Buchstaben, oder du verwendest QThread.
Die erste Lösung könnte aber seltsame Seiteneffekte haben weshalb ich davon mal abrate.
QProcess würde ich nicht verwenden, da vermutlich das ganze so ne Art Lernprogramm für's morsen werden soll, und dann wirst du evtl. auf den aktuellen Zustand der Soundausgabe zurückgreifen wollen. In dem Fall tust Du dir mit nem Thread viel leichter.
Wenn ich da falsch liege, dann kannst Du natürlich auch einfach ein Programm schreiben, das deine morse Funktion mit entsprechenden Kommandozeilenparametern aufruft und das ganze dann über QProcess starten.

Verfasst: 27. August 2007 21:17
von dl4dz
Hallo Volker,

Ja, es soll ein Lernprogramm werden. Eigentlich ganz einfach. Über die Soundkarte sollen Morsezeichen ausgegeben werden und über die Tastatur sollen die gehörten Zeichen wieder eingegeben werden. Am Ende des "Durchgangs" soll verglichen werden ob alles richtig eingegeben wurde. usw...usw...
Also kann die Ausgabe völlig unabhängig von der Eingabe sein.

Ich habe mal etwas mit QThread experimentiert, aber irgendwas stimmt da noch nicht.
Auch in diesem Fall wird zuerst der Thread gestartet und ich habe erst wieder Zugriff auf das "lineEdit" wenn er beendet ist.

Muss ich dem Compiler noch was mitteilen?

Gruß

Olaf

Verfasst: 27. August 2007 21:30
von Volker
Nein, vom Compiler sollte da nichts nötig sein. Früher gab es noch die Präprozessor Anweisung QT_THREAD_SUPPORT die soweit ich weiß für Multithreading Applikationen benötigt wurde, aber als ich gerade den QT4 Source Code danach durchsucht habe, konnte ich das Flag nirgends finden, obwohl es in den Makefiles nach wie vor gesetzt wird.

Ich tippe eher darauf, dass es an der Art wie du das ganze implementiert hast liegt. Aber ohne deinen Code zu kennen kann ich dir da nicht viel weiterhelfen.

Verfasst: 27. August 2007 21:58
von dl4dz
hm... ich benutze noch QT3...

hier etwas code:

Code: Alles auswählen


class morse_out : public QThread {
public:
  morse_out( std::string a = "morse_out" );
  virtual void run();
private:
  std::string name;
};


Hier der eigentliche Start, wenn ein Knopf gedrückt wurde...

Code: Alles auswählen


void cw_trainerWidget::pushButtonStart_clicked() {

 lineEditInput->setFocus();
 
 morse_out a("A");
 a.start();
 a.wait();

}

Zu Testzwecken habe ich hier NICHT die Soundausgabe genommen, sondern einfach etwas CPU Zeit verschwendet.

Code: Alles auswählen


void morse_out::run()
{

 for (int b = -128; b < 128; b++) {
    double x;
    for ( double d = 0.; d<1; d += 0.000005){           
      x = sqrt(d);
    }
  }
}

Und auch hier wird erst "morse_out" gestartet. Wenn es beendet ist, dann habe ich einen Cursor im "lineEdit".
Wenn ich BEVOR der Cursor kommt Tasten auf der Tastatur drücke, werden diese NACHDEM der Cursor da ist angezeigt...

Ich versteh's nicht...

Gruß

Olaf

Verfasst: 27. August 2007 22:01
von Volker
Der Aufruf von wait() terminiert den kompletten Sinn des Threads. Siehe Doku zu QThread::wait()

Da Du noch Qt3 verwendest, dürfte es außerdem auch sinnvoll sein die QT_THREAD_SUPPORT Präprozessor Anweisung zu setzen. Hab aber nie mit Qt3 programmiert, weiß es daher nicht genau.

Verfasst: 27. August 2007 22:16
von dl4dz
Ja, OK...aber wohin dann mit dem "wait"?

Wenn ich "wait" ganz weglasse "kracht's".

Verfasst: 27. August 2007 22:22
von Volker
evtl. solltest du nicht in dem clicked Slot einen Thread auf m Stack erstellen, da der beim Verlassen der Methode zerstört wird.

Sollte zwar meiner Meinung nach kein Absturz verursachen, wenn du im Thread nur Wurzeln berechnen lässt, aber wie das in QT3 gehandhabt ist, weiß ich nicht.

Ich würde Dir empfehlen erstmal ein paar Beispiele von Qt mit Threads durch zuarbeiten.

Verfasst: 28. August 2007 13:13
von dl4dz
Hallo Volker,

Ich habe noch etwas experimentiert und bin zu folgendem "Workaround" gekommen.

Habe mir ein "lineEditInput_returnPressed()" gebastelt und starte von dort aus als EINZIGES meinen Thread.

Code: Alles auswählen


void cw_trainerWidget::lineEditInput_returnPressed()
     {
       a.start();					// start thread
     }

So geht's ohne "Crash" !!! Meine Morsezeiche-Soundausgabe läuft und ich kann gleichzeitig über mein "lineEdit" eingeben.

Jetzt kann's mit dem Programm weitergehen.

Viele Dank für Deine Hilfel!!!

Olaf