zu langsame Slot-Bearbeitung?

Alles rund um die Programmierung mit Qt
Ozzy
Beiträge: 141
Registriert: 24. Oktober 2007 10:18

zu langsame Slot-Bearbeitung?

Beitrag von Ozzy »

Hi,

ich habe ein Problem, bei dem Ihr mir hoffentlich helfen könnt:
und zwar habe ich einen QSlider, über den TableView-Zeilen hinzugefügt werden - es sollen also immer so viele Zeilen angezeigt werden, wie der Slider gerade anzeigt.
Hierfür habe einen Slot geschrieben, der die Zeilen der TableView zählt, mit dem Slider vergleicht, und ggf. Zeilen löscht, oder hinzufügt und initiallisert. Und da scheint auch das Problem zu sein: für die Intitiallisierung wird ein Objekt angelegt, die Objektdaten in die Tabelle geschrieben, und das Objekt für spätere Bearbeitungen in einen Vektor geschoben. So sieht es jetzt aus:

Code: Alles auswählen

if ( model->rowCount() >= slider->value() ) {
	for ( int i=model->rowCount(); i >= slider->value(); i-- ) {
		model->removeRow(i);
		Vector.pop_back();
	}
} else if ( model->rowCount() < slider->value() ) {
	for ( int i=model->rowCount(); i< slider->value(); i++ ) {
		model->insertRows( model->rowCount(), 1, QModelIndex() );
		TableStruct tablestruct;
		tablestruct = createNewStruct( tablestruct; );
		insertNewData( model->rowCount()-1, tablestruct; );
		Vector.push_back( tablestruct; );
	}
}
Wenn man nun den Slider langsam bewegt, funktioniert auch alles, bewegt man ihn zu schnell in eine, und dann in die andere Richtung, bricht das Programm ab, wohl weil es nicht schafft, die Daten rechtzeitig zu verarbeiten.
Habt Ihr vielleicht eine Idee, wie man dieses Problem umgehen kann???

MfG, und vielen Dank schon einmal im Voraus, Ozzy
Christian81
Beiträge: 7319
Registriert: 26. August 2004 14:11
Wohnort: Bremen
Kontaktdaten:

Beitrag von Christian81 »

Das Problem ist nicht dass der Slot zu langsam ist sondern wohl dass Du noch im bearbeiten des eines Signals bist und schon ein neues eintrifft.
MfG Christian

'Funktioniert nicht' ist keine Fehlerbeschreibung
Ozzy
Beiträge: 141
Registriert: 24. Oktober 2007 10:18

Beitrag von Ozzy »

Hm, letzden Endes läuft ja beides aufs gleiche hinaus. Ich kann dem Benutzer ja schlecht vorschreiben, wie langsam das passieren darf. Was kann man da denn machen?

MfG, Ozzy
Christian81
Beiträge: 7319
Registriert: 26. August 2004 14:11
Wohnort: Bremen
Kontaktdaten:

Beitrag von Christian81 »

Habe ich doch im Grunde schon gesagt - schauen ob man gerade im Slot ist und wenn ja warten (oder einfach ignorieren).
MfG Christian

'Funktioniert nicht' ist keine Fehlerbeschreibung
Ozzy
Beiträge: 141
Registriert: 24. Oktober 2007 10:18

Beitrag von Ozzy »

Hi,

so etwas geht? Kannst Du mir auch sagen, wie man so etwas überprüft?
Bzw. Was ist denn, wenn man den Regler bewegt, man dann in den Slot reinkommt, und man den Slider dann weiterbewegt, während man man im Slot ist? Dann wird diese Änderung doch auch nicht übernommen, oder???
Christian81
Beiträge: 7319
Registriert: 26. August 2004 14:11
Wohnort: Bremen
Kontaktdaten:

Beitrag von Christian81 »

Entweder QMutex(Locker) oder was ganz einfaches mit ne Klassenvariable m_binSlot
MfG Christian

'Funktioniert nicht' ist keine Fehlerbeschreibung
Ozzy
Beiträge: 141
Registriert: 24. Oktober 2007 10:18

Beitrag von Ozzy »

Oder ich nehme einen Timer... Wenn sich nach Zeit x nichts mehr ändert, dann übernimmt er den Wert... Ginge vielleicht auch. Naja, mal sehen, was besser ist...

MfG, Ozzy
solarix
Beiträge: 1133
Registriert: 7. Juni 2007 19:25

Beitrag von solarix »

Christian81 hat geschrieben:sondern wohl dass Du noch im bearbeiten des eines Signals bist und schon ein neues eintrifft.
IMHO kann das nicht sein, weil Signals ja nicht asynchron hereinplatzen, sondern erst als Events behandelt werden. Also muesste man im Slot schon ein
QCoreApplication::processEvents()
aufrufen, was ja kaum der Fall sein wird..
Ozzy hat geschrieben: Oder ich nehme einen Timer... Wenn sich nach Zeit x nichts mehr ändert, dann übernimmt er den Wert..
uebel.. warum muss den das Model ueberhaupt den Slider kennen? Kannst du nicht einfach das Signal "void sliderMoved ( int value )" des Sliders mit einen Slot deines Models connecten? Da hast du doch gratis alle Infos die du brauchst und musst auch nicht pollen..
Christian81
Beiträge: 7319
Registriert: 26. August 2004 14:11
Wohnort: Bremen
Kontaktdaten:

Beitrag von Christian81 »

solarix hat geschrieben:
Christian81 hat geschrieben:sondern wohl dass Du noch im bearbeiten des eines Signals bist und schon ein neues eintrifft.
IMHO kann das nicht sein, weil Signals ja nicht asynchron hereinplatzen, sondern erst als Events behandelt werden.
Falsch.
MfG Christian

