PyQt: pintar dintre d'un widget
La revisió el 15:56, 1 març 2013 per Enric (discussió | contribucions) (super del constructor erroni)
Contingut
Pintar en els widgets[modifica]
Anem a pintar els nostres propis widgets en Qt. Per fer això es fa de la següent manera:
- Creem la nostra classe derivant-la de QWidget (en el nostre exemple la classe Pantalla)
- Reimplementem el mètode paintEvent que es crida automàticament quan es repinta el Widget.
- Dintre de paintEvent(self,e) podem pintar el què vulguem mitjançant l'objecte QPainter.
- L'objecte QPainter ve a ser un "llapis" per dibuixar en el Widget. Feu un cop d'ull a la documentació, veureu que a part de la funció drawEllipse que fem servir, n'hi ha un fotimer com drawRect, drawArc, drawPixmap, etc.
Classe derivada[modifica]
class Pantalla(QtGui.QWidget):
def __init__(self):
# ULL: cridar el constructor de la classe base és IMPRESCINDIBLE
# (si sobreescrivim el constructor __init__, si no, no cal)
super(Pantalla,self).__init__()
self.initUI()
def initUI(self):
# inicialitzem aqui si tenim objectes interns
pass
# la funció paintEvent es crida cada cop que es pinta la pantalla
# no cal cap connect(), ja ve connectada per la QApplication
def paintEvent(self,e):
# podriem liar-nos a pintar aquí mateix, o examinar l'event "e"
# anem al lio... necessitem un objecte QPainter
qp = QtGui.QPainter()
qp.begin( self )
self.pintaPilota( qp )
qp.end()
def pintaPilota(self, qp):
# podem optar per un Pen (pinta perifèric)
color = QtGui.QColor( 0, 0, 0 )
color.setNamedColor( '#d4d4d4' )
qp.setPen( color )
# o bé per un Brush (farcit). El color és RGB, òbviament
qp.setBrush( QtGui.QColor(200, 0, 0) )
# PER FI, PINTEM LA PILOTA!
posx, posy = 20, 20
radx, rady = 10, 10
qp.drawEllipse( posx, posy , radx, rady )
Exercici: control d'una pilota[modifica]
L'objectiu és pintar una pilota i controlar-la amb els sliders (posició vertical i horitzontal).
- Feu l'anterior exercici dels sliders (en la intro de PyQt).
- Canviem el textedit per una classe nova nostra (Pantalla) heretada de QWidget (detallada més amunt)
- Afegim paintEvent i el disparem (de moment un print) només al repintar la pantalla (canvi de task)
- Pintem al widget Pantalla() amb QPainter.
- Comença per la pilota amb un drawEllipse com el de l'exemple però també prova drawRect, drawArc o altres opcions del QPainter (caldrà que miris la documentació).
- Per poder seguir ens convé tenir els valors posx i posy com a atributs de l'objecte Pantalla (i no com a variables locals). Crea, doncs, aquests atributs en Pantalla i pinta la pilota amb aquests valors interns. Després modificarem aquests valors amb els sliders.
- Connectem els sliders amb funcions que modifiquin la posx i la posy. De moment assigna'ls el valor que t'arriba del slider i prou.
- PyQt: connectant signals amb slots
- IMPORTANT: quan canvieu el valor de posx o posy cal repintar la pantalla (no es fa automàticament). Utilitzeu la funció repaint() del widget per forçar una repintada.
- Calculem la posx i posy d'acord amb els límits dels sliders i de la geometria de la pantalla (que pot variar, per exemple, al maximitzar-la). Es tracta d'una senzilla regla de 3:
x = valor_slider * amplada / total_ticks_slider
- 100 és el total de ticks del slider, i l'amplada la podeu esbrinar del propi widget amb width()
- Per canviar el color del background teniu aquest link. A mi m'ha funcionat el del QPalette i no el de QStyleSheet.
- PyQt: Events de teclat: opcionalment pots afegir control del teclat als sliders.
Timers i pilotetes[modifica]
Ens proposem l'objectiu de fer un widget on aparegui una pilota que rebota a les seves parets.
Seguiu el següent article: PyQt: Timers i pilotes rebotant