IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

PyQt Python Discussion :

[PyQT] Dessiner avec QPainter


Sujet :

PyQt Python

  1. #1
    Membre éclairé
    Profil pro
    Inscrit en
    Juillet 2005
    Messages
    482
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juillet 2005
    Messages : 482
    Par défaut [PyQT] Dessiner avec QPainter
    Bonjour,

    Je définit un objet avec un QLabel et un QPixmap dans lequel je vais dessiner :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    class preview(QGroupBox):
        def __init__(self, width=400, height=300):
            super().__init__()
     
            self.__margin = 5
            self.__width = width
            self.__height = height
     
            self.setTitle('Preview')
     
            self.__layout = QVBoxLayout()
            self.setLayout(self.__layout)
     
            self.__label = QLabel()
            canvas = QPixmap(width, height)
            canvas.fill(Qt.white)
            self.__label.setPixmap(canvas)
     
            self.__layout.addWidget(self.__label)
     
            #self.draw(5, 5, 290, 290)
     
        def draw(self, x, y, width, height, color='black'):
     
            painter = QPainter(self.__label.pixmap())
            pen = QPen()
            pen.setWidth(3)
            pen.setColor(QColor(color))
            painter.setPen(pen)
     
            painter.drawRect(x, y, width, height)
            painter.end()
    Dans l'interface de ma QMainWindow, je met une instance de mon objet preview et un bouton, quand je clique sur le bouton, il doit appeler la méthode draw de l'objet preview pour dessiner sur le canvas :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    class myApp(QMainWindow):
        ''' Fenêtre principale de l'interface graphique
        '''
        def __init__(self, parent=None):
            super().__init__(parent, Qt.WindowFlags())
     
            self.__chartPreview = preview()
     
            self.__mainLayout = QVBoxLayout()
     
            self.btntest = QPushButton('Test')
            self.btntest.clicked.connect(self.test)
     
            self.__mainLayout.addWidget(self.__chartPreview)
            self.__mainLayout.addWidget(self.btntest)
     
        def test(self):
            self.__chartPreview.draw(5, 5, 290, 290)

    Mais quand je clique sur le bouton, ça ne dessine rien. Si je met une appel à draw dans le __init__ du l'objet preview (cf. ligne en commentaire), ça me dessine bien un rectangle dans le canvas.

    Qu'est ce qui cloche?

    Merci,
    Nico

  2. #2
    Membre prolifique
    Avatar de Sve@r
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Février 2006
    Messages
    12 801
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Oise (Picardie)

    Informations professionnelles :
    Activité : Ingénieur développement logiciels
    Secteur : Aéronautique - Marine - Espace - Armement

    Informations forums :
    Inscription : Février 2006
    Messages : 12 801
    Billets dans le blog
    1
    Par défaut
    Bonjour
    Citation Envoyé par DiverSIG Voir le message
    Qu'est ce qui cloche?
    Là comme ça à froid je vois pas. Peut-être que créer un QPen() sans lui dire que le QWidget sera son parent pose souci (la parenté est un élément super important dans Qt). Il faudrait un exemple plus complet permettant de tester (parce que même en rajoutant un QApplication qui crée un myApp je n'ai vu aucun bouton permettant de cliquer quoi que ce soit).
    En revanche, un QWidget possède un évènement paintEvent() que tu as le droit de surcharger. Et cet évènement est appelé dès que la méthode .update() du QWidget est invoquée.
    Autrement dit, tu peux connecter le bouton à un slot qui se charge de préparer l'affichage puis appeler .update(). Et dans le paintEvent() tu fais ton dessin.
    Un exemple ici: https://pyqt.developpez.com/telechar...eut-tout-faire. Et tu verras que dans cet exemple, je n'ai pas eu besoin de QPen

    J'ai toutefois vu un détail qui choque: ton QMainWindow ne définit aucun widget central (méthode setCentralWidget). Or c'est ultra important. Parce qu'un QMainWindow est un widget un peu universel: il peut représenter n'importe quel widget (et donc son comportement) ; mais donc on doit lui dire quel widget il doit représenter.
    Un exemple ici: https://pyqt.developpez.com/telechar...-au-mainwindow
    Mon Tutoriel sur la programmation «Python»
    Mon Tutoriel sur la programmation «Shell»
    Sinon il y en a pleins d'autres. N'oubliez pas non plus les différentes faq disponibles sur ce site
    Et on poste ses codes entre balises [code] et [/code]

  3. #3
    Membre éclairé
    Profil pro
    Inscrit en
    Juillet 2005
    Messages
    482
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juillet 2005
    Messages : 482
    Par défaut
    J'ai oublié, mais à la fin du __init__ de mon QMainWindow, j'ai ces 3 lignes :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    self.__centralWidget = QWidget(None, Qt.WindowFlags())
    self.__centralWidget.setLayout((self.__mainLayout))
    self.setCentralWidget(self.__centralWidget)

  4. #4
    Membre prolifique
    Avatar de Sve@r
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Février 2006
    Messages
    12 801
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Oise (Picardie)

    Informations professionnelles :
    Activité : Ingénieur développement logiciels
    Secteur : Aéronautique - Marine - Espace - Armement

    Informations forums :
    Inscription : Février 2006
    Messages : 12 801
    Billets dans le blog
    1
    Par défaut
    Citation Envoyé par DiverSIG Voir le message
    J'ai oublié
    Ah ben !!! C'était si difficile de faire "ctrl-a+ctrl-c" depuis ton source de départ???

    Citation Envoyé par DiverSIG Voir le message
    , mais à la fin du __init__ de mon QMainWindow, j'ai ces 3 lignes :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    self.__centralWidget = QWidget(None, Qt.WindowFlags())
    self.__centralWidget.setLayout((self.__mainLayout))
    self.setCentralWidget(self.__centralWidget)
    Evidemment là ça fonctionne mieux.

    J'ai trouvé: il faut rajouter un .update() à la fin du draw() pour activer le paintEvent() qui se charge d'afficher réellement le dessin. Quand tu appelles le draw() dans le __init__, c'est le show() (fait fatalement après) qui se charge d'appeler paintEvent() donc là ça fonctionne.
    Code python : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    from PyQt5.QtCore import *
    from PyQt5.QtGui import *
    from PyQt5.QtWidgets import *
    class preview(QGroupBox):
    	def __init__(self, width=400, height=300):
    		super().__init__()
     
    		self.__margin = 5
    		self.__width = width			# Inutile
    		self.__height = height			# Inutile
     
    		self.setTitle('Preview')
     
     
    		canvas = QPixmap(width, height)
    		canvas.fill(Qt.white)
    		self.__label = QLabel()
    		self.__label.setPixmap(canvas)
     
    		layout = QVBoxLayout(self)
    		layout.addWidget(self.__label)
     
    		#self.draw(5, 5, 290, 290)
     
    	def draw(self, x, y, width, height, color='black'):
    		print("draw")
     
    		pen = QPen()
    		pen.setWidth(3)
    		pen.setColor(QColor(color))
     
    		painter = QPainter(self.__label.pixmap())
    		painter.setPen(pen)
     
    		painter.drawRect(x, y, width, height)
    		painter.end()
    		self.update()
     
    class myApp(QMainWindow):
    	''' Fenêtre principale de l'interface graphique
            '''
    	def __init__(self, parent=None):
    		super().__init__(parent, Qt.WindowFlags())
     
    		self.setCentralWidget(QWidget(None, Qt.WindowFlags()))
     
    		self.__chartPreview = preview()
     
    		self.btntest = QPushButton('Test', clicked=self.test)
     
    		mainLayout = QVBoxLayout(self.centralWidget())
    		mainLayout.addWidget(self.__chartPreview)
    		mainLayout.addWidget(self.btntest)
     
    	def test(self):
    		print("test")
    		self.__chartPreview.draw(5, 5, 290, 290)
     
    import sys
    app=QApplication(sys.argv)
    app.w=myApp()
    app.w.show()
    app.exec_()
    Mon Tutoriel sur la programmation «Python»
    Mon Tutoriel sur la programmation «Shell»
    Sinon il y en a pleins d'autres. N'oubliez pas non plus les différentes faq disponibles sur ce site
    Et on poste ses codes entre balises [code] et [/code]

  5. #5
    Membre Expert
    Profil pro
    Inscrit en
    Mai 2006
    Messages
    721
    Détails du profil
    Informations personnelles :
    Localisation : Belgique

    Informations forums :
    Inscription : Mai 2006
    Messages : 721
    Par défaut
    La prochaine fois essayez de donner un exemple complet avec les import et le main(), ça va plus vite pour tester.

Discussions similaires

  1. Dessiner avec QPainter
    Par devqt dans le forum Débuter
    Réponses: 10
    Dernier message: 28/02/2011, 19h27
  2. [2D/3D] Dessiner un QCursor avec QPainter
    Par kaymak dans le forum Débuter
    Réponses: 2
    Dernier message: 28/08/2010, 00h07
  3. Réponses: 2
    Dernier message: 23/05/2010, 03h30
  4. Dessiner une ligne avec QPainter
    Par mr_samurai dans le forum Qt
    Réponses: 3
    Dernier message: 20/11/2008, 13h56
  5. Réponses: 6
    Dernier message: 18/09/2008, 12h35

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo