Seite 1 von 1

QueuedConnection, Signalbuffer?

Verfasst: 7. Dezember 2010 16:30
von bobcat
Hallo,

ich generiere in meiner Anwendung Events, die nacheinander abgearbeitet werden müssen. Die Art des Events wird in einer signal/slot Verbindung an die abarbeitende Funktion übergeben:

Code: Alles auswählen

connect(this, SIGNAL(sigEvent(int)), this, SLOT(process(int)), Qt::QueuedConnection);
In der Methode process(int) können nun weitere Events ausgelöst werden. Für den Programmablauf ist es wichtig, dass ein Event komplett abgearbeitet wird, bevor das nächste an die Reihe kommt. Mit anderen Worten, process(event1) müsste returnieren, bevor process(event2) aufgerufen wird. Ich hatte versucht, das durch die QueuedConnection sicherzustellen, allerdings funktioniert das nicht. Gibt es in Qt einen Mechanismus, mit dem ich das einfach erreichen könnte?

Verfasst: 7. Dezember 2010 16:35
von Christian81
Wie wäre es mit Qt::DirectConnection? Ich mein Qt::QueuedConnection ist doch genau da sie zu queuen was Du ja augenscheinlich nicht möchtest, also warum benutzt Du es dann?
Abgesehen davon - warum überhaupt Signal/Slot wenn doch beide Funktionen in der gleichen Klasse sind?

Verfasst: 7. Dezember 2010 16:35
von Giesbert
Normalerweise funktioniert das schon. Aber wenn du irgendwo processEvents aufrufst (.o.ä.) dann bringst du das System durcheinander.
Was hälst du davon, die sachen mittel direct slot zu schicken und in eine queue zu schreiben, welche du stück für stück abarbeitest?

Verfasst: 7. Dezember 2010 17:07
von bobcat
Christian81 hat geschrieben:Wie wäre es mit Qt::DirectConnection? Ich mein Qt::QueuedConnection ist doch genau da sie zu queuen was Du ja augenscheinlich nicht möchtest, also warum benutzt Du es dann?
Queuen möchte ich sie schon, denn die Events sollen ja in der Reihenfolge abgearbeitet werden, in der sie erzeugt werden. Aber ich stimme zu, dass Qt hier nicht das macht, was ich gerne hätte ... wenn ich in die Doku schaue, dann heißt es, dass sich die Queue lediglich darauf bezieht, ob der Slot direkt aufgerufen wird oder ob erst der Code nach dem emit ausgeführt wird.

Würde ich DirectConnection benutzen, dann würde ich ja gemäß Doku wirklich gleich in den Slot springen, was der Sache noch weniger dienlich ist. Hatte ich aber auch ohne Erfolg ausprobiert.
Christian81 hat geschrieben: Abgesehen davon - warum überhaupt Signal/Slot wenn doch beide Funktionen in der gleichen Klasse sind?
Der Gedanke war, erst ein process(...) abzuarbeiten, bevor das nächste Signal an die Reihe kommt. Wenn ich nicht mit Signal/Slot arbeite, dann wird bei der Ausführung von process(...) dieses wieder aufgerufen, wodurch noch weniger gewährleistet ist, dass der erste Aufruf vor dem zweiten endet.
Giesbert hat geschrieben: Normalerweise funktioniert das schon. Aber wenn du irgendwo processEvents aufrufst (.o.ä.) dann bringst du das System durcheinander.
Guter Punkt, das muss ich nochmal überprüfen! Dazu habe ich noch eine Verständnisfrage, zu der ich bisher in der Doku noch nichts gefunden habe: Wenn ich ein Signal sende, wird dann ein QEvent generiert? Bearbeitet QApplication::processEvents() nur QEvents oder auch Signale (falls es da überhaupt einen Unterschied gibt)?
Giesbert hat geschrieben:Was hälst du davon, die sachen mittel direct slot zu schicken und in eine queue zu schreiben, welche du stück für stück abarbeitest?
Sowas werd ich dann wohl machen müssen ... lieber würde ich natürlich nen vorhandenen Mechanismus richtig nutzen ...

Verfasst: 7. Dezember 2010 17:11
von Giesbert
QueuedConnection sorgt dafür, das ein QEvent in die event queue geschrieben wird und der slot wird abgearbeitet, wenn die event loop wieder abgearbeotet wird. 3 x Queued event sollte auch in der reihenfolge kommen. Wenn du aber processEvents aufrufst, bringst du die reihenfolge durcheinander.

Verfasst: 7. Dezember 2010 17:35
von bobcat
Giesbert hat geschrieben:Normalerweise funktioniert das schon. Aber wenn du irgendwo processEvents aufrufst (.o.ä.) dann bringst du das System durcheinander.
Ich hab tatsächlich in nem Modul, das nicht von mir war, noch ein processEvents() gefunden. Werfe ich das raus, dann scheint es zu funktionieren, werde ich jetzt noch genauer testen.

Vielen Dank!