Diferència entre revisions de la pàgina «PyQt: Events de teclat»
Línia 9: | Línia 9: | ||
<br> | <br> | ||
− | + | Per moure objectes tenim bàsicament dues aproximacions: | |
+ | * '''Per events''': quan arribi un esdeveniment de tecla, canviem la posició de l'objecte. | ||
+ | * '''Per estat''': quan arribi un esdeveniment de tecla, canviarem l'estat del | ||
+ | <br> | ||
+ | |||
+ | == Moviment per event == | ||
Un petit sample per incloure a la vostra classe (normalment a la main window). | Un petit sample per incloure a la vostra classe (normalment a la main window). | ||
<syntaxhighlight lang="python"> | <syntaxhighlight lang="python"> | ||
def keyPressEvent(self, e): | def keyPressEvent(self, e): | ||
if e.key() == QtCore.Qt.Key_Left: | if e.key() == QtCore.Qt.Key_Left: | ||
+ | # canviem valor del slider | ||
val = self.xslider.value() | val = self.xslider.value() | ||
self.xslider.setValue( val - 2 ) | self.xslider.setValue( val - 2 ) | ||
+ | # o bé modifiquem la posició del nostre objecte | ||
+ | self.pantalla.barca.posx -= self.pantalla.barca.velx | ||
elif e.key() == QtCore.Qt.Key_Right: | elif e.key() == QtCore.Qt.Key_Right: | ||
+ | # canviem valor del slider | ||
val = self.xslider.value() | val = self.xslider.value() | ||
self.xslider.setValue( val + 2 ) | self.xslider.setValue( val + 2 ) | ||
+ | # o bé modifiquem la posició del nostre objecte (amb mètode) | ||
+ | self.pantalla.barca.mou_dreta() | ||
</syntaxhighlight> | </syntaxhighlight> | ||
<br> | <br> | ||
<big class="exercici">Oju amb l'autorepetició de tecles!!</big> | <big class="exercici">Oju amb l'autorepetició de tecles!!</big> | ||
<br> | <br> | ||
+ | |||
+ | |||
+ | == Moviment per estat == | ||
+ | Voldrem aquesta aproximació si volem un moviment fluid, i no a batzegades com resulta de fer-ho per events. | ||
+ | |||
+ | Per moure la barca de l'Arkanoid (o qualsevol altre joc) canviarem l'estat de l'objecte a la '''''flag'' booleana esq/dreta''', i ell sol canviarà la seva posició quan li arribi el torn del '''paintEvent''' (haurem d'implementar una funció '''actualitza_pos'''). | ||
Pel cas del '''keyReleaseEvent''' potser cal que comprovem si la tecla no ens ha saltat per "autorepeat" (quan mantenim premuda la tecla saltaran esdeveniments "a porrillo"). Per comprovar-ho farem: | Pel cas del '''keyReleaseEvent''' potser cal que comprovem si la tecla no ens ha saltat per "autorepeat" (quan mantenim premuda la tecla saltaran esdeveniments "a porrillo"). Per comprovar-ho farem: | ||
<syntaxhighlight lang="python"> | <syntaxhighlight lang="python"> | ||
+ | class Pantalla(QWidget): | ||
+ | ... | ||
def keyReleaseEvent(self, e): | def keyReleaseEvent(self, e): | ||
if not e.isAutoRepeat(): | if not e.isAutoRepeat(): | ||
Línia 34: | Línia 53: | ||
elif e.key() == QtCore.Qt.Key_Right: | elif e.key() == QtCore.Qt.Key_Right: | ||
self.barca.dreta = False | self.barca.dreta = False | ||
+ | ... | ||
+ | class Barca(QRect): | ||
+ | ... | ||
+ | def actualitza_pos(self): | ||
+ | if self.dreta: | ||
+ | self.posx += self.velx | ||
+ | ... | ||
+ | ... | ||
</syntaxhighlight> | </syntaxhighlight> | ||
+ | <br> | ||
== Focus == | == Focus == |
Revisió del 11:37, 28 gen 2014
Per capturar els events de teclat cal reimplementar diversos mètodes dintre del nostre widget principal:
- keyPressEvent(self, e): tecla premuda
- keyReleaseEvent(self,e): tecla alliberada
...i finalment donar el "focus" del teclat al widget (veure més avall).
La referència de les tecles la teniu aquí:
http://doc.qt.digia.com/4.7/qt.html#Key-enum
Per moure objectes tenim bàsicament dues aproximacions:
- Per events: quan arribi un esdeveniment de tecla, canviem la posició de l'objecte.
- Per estat: quan arribi un esdeveniment de tecla, canviarem l'estat del
Moviment per event
Un petit sample per incloure a la vostra classe (normalment a la main window).
def keyPressEvent(self, e):
if e.key() == QtCore.Qt.Key_Left:
# canviem valor del slider
val = self.xslider.value()
self.xslider.setValue( val - 2 )
# o bé modifiquem la posició del nostre objecte
self.pantalla.barca.posx -= self.pantalla.barca.velx
elif e.key() == QtCore.Qt.Key_Right:
# canviem valor del slider
val = self.xslider.value()
self.xslider.setValue( val + 2 )
# o bé modifiquem la posició del nostre objecte (amb mètode)
self.pantalla.barca.mou_dreta()
Oju amb l'autorepetició de tecles!!
Moviment per estat
Voldrem aquesta aproximació si volem un moviment fluid, i no a batzegades com resulta de fer-ho per events.
Per moure la barca de l'Arkanoid (o qualsevol altre joc) canviarem l'estat de l'objecte a la flag booleana esq/dreta, i ell sol canviarà la seva posició quan li arribi el torn del paintEvent (haurem d'implementar una funció actualitza_pos).
Pel cas del keyReleaseEvent potser cal que comprovem si la tecla no ens ha saltat per "autorepeat" (quan mantenim premuda la tecla saltaran esdeveniments "a porrillo"). Per comprovar-ho farem:
class Pantalla(QWidget):
...
def keyReleaseEvent(self, e):
if not e.isAutoRepeat():
if e.key() == QtCore.Qt.Key_Left:
self.barca.esq = False
elif e.key() == QtCore.Qt.Key_Right:
self.barca.dreta = False
...
class Barca(QRect):
...
def actualitza_pos(self):
if self.dreta:
self.posx += self.velx
...
...
Focus
Cal donar el "focus" del teclat al widget desitjat.
http://doc.qt.digia.com/qt/qwidget.html#setFocus
Simplement després del show() del widget principal:
self.show() self.setFocus()
Estratègies per moure una raqueta
...