I. Écrire des signaux personnalisés▲
Écrire des signaux personnalisés que l'on peut émettre à l'occasion de certains événements est une tâche facile. On doit d'abord créer l'objet de signal. Ceci se fait en utilisant la fonction pyqtSignal() de PyQt.QtCore. Voici sa signature :
QtCore.pyqtSignal
(
[optional argument types], [optional name])
On doit créer un objet de signal en utilisant ce signal comme propriété de la classe, ensuite appeler sa méthode connect() pour finalement l'émettre. Sous forme de diagramme,
Le code ci-dessous explique trois types de signal :
- un signal sans argument - simpleSig ;
- un signal avec quelques arguments - argumentSig ;
- un signal avec des arguments de plusieurs types (surcharge) - doubleSig.
# -*- coding: utf-8 -*-
from
PyQt4.QtGui import
*
from
PyQt4.QtCore import
*
import
sys
class
MyWidget
(
QWidget):
# Définition des signaux
# Pas d'argument, un simple signal qui peut être émis
simpleSig =
pyqtSignal
(
)
# Un signal qui requiert deux paramètres : un entier
# et une liste Python. On peut aussi en avoir plus
# de deux.
argumentSig =
pyqtSignal
(
int, list)
# Un signal qui peut envoyer deux ensembles différents
# de paramètres : l'un pour un int, l'autre pour une QString.
# Ce signal est aussi nommé name pour utilisation dans des
# buts plus dynamiques.
doubleSig =
pyqtSignal
((
int,), (
QString,), name=
'doubles'
)
def
__init__
(
self, parent=
None
):
# Construction du parent, à ne jamais oublier !
super(
MyWidget, self).__init__
(
parent)
# On connecte les signaux à leur slot
self.simpleSig.connect
(
self.simpleSlot)
self.argumentSig.connect
(
self.argumentSlot)
# On a le même slot pour les signaux doubles (surchargés),
# parce que l'on peut aussi vérifier l'argument depuis
# l'intérieur
self.doubleSig['int'
].connect
(
self.doubleSlot)
self.doubleSig['QString'
].connect
(
self.doubleSlot)
# On connecte le bouton à un slot qui va appeler les signaux.
self.button =
QPushButton
(
'Press me'
, self)
self.button.clicked.connect
(
self.buttonClicked)
def
buttonClicked
(
self, checked=
False
):
# On émet les signaux pour les utiliser.
self.simpleSig.emit
(
)
self.argumentSig.emit
(
2
, [1
,2
,3
])
# Les signaux surchargés ont le format suivant.
self.doubleSig['int'
].emit
(
42
)
self.doubleSig['QString'
].emit
(
'Hitchhiking a ride.'
)
# Définition des slots
def
simpleSlot
(
self):
# Sans argument
print
"Simple custom signal:"
,
print
"No arguments in this type of signal."
def
argumentSlot
(
self, *
args):
# (ou 'argumentSlot(self, intArg, listArg)')
# Possède deux arguments, qui sont regroupés en un seul avec *
print
"Multi-argument signal:"
,
print
"Two arguments were passed: value: '
%d
' of
%s
and value: '
%s
' of
%s
."
%
(
args[0
], type(
args[0
]), args[1
], type(
args[1
]))
def
doubleSlot
(
self, someArgument):
# Ce slot gère doubleSig(int)
# et doubleSig(QString)
print
"Overloaded signal:"
,
print
"An argument was passed and it was of '
%s
' and value: '
%s
'."
%
(
type(
someArgument), someArgument)
if
__name__
==
'__main__'
:
app =
QApplication
(
sys.argv)
widget =
MyWidget
(
)
widget.show
(
)
app.exec_
(
)
La sortie à l'exécution de cet exemple pourrait être :
Simple custom signal: No arguments in this type of signal.
Multi-argument signal: Two arguments were passed: value: '2' of <type 'int'> and value: '[1, 2, 3]' of <type 'list'>.
Overloaded signal: An argument was passed and it was of '<type 'int'>' and value: '42'
Overloaded signal: An argument was passed and it was of '<class 'PyQt4.QtCore.QString'>' and value: 'Hitchhiking a ride.'
Référence : la documentation de PyQt.
II. Sauvegarder une image en JPEG avec QImage▲
JPEG est un format d'image génial, mais avec pertes. PyQt supporte le JPEG si un plug-in libjpeg est disponible sur le système. Peu importe, voici comment sauvegarder une QImage en JPEG :
img =
QImage
(
50
, 50
, QImage.Format_RGB32)
painter =
QPainter
(
img)
painter.setBrush
(
QBrush
(
QColor
(
'#ff0000'
)))
painter.drawRect
(
0
,0
,50
,50
)
painter.end
(
)
img.save
(
"sample.jpg"
)
Ce snippet crée une image sample.jpg qui ressemble à ceci :
III. Suivre la souris de près avec les événements de survol▲
Les événements de survol (aussi connus sous le nom de mouseMoveEvent(event) du côté de PyQt) sont suivis par défaut si un bouton de la souris est pressé puis relâché. Cependant, si on veut aussi suivre les mouvements de la souris quand elle survole une zone sans qu'un bouton soit appuyé, on va devoir activer la propriété mouseTracking de QWidget. Ainsi, on doit appeler widget.setMouseTracking(true). Le snippet suivant est un simple programme qui affiche les coordonnées du pointeur de la souris tant qu'il survole la fenêtre.
from
PyQt4.QtGui import
*
from
PyQt4.QtCore import
*
import
sys
class
MyWidget
(
QWidget):
def
__init__
(
self, parent=
None
):
super(
MyWidget, self).__init__
(
parent)
self.setMouseTracking
(
True
)
def
mouseMoveEvent
(
self, event):
print
"Mouse Pointer is currently hovering at: "
, event.pos
(
)
if
__name__
==
'__main__'
:
app =
QApplication
(
sys.argv)
widget =
MyWidget
(
)
widget.show
(
)
app.exec_
(
)
Il devrait ressortir quelque chose comme ceci :
Mouse Pointer is currently hovering at: PyQt4.QtCore.QPoint(415, 66)
Mouse Pointer is currently hovering at: PyQt4.QtCore.QPoint(420, 60)
Mouse Pointer is currently hovering at: PyQt4.QtCore.QPoint(424, 56)
Mouse Pointer is currently hovering at: PyQt4.QtCore.QPoint(427, 51)
Mouse Pointer is currently hovering at: PyQt4.QtCore.QPoint(433, 41)
Mouse Pointer is currently hovering at: PyQt4.QtCore.QPoint(438, 36)
On peut aussi procéder en définissant un attribut Qt.Hover par QWidget.setAttribute(attribute) puis en filtrant ces événements.
Référence : QMouseEvent.
IV. Bonus▲
IV-A. Taille de l'écran▲
Pour récupérer la taille de l'écran (la résolution d'affichage, en d'autres mots), il suffit d'accéder au widget du bureau par QApplication.desktop(), une méthode statique, il n'est donc pas nécessaire d'avoir un objet QApplication. On peut alors en récupérer la size() :
QApplication.desktop
(
).size
(
)
Référence : QApplication.
IV-B. Définir la taille de la fenêtre▲
On peut définir la taille de la fenêtre comme celle de n'importe quel widget, on doit juste définir sa propriété de géométrie, peu importe la classe :
widgetObj.setGeometry
(
x, y, width, height)
Référence : QWidget.
V. Remerciements▲
Merci à Harsh pour l'autorisation de traduire son article, PyQt FAQ - Custom Signals, JPEG, Mouse Hovers and More !
Merci à Jean-Philippe André pour sa relecture orthographique !