Seite 1 von 1

Dialogfenster öffnet sich nicht vor Berechnung

Verfasst: 11. Mai 2009 23:26
von GammaBlitz
Hallo!
Ich habe eine Dialogklasse von QDialog abgeleitet dynamisch erzeugt und will, dass das
Dialogfenster erscheint. Es zeigt an, dass eine länger andauernde Berechnung folgt und
bittet den Benutzer darum, etwas zu warten.

dialog->show();
dialog->raise();
dialog->activateWindow();
// Zeitintensive Berechnung
//...
// Berechnungsende
dialog->close();

-funktioniert nicht. Durch einen Trick mit der Änderung der Dialogfenstergröße konnte ich
erkennen, dass das Dialogfenster zwischen dem Berechnungsende und dialog->close()
kurz und kaum sichtbar "aufblitzt". Ich habe mir gedacht, dass das Qt-System nicht genug Zeit hat, das Dialogfenster vor der Berechnung zu zeichnen und dass es deshalb
nicht erscheint. Also habe ich eine Thread-Klasse von QThread abgeleitet erzeugt, die
den Dialog in einem extra Thread mit dialog->exec () startet. Leider war auch das er-
folglos. Das Dialogfenster ist nicht erschienen. Ich frage mich, wie man z.B. einen
Dialog starten soll, der mit einer Progressbar den Fortschritt eines rechenintensiven
Abschnittes anzeigen soll. Ich will ja einfach nur "Bitte warten..." ausgeben.
Weiß jemand eine Lösung?

Verfasst: 11. Mai 2009 23:35
von solarix
Ich habe mir gedacht, dass das Qt-System nicht genug Zeit hat, das Dialogfenster vor der Berechnung zu zeichnen und dass es deshalb
nicht erscheint.
Gezeichnet wird erst im Eventloop... falls du nichts ändern möchtest, hilft dir also vor der Berechnung http://doc.trolltech.com/4.5/qcoreappli ... cessEvents
Also habe ich eine Thread-Klasse von QThread abgeleitet erzeugt, die
den Dialog in einem extra Thread mit dialog->exec () startet.
Anderst rum wäre richtig.. nur der Mainthread darf zeichnen, also ist die Berechnung in einen Thread auszulagern, nicht die GUI..

Ich will ja einfach nur "Bitte warten..." ausgeben.
Weiß jemand eine Lösung?
Ich verwende bei sowas hin und wieder QSplashScreen...

Verfasst: 12. Mai 2009 21:59
von GammaBlitz
Danke, Solarix.

QCoreApplication::processEvents() hat etwas geholfen. Der Inhalt des Dialogs wird
zwar trotzdem noch nicht gezeichnet, aber wenigstens erscheint er.
Eigentlich hatte ich mir von processEvents() mehr versprochen.
Ich habe mich entschlossen, die Berechnung doch nicht in einem extra Thread auszu-
lagern, weil es den Nebeneffekt hat, das die aktuelle Funktion verlassen werden muss
(sonst bringt das Ganze ja nichts) und weitere Benutzereingaben als unzulässig abge-
fangen werden müssen.

Verfasst: 12. Mai 2009 22:05
von solarix
evt "while (app->hasPendingEvents()) app->processEvents();"?

[EDIT]
"und weitere Benutzereingaben als unzulässig abge-
fangen werden müssen." oder die Applikation wird eben mit einem SplashScreen (oder sonst ein modaler Dialog) gesperrt...

Verfasst: 17. Mai 2009 21:52
von GammaBlitz
Danke solarix.

Ja,

while (application->hasPendingEvents())
application->processEvents();

zeichnet den Dialog schon häufiger, aber noch nicht immer.
Ich muss aber noch dazu sagen, dass noch mehrere Threads laufen und
ein Timer 3 mal pro Sekunde ein Widget aktualisiert.
Ich frage mich allerdings, wie es gemacht wird, dass das Application-Object von den
Events in Mainwindow Bescheid weiß, denn sie werden ja in main() als zwei
verschiedene und getrennte Objecte initialisert.

Verfasst: 18. Mai 2009 08:56
von solarix
zeichnet den Dialog schon häufiger, aber noch nicht immer.
schade.. naja, war ein Versuch wert.. QDialog ist IMHO auch einfach nicht für sowas gedacht.. Warum denn nicht einfach:

Code: Alles auswählen

{
 QPixmap pixmap(":/bitte_warten.png"); // falls gewuenscht....
 QSplashScreen splash(pixmap);
 splash.show();
 splash.showMessage("bitte Warten");  // falls gewuenscht....
 qApp->processEvents();

 // deine Berechnung
 .....
}
siehe: http://doc.trolltech.com/4.5/qsplashscreen.html#details
Ich frage mich allerdings, wie es gemacht wird, dass das Application-Object von den
Events in Mainwindow Bescheid weiß
Ganz einfach: _alle_ Events des Hauptthreads werden dort behandelt: http://doc.trolltech.com/4.5/qapplication.html#details

Verfasst: 18. Mai 2009 22:26
von GammaBlitz
Danke solarix.

Ich habe mir Deinen Rat zu Herzen genommen und gebe die Meldung nun mit einem
QSplashScreen aus. Das klappt allerdings nur mit einer Pixmap. Nur die Meldung ohne
Pixmap klappt nicht.
Also, ich habe es ein paar mal mit einer Pixmap probiert und es hat immer geklappt.
Damit ist das Problem gelöst.