'Funktioniert nicht' ist keine Fehlerbeschreibung
solarix
Beiträge: 1133
Registriert: 7. Juni 2007 19:25

Beitrag von solarix »

In einer Single-Thread Applikation wuesste ich nicht, wer (ausser dem Kern) meine Applikation unterbrechen soll.. Wenn sich das Programm also in einem Slot befindet, werden keine Events abgearbeitet (GUI "freezee") und keine (Qt-)Signals koennen hereinschneien (weil niemand da ist der Signals emittieren koennte..).
Christian81
Beiträge: 7319
Registriert: 26. August 2004 14:11
Wohnort: Bremen
Kontaktdaten:

Beitrag von Christian81 »

Wo steht hier was von Single-Thread?
Qt ist multithreaded. Und ein model->removeRow() (oder irgend eine andere gui-applikation) kann unter Umständen auch kurz in die Eventloop führen.
MfG Christian

'Funktioniert nicht' ist keine Fehlerbeschreibung
ObeliX
Beiträge: 59
Registriert: 14. November 2007 17:47

Beitrag von ObeliX »

ich kann Christian81 da nur beipflichten.

der signal/slot-mechanismus ist nicht mit den events gleich zu setzen.
die slots können sehrwohl kaskadiert gerufen werden. ich mußte schon oft blocker in slots einbauen, weil diverse controls zb. auch changed()-signale auslösen, wenn die änderung nicht vom user vorgenommen werden, sondern das programm selbst zb.mit setIrgendwas() modifikationen vornimm.


MfG Obel
solarix
Beiträge: 1133
Registriert: 7. Juni 2007 19:25

Beitrag von solarix »

Wo steht hier was von Single-Thread?
Anderst herum: wo steht was von Multithread? Eine Standardapplikation hat (auf meinen Rechnern jedenfalls) nur einen Thread. Die Event-Behandlung inkl. Signal/Slots finden also nur statt, wenn ich explizit wieder an den Mainloop zurueckgebe (oder eine Methode aufrufe, welche wiederum die Kontrolle temporaer an den Mainloop zurueckgibt).
Und ein model->removeRow() (oder irgend eine andere gui-applikation) kann unter Umständen auch kurz in die Eventloop führen.
Ich gehe davon aus, dass du "gui-funktion" meinst (oder andere Bereiche welche processEvents() aufrufen) .
Ich kenne jedoch keine, bei welchen diese (gefaehrliche) Eigenschaft jedoch nicht ausdruecklich in der Doku erwaehnt wird (z.B. QTest::qWait()). Auch gui-Operationen werden normalerweise erst wieder im EventLoop abgearbeitet.

[edit]
ObeliX hat geschrieben: der signal/slot-mechanismus ist nicht mit den events gleich zu setzen.
Einverstanden.. das war keine überlegte Aussage
ObeliX hat geschrieben: die slots können sehrwohl kaskadiert gerufen werden. ich mußte schon oft blocker in slots einbauen, weil diverse controls zb. auch changed()-signale auslösen, wenn die änderung nicht vom user vorgenommen werden, sondern das programm selbst zb.mit setIrgendwas() modifikationen vornimm.
auch bei solchen (schlechten) Designs wird die Funktion nicht unterbrochen (Kette an Funktionspointer). Wobei ich zugeben muss, dass es schlussendlich keine Rolle mehr spielt, ob die laufende Funktion unterbrochen wurde oder ob sie (bewusst oder unbewusst) rekursiv aufgerufen wird. Das Ergebnis ist das Selbe. Ich kann mir jedoch nicht vorstellen, was für eine Operation im Model von Ozzy die Kontrolle wieder an den Eventloop abgeben soll..
Zuletzt geändert von solarix am 11. Dezember 2007 20:19, insgesamt 1-mal geändert.
upsala
Beiträge: 3946
Registriert: 5. Februar 2006 20:52
Wohnort: Landshut
Kontaktdaten:

Beitrag von upsala »

Signal/Slots haben nichts mit dem Event-Handler zu tun.
When a signal is emitted, the slots connected to it are usually executed immediately, just like a normal function call. When this happens, the signals and slots mechanism is totally independent of any GUI event loop.
Ausnahme sind Threadübergreifende Signal/Slot-Verbindungen oder wenn es beim connect explizit angegeben wurde.

Eine kurze Analyse des Qt-Quelltextes ergibt, daß z.B. processEvents nur dann intern aufgerufen wird, wenn man es auch wirklich erwartet. (QDialog, QSplashScreen, QScriptEngine, Q(Core)Application, QTimer...) Somit wird auch die Event-Routine auch nur dann ausgeführt, wann man es erwartet.

just my 2ct...
RHBaum
Beiträge: 1436
Registriert: 17. Juni 2005 09:58

Beitrag von RHBaum »

muss auch solarix recht geben ....

multithreaded an der stelle bedeutet, das QT multithread faehig ist, und gegen die multithreaded runtimes gelinkt ist.

Aber standardmaessig laeuft alles in einem thread .....
der zwar vom kern unterbrochen werden kann, aber dann wieder an seiner alten stelle fortsetzt.
Also man das Programm schoen blockieren kann, wenn man den focus ned an die eventloop abgibt :-)

Threads muss man schon per hand erstellen (QThread z.b. ) ansonsten waers eh gefaehrlich, weil man ja ansonsten immer alle nichtlokalen variablen schuetzen muesste, weil man ja nie weiss wenn irgendwas aufgerufen wuerde :-)

Ciao ...
Antworten