Seite 1 von 2
QWidget / Events
Verfasst: 29. Dezember 2008 19:49
von Gapa
Hallo (mal wieder

),
in meinem Progrämmchen dachte ich es wäre nicht schlecht, wenn beim Versuch ein Fenster zu schließen erst mal ne Sicherheitsmeldung kommen würde, bei der der Benutzer gefragt wird, ob er auch wirklich beenden will.
In der Doku habe ich dann etwas über Events gelesen: Stichwort
QCloseEvent...
Jedoch verstehe ich die Sache mit den Events noch nicht so ganz.
1.
Was genau ist der Unterschied zwischen einem Event und einem Signal??
2.
Wie genau verwende ich Events?
Ich habe in der Doku erfahren, dass es genügt, wenn ich in meine von QWidget abgeleitete Klasse folgende Funktion einbaue:
void closeEvent(QCloseEvent *event);
Ich habe nun gemerkt, dass diese Funktion dann beim Versuch das Fenster zu schließen auch aufgerufen wird, nur meine Frage:
WIE???
Was sagt hier meinem Fenster, dass es beim Schließen diese Funktion aufrufen soll??
Und wenn ich dann in diese Funktion eine
MessageBox einbaue, welche mit
"Ja" bzw.
"Nein" bestätigt werden muss, dann soll bei
"Nein" wieder zum Fenster zurückgekehrt werden. Doch das funktioniert mit einem einfachen return; nicht mehr...das Fenster ist quasi schon geschlossen worden...was bringt dann eine Abfrage überhaupt noch??
Ich glaube ich habe das Prinzip der
Events noch nicht so ganz verstanden...
Ich hoffe ihr könnt mir da mal weiterhelfen..
Viele Grüße
Gapa
Verfasst: 29. Dezember 2008 19:56
von franzf
event->ignore();
wenn auf nein geklickt wurde, sollte iegentlich dafür sorgen, dass das event ignoriert wird

