QWidget / Events

Alles rund um die Programmierung mit Qt
Gapa
Beiträge: 63
Registriert: 4. Juli 2008 14:33
Kontaktdaten:

QWidget / Events

Beitrag von Gapa »

Hallo (mal wieder :D ),

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
Gestern war heute noch morgen!
franzf
Beiträge: 3114
Registriert: 31. Mai 2006 11:15

Beitrag 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 :P)
RD1978
Beiträge: 84
Registriert: 5. Juni 2007 08:00
Wohnort: Stralsund (DDR)

Beitrag 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.
AuE
Beiträge: 918
Registriert: 5. August 2008 10:58

Beitrag 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 ;-)
Gapa
Beiträge: 63
Registriert: 4. Juli 2008 14:33
Kontaktdaten:

...

Beitrag von Gapa »

Hallo,

vielen Dank für die Antworten! Ich hatte nicht gesehen, dass die Methode virtuell ist... :oops:

@AuE:
Jo danke, genau so mache ich es auch! :D

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
Gestern war heute noch morgen!
AuE
Beiträge: 918
Registriert: 5. August 2008 10:58

Beitrag von AuE »

Du hast die keypressed - Methode deines Mainwidgets überschrieben und nicht die des LineEdits...
Gapa
Beiträge: 63
Registriert: 4. Juli 2008 14:33
Kontaktdaten:

...

Beitrag 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?
Gestern war heute noch morgen!
franzf
Beiträge: 3114
Registriert: 31. Mai 2006 11:15

Beitrag 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
AuE
Beiträge: 918
Registriert: 5. August 2008 10:58

Beitrag 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
Gapa
Beiträge: 63
Registriert: 4. Juli 2008 14:33
Kontaktdaten:

...

Beitrag 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
Gestern war heute noch morgen!
upsala
Beiträge: 3946
Registriert: 5. Februar 2006 20:52
Wohnort: Landshut
Kontaktdaten:

Beitrag von upsala »

QTextEdit oder QLineEdit?

Könnte es sein, daß nur ein Return/Enter-Key interessant ist?

Code: Alles auswählen

void QLineEdit::returnPressed () 
Event-Filter. Auch dafür gibts in der Doku Beispielcode
Gapa
Beiträge: 63
Registriert: 4. Juli 2008 14:33
Kontaktdaten:

...

Beitrag 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 :D

Viele Grüße
Gapa
Gestern war heute noch morgen!
RD1978
Beiträge: 84
Registriert: 5. Juni 2007 08:00
Wohnort: Stralsund (DDR)

Beitrag 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...
}
franzf
Beiträge: 3114
Registriert: 31. Mai 2006 11:15

Beitrag 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...
upsala
Beiträge: 3946
Registriert: 5. Februar 2006 20:52
Wohnort: Landshut
Kontaktdaten:

Beitrag 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...
Antworten