Seite 1 von 1

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

Verfasst: 30. März 2009 10:05
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?

Verfasst: 30. März 2009 10:11
von RavenIV
/offtopic
Wie weit ist denn Dein 3D-Widget schon?
Kann man da Screenshots sehen?
/offtopic

Verfasst: 30. März 2009 10:18
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.

Verfasst: 30. März 2009 10:22
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.

Verfasst: 30. März 2009 13:47
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...

Verfasst: 30. März 2009 14:06
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!

Verfasst: 30. März 2009 14:57
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 ); 
}

Verfasst: 30. März 2009 15:42
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 :)