(Doku ist immer ein doller Anlaufpunkt

)
Verfasst: 29. Dezember 2008 23:52
von RD1978
Ich habe nun gemerkt, dass diese Funktion dann beim Versuch das Fenster zu schließen auch aufgerufen wird, nur meine Frage: WIE???
Was sagt hier meinem Fenster, dass es beim Schließen diese Funktion aufrufen soll??
Bei einer virtuellen Methode, wird (über eine
VTable) zuerst in der abgeleiteten Klasse gesucht. Ist diese Methode dort implementiert, wird sie dort ausgeführt.
Verfasst: 30. Dezember 2008 07:34
von AuE
und hier ein wenig code.....
Code: Alles auswählen
void Foo::closeEvent(QCloseEvent *event)
{
if ( QMessageBox::information(this, tr("Wirklich beenden?"), tr("Möchten Sie wirklich beenden?") , QMessageBox::Yes | QMessageBox::No) == QMessageBox::No )
{
event->ignore();
return;
}
// und hier kommen deine Aufräumarbeiten ;-)
...
Verfasst: 30. Dezember 2008 13:17
von Gapa
Hallo,
vielen Dank für die Antworten! Ich hatte nicht gesehen, dass die Methode virtuell ist...
@AuE:
Jo danke, genau so mache ich es auch!
Ich verwende nun auf dem selben Weg auch das
keyPressedEvent, jedoch bereitet mir dieses Event noch ein paar Schwierigkeiten.
Bei einem Chat ist es ja oft erwünscht, dass man Eingaben per Enter/Return-Taste versenden kann, also habe ich versucht, diesen Tastendruck abzufangen.
Soweit bin ich schon:
Code: Alles auswählen
void Chat_Window::keyPressedEvent(QKeyEvent *event)
{
if(event->key() == Qt::Key_Return || event->key() == Qt::Key_Enter)
this->Send();
}
So hat aber leider erst mal gar nichts funktioniert.
Dann habe ich in der Doku nachgelesen und herausgefunden, dass ich mit der Funktion
setFocusPolicy() zumindest erreichen kann, dass ich per Mausklick auf das Fenster den Focus dem Fenster gebe und somit dann per Enter/Return-Taste die Eingabe absenden kann.
Nun frage ich mich jedoch wie ich es anstelle, dass mein Fenster auf das keyPressedEvent reagiert, obwohl den Focus nicht das Fenster, sondern das TextEdit hat.
Hat mir da jemand nen Lösungsvorschlag??
Viele Grüße
Gapa
Verfasst: 30. Dezember 2008 13:24
von AuE
Du hast die keypressed - Methode deines Mainwidgets überschrieben und nicht die des LineEdits...
...
Verfasst: 30. Dezember 2008 13:45
von Gapa
Hallo,
und wie überschreibe ich dann die keyPressed-Methode des TextEdits???
Muss ich dann etwa extra eine Klasse für mein TextEdit erstellen, in der ich dann nochmal eine keyPressedEvent()-Methode deklariere??
Das wäre ja sehr umständlich, oder?
Verfasst: 30. Dezember 2008 14:06
von franzf
Such im assistant mal nach eventFilter.
Du musst dir da nur ne Methode im MainWindow überladen (alternativ ne Filterklasse von QObject ableiten), und den Zeiger des Filterobjekt mittels installEventFilter() an das LineEdit zuweisen.
Ist für solche Sachen das einfachste.
Grüße
Franz
Verfasst: 30. Dezember 2008 14:17
von AuE
oder ne Klasse machen die sich vom Lineedit ableitet und dort die gewünschte Methode überschreiben. Glaube aber das das von franz eher angebracht ist
...
Verfasst: 30. Dezember 2008 15:24
von Gapa
@AuE:
Ja das hätte ich jetzt auch gemacht...ist einfacher^^
@franzf:
Könntest du mir ein kleines Beispiel demonstrieren (vorrausgesetzt diese Anforderung kommt bei dir nicht als zu anspruchsvoll an)?
Wäre echt prima!
Viele Grüße
Gapa
Verfasst: 30. Dezember 2008 22:24
von upsala
QTextEdit oder QLineEdit?
Könnte es sein, daß nur ein Return/Enter-Key interessant ist?
Event-Filter. Auch dafür gibts in der Doku
Beispielcode
...
Verfasst: 31. Dezember 2008 14:00
von Gapa
Hallo,
QKeyEvent *keyEvent = static_cast<QKeyEvent *>(event);
QTextEdit oder QLineEdit?
Es ist schon ein QTextEdit...so einfach ist es dann doch nicht^^.
zum EventFilter:
QKeyEvent *keyEvent = static_cast<QKeyEvent *>(event);
Diese Zeile bereitet mir ein paar Schwierigkeiten.
Ich weiß, dass sie das QEvent in ein QKeyEvent umkonvertiert, nur sind mir die einzelnen Befehle nicht ganz klar. Wofür steht zum Beispiel
static_cast? Ich weiß, dass man mit static_cast basisklassenzeiger in davon abgeleitete Klassenzeiger umkonvertieren kann, jedoch ist QEvent wohl kaum eine Basisklasse, oder? Oder was hat
<QKeyEvent *>(event) zu sagen??
Könnte mir jemand noch diese Zeile etwas genauer erläutern, sodass ich auch verstehe was ich programmiere
Viele Grüße
Gapa
Verfasst: 31. Dezember 2008 14:25
von RD1978
QEvent ist die Basisklasse alles Eventklassen und somit auch von QKeyEvent.
Hierarchie: QEvent > QInputEvent > QKeyEvent
Da der eventFilter flexibel sein soll, können auch andere Events ankommen. Du musst also ein Downcast auf das Event machen, welches Du abfangen möchtest.
Der Operator static_cast gibt, im Gegensatz zum normalen casting, einen NULL Pointer zurück, wenn die Konvertierung fehlschlägt. In Deinem Fall also, wenn ein anderes Event als ein QKeyEvent ankommt.
Das kannst/solltest Du dann auch noch überprüfen:
Code: Alles auswählen
QKeyEvent *keyEvent = static_cast<QKeyEvent *>(event);
if( keyEvent )
{
// Pointer ist vom Typ QKeyEvent...
// Code hier...
}
Verfasst: 31. Dezember 2008 14:37
von franzf
RD1978 hat geschrieben:Der Operator static_cast gibt, im Gegensatz zum normalen casting, einen NULL Pointer zurück, wenn die Konvertierung fehlschlägt. In Deinem Fall also, wenn ein anderes Event als ein QKeyEvent ankommt.
Das kannst/solltest Du dann auch noch überprüfen:
Code: Alles auswählen
QKeyEvent *keyEvent = static_cast<QKeyEvent *>(event);
if( keyEvent )
{
// Pointer ist vom Typ QKeyEvent...
// Code hier...
}
Im Beispiel zum eventFilter (und den examples) wird nicht auf NULL geprügt. Dort wird der event->type() ausgewertet, was wahrscheinlich schneller ist als bei jedem eintreffenden event zu casten.
K.A. ob es vorkommen kann, dass type() ein QEvent::KeyPress zurückliefert, aber der cast in einem NULL-Pointer endet...
Verfasst: 31. Dezember 2008 14:39
von upsala
Der Operator static_cast gibt, im Gegensatz zum normalen casting, einen NULL Pointer zurück, wenn die Konvertierung fehlschlägt. In Deinem Fall also, wenn ein anderes Event als ein QKeyEvent ankommt.
Da verwechselt jemand was mit dem dynamic_cast...