Diferència entre revisions de la pàgina «PyQt: Events de teclat»

De Cacauet Wiki
Salta a la navegació Salta a la cerca
Línia 9: Línia 9:
 
<br>
 
<br>
  
== Exemples ==
+
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

...