Hallo Forum, ich bin ein blutiger Anfänger in C++ und habe fast keine Erfahrung in QT. Im Moment arbeite ich an einem Projekt, welches Daten über die Serielle Schnittstelle sendet und wieder einliest - das geht bereits. Weiteres sollen die Daten auch auf der Gui ausgegeben werden - was über manuelle betätigung über Buttons auch Funktioniert. Mein Ziel ist es, das senden und empfangen in einer Schleife ausführen zu lassen. Hierfür habe ich im Programm wo SetupUi aufgerufen wird einen Thread erzeugt, welcher auch ausgeführt (zZ. while(1) Schleife in der run()-Methode) wird. In diesem soll dann das Senden/Empfangen stattfinden. Miniterminal::Miniterminal(QMainWindow *parent) : QMainWindow(parent){ setupUi(this); connect(buttonConnect, SIGNAL(clicked()), this, SLOT(Verbinden())); connect(buttonSend, SIGNAL(clicked()), this, SLOT(Senden())); a.start(); // Thread } Mein eigentliches Problem ist, wie ich die empfangenen Daten vom Thread a in das UI bekomme. Bis jetzt habe ich folgendes Probiert: Ich habe im Thread die "ui_Miniterminal.h" eingebunden (vom qmake erzeugte GUI Header) und lineSenden->setText("Test"); (lineSenden ist der Objektname von meinem LineEdit) aufgerufen, was er mir mit der Fehlermeldung 'lineSenden undecleared' aber leider verweigert. Wie kann ich dieses Problem am einfachsten lösen? Was wäre der sauberste Weg? Danke im vorraus, Mike EDIT: Entwicklung unter Windows XP, QT 4.5.1/MinGW
Wozu brauchst du denn da Threads? > Hierfür habe ich im Programm wo SetupUi aufgerufen wird einen > Thread erzeugt, welcher auch ausgeführt (zZ. while(1) Schleife in der > run()-Methode) wird. In diesem soll dann das Senden/Empfangen > stattfinden. So würde dein Programm ständig die CPU zu 100% auslasten.
Hallo Rolf, Den Thread brauche ich da mir eine Schleife im GUI die GUI blockieren würde. Zumindest habe ich ausser einem Thread noch keine Lösung gefunden. Das der Thread mit while(1) 100% (in meinem Fall 25% dank Quadcore ;-) ) frisst, ist mir durchaus bewusst und kommt später auch wieder raus. Geplant ist Daten senden und abholen und dann den Thread für 500ms oder so schlafen zu legen. Die while(1) ist im Moment nur drinn um den Thread am Leben zu erhalten. Mein Promlem ist wie ich die Datem aus dem Thread in die GUI bekomme. Mike
Für die serielle Schnittstelle empfehle ich QExtSerialPort. Das ist eine Erweiterungsbibliothek zu Qt, die die serielle Schnittstelle als QIODevice zur Verfügung stellt. Und statt deiner Schleife könntest du auch einfach einen QTimer verwenden. Da muß dann nirgends mehr blockiert werden.
Hallo Rolf, das mit dem Timer klingt sehr interessant und würde in diesem Fall den selben Zweck erfüllen. Ähnlich wie bei einem uC-Timer halt - insofern ich das jetzt richtig interpretiert habe. Werde mich morgen da mal reinlesen. QIODevice klingt auch sehr gut. Ich habe zwar aus Codeteilen aus dem Netz schon eine funktionierende Schnittstelle gebastelt, aber möchte dennoch viel QT verwenden, da ich das in ein paar Monaten in der Firma brauchen werde. Vielen Dank für die Hinweise und eine schöne Woche, Mike
Hi Michael, Signal und Slots ist der standard QT Mechanismus für Interprozesskommunikation (u.a. Threads). Prinzipiell hast Du immer ein Signal im einem Thread (emitter) und einen (oder mehrere) Slots in anderen Threads (receiver) die das Signal empfangen. Zu Deiner Frage wie man Daten vom einen in den anderen Thread kriegt: Eben mit Signal/Slots. Signal koennen mehrere Paramter haben (u.a. Deine Daten). Du kannst also ein eigenes Signal und einen dazugehörigen Slot definieren und Deine Nutzdaten beim emit() übergeben. Du kannst aber auch global ein Datenhaltungsobjekt erzeugen, dieses über einen Mutex schützen und von beiden Threads darauf zugreifen (das waere dann so ähnlich wie shared memory). Wie gesagt, da gibts viele viele Möglichkeiten. Fang mal hier an zu lesen: http://doc.trolltech.com/4.5/signalsandslots.html danach: - google: qt thread - google: qt signal slots direct connection - google: qt signal slots queued connection Gruss Frank
> oder shared memory Hm? Threads haben schon einen gemeinsamen Speicher. Das ist ihr Vorteil gegenüber getrennten Prozessen. > Eben mit Signal/Slots. Signal koennen mehrere Paramter haben (u.a. > Deine Daten). Du kannst also ein eigenes Signal und einen > dazugehörigen Slot definieren und Deine Nutzdaten beim emit() > übergeben. Wohlgemerkt unterscheidet sich der Signal/Slot-Mechanismus zwischen zwei Threads von dem innerhalb eines Threads. Letzterer ist im Prinzip nur ein Memberfunktions-Aufruf über einen Zeiger. Bei ersterem werden die Daten kopiert und durch die Event-Queue geschleift. Dazu muß man seine Klasse erst bei Qt anmelden. Man muß sich halt im Klaren darüber sein, daß man nicht ein gemeinsames Objekt hat, auf das beide zugreifen, sondern daß bei jedem Signal, das zwischen den Threads gesendet wird, die gesamten Daten erst kopiert werden.
Hallo, ich habe mich gestern Abend auseinander gesetzt und mich dann für die Signal/Slot Methode entschieden. Nach ein paar Anlaufschwierigkeiten (QT Newbie halt) hat es dann geklappt. Speziell Rolf und Frank möchte ich nochmals Danke sagen. Lg, Mike
Noch als Anmerkung: - in einer Schleife Lesen und Schreiben schadet nichts und lastet auch einen Prozessor nicht zu 100% aus, falls das Lesen blockiert, solange keine Daten zum Lesen da sind. Es ist durchaus üblich, in einem Thread ohne irgendwelche Wartezeiten in einer Endlosschleife zu lesen. Die nötige Verzögerung kommt automatisch, wenn die Eingabe stockt.
> Hm? Threads haben schon einen gemeinsamen Speicher. Das ist ihr Vorteil > gegenüber getrennten Prozessen. ja, eben. mit ein bischen hirnschmalz kann man die kommunikation darüber abwickeln.
Auch wenn man die Kommunikation über einen gemeinsamen Speicher durchführen kann, muss man die Daten in den Feldern manuell (oder eben Thread ) aktualisieren oder direkt in deren Speicher schreiben, oder?
ja. aber qt ist ja angäblich threadsave. ergo kannst du die daten schreiben und dann per QApplication::postEvent() der gui mitteilen dass sich was getan hat.
> ja. aber qt ist ja angäblich threadsave.
Die meisten Klassen in Qt sind threadsave. Das heißt, daß du diese
Klassen über mehrere Threads hinweg benutzen kannst. Es heißt nicht, daß
du dich, nur weil du an Qt linkst, auf einmal gar nicht mehr um
Synchronisation zwischen Threads kümmern mußt. Deine eigenen Typen mußt
du schon selbst threadsave machen.
nur um Missverständnissen vorzubeugen: Threadsafe heisst nur, dass sich zwei Objekte einer Klasse nicht gegenseitig beeinflussen. Wenn man auf ein Objekte einer threadsafe-Klasse von zwei Threads gleichzeitig (r/w) Zugreifen möchte, kommt man i.d.R. nicht um einen Mutex oder RWLock herum
Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.