[gelöst] Timer für gedrückte Taste?

Alles rund um die Programmierung mit Qt
Antworten
Exasperation
Beiträge: 186
Registriert: 11. März 2009 18:00
Wohnort: VS

[gelöst] Timer für gedrückte Taste?

Beitrag von Exasperation »

Hallo!
Ich bin immernoch an einem 3D Widget dran, das 3D-Pfade anzeigt.. Es gibt auch eine Zoom-Funktion, auf die sich nun meine Frage bezieht... Und zwar möchte ich, dass je länger die Zoom-Taste (in meinem Fall Bild Auf/AB) gedrückt, desto schneller soll der Zoom von statten gehen... Ihr versteht was ich meine? ^^ Also kein lineares reinzoomen in bestimmten Schritten, sondern mit "Beschleunigung"... Gibt es da irgendwie einen Timer? Oder hat jemand einen Vorschlag wie sich sowas realisieren lässt?
Zuletzt geändert von Exasperation am 30. März 2009 15:43, insgesamt 1-mal geändert.
RavenIV
Beiträge: 267
Registriert: 21. Januar 2009 14:24
Wohnort: Waldshut

Beitrag von RavenIV »

/offtopic
Wie weit ist denn Dein 3D-Widget schon?
Kann man da Screenshots sehen?
/offtopic
Linux, das längste Text-Adventure aller Zeiten
dontinelli
Beiträge: 146
Registriert: 22. September 2006 20:53

Beitrag von dontinelli »

Mit QTimer? Beim Herunterdrücken der Taste startest du den Timer, beim gewünschten Intervall wird dann timeout() emitiert. Dieses Signal kannst du mit dem Slot, welches die Beschleunigung berechnet, verbinden.
franzf
Beiträge: 3114
Registriert: 31. Mai 2006 11:15

Beitrag von franzf »

QKeyEvent::isAutoRepeat() abfragen, falls true einen int (Klassen Member/static in der Methode) hochzählen, und entsprechend den Zoomfaktor erhöhen.

So würd ich es versuchen, garantier aber nix, da ungetestet :P

Grüße
Franz

// edit: Mach den Zähler als Klassenmember, musst das Ding ja irgendwann wieder auf 0 setzen, und das geht nur im keyReleaseEvent().

// edit2:
Ein kleiner Test, und so schauen meine Events aus:

Code: Alles auswählen

void Zoomer::keyPressEvent( QKeyEvent* e )
{
    m_pressCounter++;
    if( e->key() == Qt::Key_Plus ) {
        zoomIn();
    } else if( e->key() == Qt::Key_Minus ) {
        zoomOut();
    }
    return QLabel::keyPressEvent( e );
}

void Zoomer::keyReleaseEvent( QKeyEvent* e )
{
    if( !e->isAutoRepeat() )
        m_pressCounter = 0;
    return QLabel::keyReleaseEvent( e );
}
zoomIn/zoomOut können dann mittels m_pressCounter das nächste zoom-level ausrechnen. Du wirst (denke ich) deinen Zoom animieren. Dann kannst du im keyPressEvent() vor dem Hochzählen noch abfragen, ob die Animation schon fertig ist.
Exasperation
Beiträge: 186
Registriert: 11. März 2009 18:00
Wohnort: VS

Beitrag von Exasperation »

RavenIV hat geschrieben:/offtopic
Wie weit ist denn Dein 3D-Widget schon?
Kann man da Screenshots sehen?
/offtopic
Ist ein Projekt für meine Ausbildungsfirma, was innerhalb unserer Haupt-Software für die Maschinenbedienung verwendet wird und kanns deshalb aus Copyright-Gründen etc. nicht posten ;)

@franzf:
Wow, toller Ansatz! Damit komm ich gut zurecht und ich habs jetzt mehr oder weniger in meine bestehende Zoom Funktion integriert... Mein letztes Problem ist noch, wie ich das Event als autorep kennzeichnen kann... Die ganzen Tastenfunktionen werden in eienr switch-case kontruktion abgefragt:

Code: Alles auswählen

void gl_widget::keyPressEvent( QKeyEvent* event )
{
    switch( event->key() )
    {
        [...]
        case Qt::Key_PageDown:
        {      
            zoom_in();
            break;
        }
        case Qt::Key_PageUp:
        {      
            zoom_out();
            break;
        }
       [...]
}
Weil im Moment wird das keyReleaseEvent noch nach jedem Aufruf der Zoom-Funktion aufgerufen und dementsprechend auch jedes mal m_press_counter zurückgesetzt...
Zuletzt geändert von Exasperation am 30. März 2009 14:52, insgesamt 1-mal geändert.
franzf
Beiträge: 3114
Registriert: 31. Mai 2006 11:15

Beitrag von franzf »

Exasperation hat geschrieben:Mein letztes Problem ist noch, wie ich das Event als autorep kennzeichnen kann...
Gar nicht, denke das kommt vom darunterliegenden Windowmanager (hier X11). Wenn du einmal die Taste drückst und wieder los lässt ist autoRepeat false. Bleib auf der Taste drauf und schon das 2. Event ist autoRepeat==true.

Ich hab ja im keyReleaseEvent gefragt, ob das true ist, falls ja wird nicht auf 0 zurückgesetzt. WIe handhabst du das grad? KeyRealeaseEvent hast du ja auch nach jedem autoRepeat-Anschlag!
Exasperation
Beiträge: 186
Registriert: 11. März 2009 18:00
Wohnort: VS

Beitrag von Exasperation »

Ja das habe ich so in etwa von dir übernommen

Code: Alles auswählen

void gl_widget::keyReleaseEvent( QKeyEvent* e )
{
	if( !e->isAutoRepeat() )
	{
		m_press_counter = 0;
	}
    //return QLabel::keyReleaseEvent( e ); 
}
Exasperation
Beiträge: 186
Registriert: 11. März 2009 18:00
Wohnort: VS

Beitrag von Exasperation »

Okay, ich habs jetzt hinbekommen und das Ergebnis funktioniert toll :)

Mein anfänglicher Fehler war, dass ich die m_press_counter zwar in der *.h datei definiert hab, aber nicht initialisiert.. da hats ihn total verhaun... bin davon ausgegangen, dass er default mäßig 0 da reinschreibt.. hab jetz in ner initialize funktion die ich schon hatte noch reingehaun dass ich den counter auf 5 setze.. funktioniert alles super :)

Code: Alles auswählen

void gl_widget::zoom_in()
{
	translate_z_by( m_press_counter );
	m_press_counter++;
}

void gl_widget::zoom_out()
{
	translate_z_by( m_press_counter * -1 );
	m_press_counter++;
}
innerhalb der translate_z_by funktion habe ich natürlich den counter als factor eingebunden...

Das keyReleaseEvent ist so völlig ausreichend:

Code: Alles auswählen

void gl_widget::keyReleaseEvent( QKeyEvent* e )
{
	if( !e->isAutoRepeat() )
	{
		m_press_counter = 0;
	}
}
Also vielen Dank für deine Hilfe :)
Antworten