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 :

QGraphicsScene


Sujet :

PyQt Python

  1. #1
    Invité
    Invité(e)
    Par défaut QGraphicsScene
    Bonjour,

    j'essaye actuellement d'intégrer une zone de "graphique" (à l'aide des QGraphicsScène et QGraphicsView) dans une fenêtre potentiellement remplie avec d'autres widgets. (En gros, au final, je souhaite juste tracer des droites horizontales ou verticales dans ce cadre "graphique").

    j'aimerais que l'évènement "clic" de la souris soit actif uniquement lorsque le clic est réalisé sur le QgraphicsScene et soit inactif si je clic ailleurs... parce qu'au clic sur le QgraphicsScene j'aimerais tracer une droite à partir de l'endroit qui est cliqué...

    ci dessous le code tel qu'il est actuellement. Mon problème c'est que lorsque je clique n'importe ou dans la fenêtre (hors zone de traçage), l'évènement "clic" reste actif et induit une droite dans la zone de traçage...
    aussi, quand je clique dans la zone de traçage, j'ai un décalage qui est probablement du au fait que je n'arrive pas à "cadrer" ma zone de traçage.

    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
    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
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    #!/usr/bin/env python
     
    from PyQt5.QtCore import (QLineF, QPointF, QRectF, Qt)
    from PyQt5.QtGui import (QBrush, QColor, QPainter,QPen,QFont)
    from PyQt5.QtWidgets import (QApplication, QGraphicsView, QGraphicsScene, QGraphicsItem,
                                 QGridLayout, QVBoxLayout, QHBoxLayout,
                                 QLabel, QLineEdit, QPushButton,QWidget, QMainWindow)
     
    class MainWindow(QMainWindow):
        def __init__(self):
            super(MainWindow, self).__init__()
     
            fenetre_widget = QWidget()
     
            self.scene = QGraphicsScene(self)
            self.scene.setSceneRect(0, 0, 200, 200)
            self.scene.clear()
     
            self.view =QGraphicsView(self.scene)
            self.view.setScene(self.scene)
            self.view.setCacheMode(QGraphicsView.CacheBackground)
     
            self.pen=QPen()
            self.pen.setWidth(1)
            self.pen2=QPen()
            self.pen2.setWidth(5)
     
            self.label1=QLabel("Test")
            self.label1.setFixedWidth(400)
     
            layouthorizontal1 = QHBoxLayout()
            layouthorizontal1.addWidget(self.view)
            layouthorizontal1.addWidget(self.label1)
     
            fenetre_widget.setLayout(layouthorizontal1)        
            self.setCentralWidget(fenetre_widget)
     
            self.nb_droite=0
     
        def keyPressEvent(self, event):
            key = event.key()
            if key == Qt.Key_R:
                self.scene.clear()
            super(MainWindow, self).keyPressEvent(event)
        def mousePressEvent(self, event):
            pos = event.pos()
            print(pos)
            taillex=self.width()
            tailley=self.height()
            if self.nb_droite<2:
                if self.nb_droite==0:
                    self.pos1x=pos.x()
                    self.pos1y=pos.y()
                    print(self.pos1x,self.pos1y)
                elif self.nb_droite==1:
                    self.pos2x=pos.x()
                    self.pos2y=pos.y()
                    print(self.pos2x,self.pos2y)
                self.scene.addLine(pos.x(),0,pos.x(),tailley,self.pen)
                self.nb_droite = self.nb_droite+1
                if self.nb_droite==2:
                    label=self.scene.addSimpleText (str(abs(self.pos1x-self.pos2x)) + " pixels", QFont('Norasi', 12))
                    ligne_legende=self.scene.addLine (20,tailley-15,(abs(self.pos1x-self.pos2x)/2),tailley-15,self.pen2)
                    label.setY(tailley-40)
                    label.setX(20)
                    print(self.pos1x-self.pos2x)
            elif self.nb_droite==2:
                self.scene.clear()
                self.nb_droite=0
     
    if __name__ == '__main__':
        import sys
        app = QApplication(sys.argv)
        mainWindow = MainWindow()
        mainWindow.show()
        sys.exit(app.exec_())

  2. #2
    Expert éminent

    Homme Profil pro
    Inscrit en
    Octobre 2008
    Messages
    4 302
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Belgique

    Informations forums :
    Inscription : Octobre 2008
    Messages : 4 302
    Points : 6 782
    Points
    6 782
    Par défaut
    Salut,

    Ta fenêtre et le QGraphicsView sont deux choses différentes avec leurs propres events.

    Je pense que ceci sera plus correct.
    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
    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
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
     
    from PyQt5.QtCore import (QLineF, QPointF, QRectF, Qt)
    from PyQt5.QtGui import (QBrush, QColor, QPainter,QPen,QFont)
    from PyQt5.QtWidgets import (QApplication, QGraphicsView, QGraphicsScene, QGraphicsItem,
                                 QGridLayout, QVBoxLayout, QHBoxLayout,
                                 QLabel, QLineEdit, QPushButton,QWidget, QMainWindow)
     
    class MainWindow(QMainWindow):
        def __init__(self):
            super(MainWindow, self).__init__()
            fenetre_widget = QWidget()
            self.view = QGraphicsView()
            self.view.setCacheMode(QGraphicsView.CacheBackground)
            self.pen = QPen()
            self.pen.setWidth(1)
            self.pen2 = QPen()
            self.pen2.setWidth(5)
            self.label1=QLabel("Test")
            self.label1.setFixedWidth(400)
            layouthorizontal1 = QHBoxLayout()
            layouthorizontal1.addWidget(self.view)
            layouthorizontal1.addWidget(self.label1)
            fenetre_widget.setLayout(layouthorizontal1)        
            self.setCentralWidget(fenetre_widget)
            self.view.mousePressEvent = self.on_mousePressEvent
            self.nb_droite=0
            self.scene = None
     
        def build_scene(self):
            self.scene = QGraphicsScene(self)
            self.scene.setSceneRect(0, 0, self.view.width(), self.view.height())
            self.view.setScene(self.scene)
     
        def keyPressEvent(self, event):
            key = event.key()
            if key == Qt.Key_R:
                self.scene.clear()
            super(MainWindow, self).keyPressEvent(event)
     
        def on_mousePressEvent(self, event):
            if self.scene is None:
                self.build_scene()
            pos = event.pos()
            print(pos)
            taillex=self.width()        # A mon avis tu veux dire self.view.width() ?
            tailley=self.height()       # A mon avis tu veux dire self.view.height() ?
            if self.nb_droite<2:
                if self.nb_droite==0:
                    self.pos1x=pos.x()
                    self.pos1y=pos.y()
                    print(self.pos1x,self.pos1y)
                elif self.nb_droite==1:
                    self.pos2x=pos.x()
                    self.pos2y=pos.y()
                    print(self.pos2x,self.pos2y)
                self.scene.addLine(pos.x(),0,pos.x(),tailley,self.pen)
                self.nb_droite = self.nb_droite+1
                if self.nb_droite==2:
                    label=self.scene.addSimpleText (str(abs(self.pos1x-self.pos2x)) + " pixels", QFont('Norasi', 12))
                    ligne_legende=self.scene.addLine (20,tailley-15,(abs(self.pos1x-self.pos2x)/2),tailley-15,self.pen2)
                    label.setY(tailley-40)
                    label.setX(20)
                    print(self.pos1x-self.pos2x)
            elif self.nb_droite==2:
                self.scene.clear()
                self.nb_droite=0
     
    if __name__ == '__main__':
        import sys
        app = QApplication(sys.argv)
        mainWindow = MainWindow()
        mainWindow.show()
        sys.exit(app.exec_())
    Pour le tracé des lignes je ne vois pas trop ce que tu veux obtenir, donc j'ai juste mis un commentaire.

  3. #3
    Invité
    Invité(e)
    Par défaut MERCI
    Salut,
    SUPER! c'est impeccable

    en fait, à terme j'aimerais faire des mesures sur photos... donc mesurer le nombre de pixel entre deux points (ou deux droites) afin de convertir cette mesure en longueur (après avoir étalonné les optiques qui fourniront les photos).

    je me suis pas encore penché sur le fait d'ajouter une photo là dedans mais si je me trompe pas ça devrait être possible... je vais voir ça demain.

    encore merci pour le coup de pouce!

  4. #4
    Expert éminent

    Homme Profil pro
    Inscrit en
    Octobre 2008
    Messages
    4 302
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Belgique

    Informations forums :
    Inscription : Octobre 2008
    Messages : 4 302
    Points : 6 782
    Points
    6 782
    Par défaut
    Citation Envoyé par dd-64 Voir le message
    je me suis pas encore penché sur le fait d'ajouter une photo là dedans mais si je me trompe pas ça devrait être possible...
    Sans soucis: http://pyqt.developpez.com/tutoriels/#imagerie (à adapter à Qt5)

  5. #5
    Invité
    Invité(e)
    Par défaut
    Bonjour,

    j'ai (un peu) modifié le code en ajoutant un "resizeEvent" afin de d'avoir quelque chose qui se trace correctement quelque soit la taille donnée à la fenêtre...

    L’interaction "resize"/"traçage de ligne" marche plutôt bien mais seulement une fois avoir changé la taille de la fenêtre manuellement... si j'enlève la fonction "resizeEvent" c'est l'inverse! A savoir que ça marche au premier affichage de la fenêtre mais plus une fois modifiée en taille (les ligne apparaissent décalées)...

    j'ai essayé d'appeler "resize" dès le "init" mais ça ne semble pas aller non plus...
    Aussi est-qu'il y a un moyen de forcer le fait de ne pas avoir de scrollbar qui s'affiche? (lors du redimensionnement et lorsqu'une ligne est tracée)?

    merci

    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
    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
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    from PyQt5.QtCore import (QLineF, QPointF, QRectF, Qt)
    from PyQt5.QtGui import (QBrush, QColor, QPainter,QPen,QFont)
    from PyQt5.QtWidgets import (QApplication, QGraphicsView, QGraphicsScene, QGraphicsItem,
                                 QGridLayout, QVBoxLayout, QHBoxLayout,
                                 QLabel, QLineEdit, QPushButton,QWidget, QMainWindow)
     
    class MainWindow(QMainWindow):
        def __init__(self):
            super(MainWindow, self).__init__()
            fenetre_widget = QWidget()
            self.view = QGraphicsView()
            self.view.setCacheMode(QGraphicsView.CacheBackground)
            self.pen = QPen()
            self.pen.setWidth(1)
            self.pen2 = QPen()
            self.pen2.setWidth(5)
            self.label1=QLabel("Test")
            self.label1.setFixedWidth(400)
            layouthorizontal1 = QHBoxLayout()
            layouthorizontal1.addWidget(self.view)
            layouthorizontal1.addWidget(self.label1)
            fenetre_widget.setLayout(layouthorizontal1)        
            self.setCentralWidget(fenetre_widget)
            self.view.mousePressEvent = self.on_mousePressEvent
            self.nb_droite=0
            self.scene = None
     
        def resizeEvent(self,resizeEvent):
            self.build_scene()
            self.scene.clear()
            self.nb_droite=0
     
        def build_scene(self):
            self.scene = QGraphicsScene(self)
            self.scene.setSceneRect(0, 0, self.view.width(), self.view.height())
            self.view.setScene(self.scene)
     
        def keyPressEvent(self, event):
            key = event.key()
            if key == Qt.Key_R:
                self.scene.clear()
            super(MainWindow, self).keyPressEvent(event)
     
        def on_mousePressEvent(self, event):
            if self.scene is None:
                self.build_scene()
            pos = event.pos()
            print(pos)
            taillex=self.view.width()
            tailley=self.view.height()       
            if self.nb_droite<2:
                if self.nb_droite==0:
                    self.pos1x=pos.x()
                    self.pos1y=pos.y()
                    print(self.pos1x,self.pos1y)
                elif self.nb_droite==1:
                    self.pos2x=pos.x()
                    self.pos2y=pos.y()
                    print(self.pos2x,self.pos2y)
                self.scene.addLine(pos.x(),0,pos.x(),tailley,self.pen)
                self.nb_droite = self.nb_droite+1
                if self.nb_droite==2:
                    label=self.scene.addSimpleText (str(abs(self.pos1x-self.pos2x)) + " pixels", QFont('Norasi', 12))
                    ligne_legende=self.scene.addLine (20,tailley-15,(abs(self.pos1x-self.pos2x)/2),tailley-15,self.pen2)
                    label.setY(tailley-40)
                    label.setX(20)
                    print(self.pos1x-self.pos2x)
            elif self.nb_droite==2:
                self.scene.clear()
                self.nb_droite=0
     
    if __name__ == '__main__':
        import sys
        app = QApplication(sys.argv)
        mainWindow = MainWindow()
        mainWindow.show()
        sys.exit(app.exec_())

  6. #6
    Invité
    Invité(e)
    Par défaut
    c'est bon, je crois que j'ai trouvé une petite solution (qui semble fonctionner comme il faut).
    il suffisait de remonter le setScene au dessus du setscenerect...

    et pour les scrollbars ajouter les deux lignes (comme ci dessous) dans le build_scene.

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
        def build_scene(self):
            self.scene = QGraphicsScene(self)
            self.view.setScene(self.scene)
            self.view.setVerticalScrollBarPolicy(Qt.ScrollBarAlwaysOff)
            self.view.setHorizontalScrollBarPolicy(Qt.ScrollBarAlwaysOff)
            self.scene.setSceneRect(0, 0, self.view.width(), self.view.height())

+ Répondre à la discussion
Cette discussion est résolue.

Discussions similaires

  1. [QGraphicsScene] Déplacer un item
    Par black is beautiful dans le forum Qt
    Réponses: 1
    Dernier message: 22/02/2009, 22h10
  2. QGraphicsScene et ses QGraphicsPolygonItem
    Par Tipha dans le forum Qt
    Réponses: 20
    Dernier message: 28/10/2008, 16h58
  3. Réponses: 3
    Dernier message: 13/09/2008, 19h23
  4. Réponses: 13
    Dernier message: 24/04/2008, 10h52
  5. utilisation de TControlGraphic ou QGraphicsScene
    Par guideram dans le forum C++
    Réponses: 2
    Dernier message: 02/07/2007, 11h57

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