Diferència entre revisions de la pàgina «PyQt: pintar dintre d'un widget»
		
		
		
		
		
		
		Salta a la navegació
		Salta a la cerca
		
				
		
		
		
		
		
		
		
	
|  (super del constructor erroni) | |||
| (Hi ha 17 revisions intermèdies del mateix usuari que no es mostren) | |||
| Línia 1: | Línia 1: | ||
| + | == Pintar en els widgets == | ||
| Anem a pintar els nostres propis widgets en Qt. Per fer això es fa de la següent manera: | 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) | * 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. | * 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 el  | + | * Dintre de paintEvent(self,e) podem pintar el què vulguem mitjançant l'[http://doc.qt.digia.com/qt/qpainter.html objecte QPainter]. | 
| + | * L'[http://doc.qt.digia.com/qt/qpainter.htmlhttp://doc.qt.digia.com/qt/qpainter.html 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 == | == Classe derivada == | ||
| Línia 10: | Línia 13: | ||
|          # ULL: cridar el constructor de la classe base és IMPRESCINDIBLE |          # ULL: cridar el constructor de la classe base és IMPRESCINDIBLE | ||
|          # (si sobreescrivim el constructor __init__, si no, no cal) |          # (si sobreescrivim el constructor __init__, si no, no cal) | ||
| − |          super( | + |          super(Pantalla,self).__init__() | 
|          self.initUI() |          self.initUI() | ||
| Línia 17: | Línia 20: | ||
|          pass |          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): |      def paintEvent(self,e): | ||
|          # podriem liar-nos a pintar aquí mateix, o examinar l'event "e" |          # podriem liar-nos a pintar aquí mateix, o examinar l'event "e" | ||
| − |          # anem al lio... | + |          # anem al lio... necessitem un objecte QPainter | 
| − |          self.pintaPilota() | + |         qp = QtGui.QPainter() | 
| + |         qp.begin( self ) | ||
| + |          self.pintaPilota( qp ) | ||
| + |         qp.end() | ||
| − |      def pintaPilota(self): | + |      def pintaPilota(self, qp): | 
| − | |||
| − | |||
| − | |||
| − | |||
|          # podem optar per un Pen (pinta perifèric) |          # podem optar per un Pen (pinta perifèric) | ||
| − |          color = QtGui.QColor(0, 0, 0) | + |          color = QtGui.QColor( 0, 0, 0 ) | 
| − |          color.setNamedColor('#d4d4d4') | + |          color.setNamedColor( '#d4d4d4' ) | 
| − |          qp.setPen(color) | + |          qp.setPen( color ) | 
|          # o bé per un Brush (farcit). El color és RGB, òbviament |          # o bé per un Brush (farcit). El color és RGB, òbviament | ||
| − |          qp.setBrush(QtGui.QColor(200, 0, 0)) | + |          qp.setBrush( QtGui.QColor(200, 0, 0) ) | 
|          # PER FI, PINTEM LA PILOTA! |          # PER FI, PINTEM LA PILOTA! | ||
|          posx, posy = 20, 20 |          posx, posy = 20, 20 | ||
|          radx, rady = 10, 10 |          radx, rady = 10, 10 | ||
| − |          qp.drawEllipse( | + |          qp.drawEllipse( posx, posy , radx, rady ) | 
| − | |||
| − | |||
| − | |||
| </syntaxhighlight> | </syntaxhighlight> | ||
| <br> | <br> | ||
| − | == Exercici  | + | == Exercici: control d'una pilota == | 
| − | # Feu l'anterior exercici dels sliders | + | L'objectiu és pintar una pilota i controlar-la amb els sliders (posició vertical i horitzontal). | 
| + | |||
| + | # Feu l'anterior exercici dels sliders (en la [[Python:_GUI#Qt_pas_a_pas...|intro de PyQt]]). | ||
| #: [[Fitxer:Qt-sliders1.png]] | #: [[Fitxer:Qt-sliders1.png]] | ||
| # Canviem el textedit per una classe nova nostra (Pantalla) heretada de QWidget (detallada més amunt) | # 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) | # Afegim paintEvent i el disparem (de moment un print) només al repintar la pantalla (canvi de task) | ||
| − | # Pintem al widget Pantalla() amb QPainter ( | + | # Pintem al widget Pantalla() amb [http://doc.qt.digia.com/qt/qpainter.html 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ó). | 
| − | # Connectem els sliders amb posx i posy  | + | # 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. | 
| − | # Calculem la posx i posy d'acord amb els límits dels sliders i de la geometria de la pantalla | + | # 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. | ||
| + | #: [[Fitxer:Qt-piloteta1.png]] | ||
| + | # 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:<pre>x = valor_slider * amplada / total_ticks_slider</pre> | ||
| + | #: 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 [http://stackoverflow.com/questions/177778/in-qt-how-do-i-set-the-background-color-of-a-widget-like-combobox-or-double-spi 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. | ||
| + | <br> | ||
| − | + | == Timers i pilotetes == | |
| − | + | 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]] | |
| − | |||
Revisió de 15:56, 1 març 2013
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



