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 :

Bouger un segment à la souris [QtGui]


Sujet :

PyQt Python

  1. #1
    Membre chevronné

    Profil pro
    Account Manager
    Inscrit en
    Décembre 2006
    Messages
    2 301
    Détails du profil
    Informations personnelles :
    Localisation : France, Savoie (Rhône Alpes)

    Informations professionnelles :
    Activité : Account Manager

    Informations forums :
    Inscription : Décembre 2006
    Messages : 2 301
    Points : 1 752
    Points
    1 752
    Par défaut Bouger un segment à la souris
    Bonjour,
    les codes donnés ci-dessous permettent de créer une fenêtre graphique dans laquelle on peut tracer à la souris des segments ou des lignes brisées (ie un ensemble de segments qui se "suivent"), ainsi que des points isolés et des cercles.

    Le problème est que ma méthode est statique (donc pratiquement inutile) : une fois les objets tracés, impossible de les déplacer. Je voudrais donc savoir comment créer des objets qui peuvent être déplacés. Je pense qu'il faut définir une classe item pour chaque objet graphique, et aussi faire en sorte que les points utilisés par ces items soient "dragables". Les déplacements seront ainsi gérés par PyQt.
    Il faudrait aussi que je sache quand un élément est bougé pour savoir quel objet est bougé.

    Si quelqu'un a une idée je suis preneur.

    LES CODES

    Comportement_GraphicsView.py
    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
    from PyQt4 import QtCore, QtGui
     
    class GraphicsView_1(QtGui.QGraphicsView):
    # Lors du premier appel d'un graphique, on peut lui donner diverses variables mais aussi des fonctions.
    # Nous utilisons cela pour récupérer foncRetour, la fonction qui sera appelée à partir du GraphicsView personnalisé.
    #
    # Cette méthode a été trouvée à l'adresse suivante :
    # http://www.mail-archive.com/pyqt@riverbankcomputing.com/msg13873.html
        def __init__(self, foncRetour, parent=None):
            super(GraphicsView_1, self).__init__(parent)
    # Pour un usage tout au sein de la classe, nous utilisons l'astuce ci-dessous (sans faire cela, nous ne pourrions pas
    # utiliser foncRetour dans n'importe quelle méthode).
            self.foncRetour = foncRetour
     
    # Les différents évènements liés à la souris sont présentés dans le livre «*Rapid GUI Programming with Python and Qt*» de Mark SUMMERFIELD.
        def wheelEvent(self, event):
            print u"Au dessus du graphique 1 : Roulette de la souris activée"
     
        def mouseMoveEvent(self, mouseEvent):
            pt = mouseEvent.pos()
            self.foncRetour(1,pt.x(),pt.y())
     
        def mousePressEvent(self, mouseEvent):
            if mouseEvent.button() == QtCore.Qt.LeftButton :
                pt = mouseEvent.pos()
                print 'Sur le graphique 1 : Clic Gauche avec la souris \nPosition relative (x;y) = (' + str(pt.x()) + ';' + str(pt.y()) + ')'
            elif mouseEvent.button() == QtCore.Qt.RightButton :
                print 'Sur le graphique 1 : Clic Droit avec la souris \nPosition globale (x;y) = (' + str(mouseEvent.globalX()) + ';' + str(mouseEvent.globalY()) + ')'
     
     
    class GraphicsView_2(QtGui.QGraphicsView):
        def __init__(self, foncRetour, parent=None):
            super(GraphicsView_2, self).__init__(parent)
            self.foncRetour = foncRetour
     
        def wheelEvent(self, event):
            print u"Au dessus du graphique 2 : Roulette de la souris activé"
     
        def mouseMoveEvent(self, mouseEvent):
            pt = mouseEvent.pos()
            self.foncRetour(2,pt.x(),pt.y())
     
        def mousePressEvent(self, mouseEvent):
            if mouseEvent.button() == QtCore.Qt.LeftButton :
                pt = mouseEvent.pos()
                print 'Sur le graphique 2 : Clic Gauche avec la souris \nPosition relative (x;y) = (' + str(pt.x()) + ';' + str(pt.y()) + ')'
            elif mouseEvent.button() == QtCore.Qt.RightButton :
                print 'Sur le graphique 2 : Clic Droit avec la souris \nPosition globale (x;y) = (' + str(mouseEvent.globalX()) + ';' + str(mouseEvent.globalY()) + ')'
    window_TestSouris_Plus.py
    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
    # -*- coding: utf-8 -*-
     
    # Form implementation generated from reading ui file 'C:\Documents and Settings\Christophe\Mes documents\2,pyBaNaMa\DebuterAvecPythonEtPyQT\CodesProjets\05-Proj5_DessinGraphSouris\01-TestSouris\window_TestSouris_Plus.ui     '
    #
    # Created: Thu Aug 14 13:49:25 2008
    #      by: PyQt4 UI code generator 4.4.2
    #
    # WARNING! All changes made in this file will be lost!
     
    from PyQt4 import QtCore, QtGui
     
    # On commence par importer les GraphicsView modifiés pour notre usage.
    # Nous pourrions très bien coller ici ces modifications mais que se passerait-il en cas de restrucration visuelle de l'interface ?
    # Nous avons donc choisi de modifier au minimum le code Python de notre interface (toujours dans l'esprit de sépartaion du fond et de la forme).
    from Comportement_GraphicsView import GraphicsView_1, GraphicsView_2
     
    class Ui_window_TestSouris_Plus(object):
        def setupUi(self, window_TestSouris_Plus):
            window_TestSouris_Plus.setObjectName("window_TestSouris_Plus")
            window_TestSouris_Plus.resize(697,538)
            window_TestSouris_Plus.setMinimumSize(QtCore.QSize(697,538))
            window_TestSouris_Plus.setMaximumSize(QtCore.QSize(697,538))
            self.centralwidget = QtGui.QWidget(window_TestSouris_Plus)
            self.centralwidget.setGeometry(QtCore.QRect(0,21,697,498))
            self.centralwidget.setObjectName("centralwidget")
            self.horizontalLayout = QtGui.QHBoxLayout(self.centralwidget)
            self.horizontalLayout.setObjectName("horizontalLayout")
     
    # Voici un autre changement à faire. La ligne originale de window_TestSouris est :
    # self.graphicsView_1 = QtGui.QGraphicsView(self.centralwidget)
            self.graphicsView_1 = GraphicsView_1(self.modifGraph)
    # Ce changement permet d'utiliser notre 1er Graphics View personnalisé en lui fournissant la fonction
    # qu'il utilisera pour indiquer les quelques évènments liés à la souris.
    # Toujours pour réduire au minimum la modification du code Python originel de notre interface,
    # nous définirons plus tard et à part la fonction modifGraph (voir le code de TestSouris_v1).
    # Fin du changement.
     
            self.graphicsView_1.setObjectName("graphicsView_1")
            self.horizontalLayout.addWidget(self.graphicsView_1)
            spacerItem = QtGui.QSpacerItem(40,20,QtGui.QSizePolicy.Preferred,QtGui.QSizePolicy.Minimum)
            self.horizontalLayout.addItem(spacerItem)
     
    # Même changement que pérécédemment.
            self.graphicsView_2 = GraphicsView_2(self.modifGraph)
    # Fin du changement.
     
            self.graphicsView_2.setObjectName("graphicsView_2")
            self.horizontalLayout.addWidget(self.graphicsView_2)
            window_TestSouris_Plus.setCentralWidget(self.centralwidget)
            self.menubar = QtGui.QMenuBar(window_TestSouris_Plus)
            self.menubar.setGeometry(QtCore.QRect(0,0,697,21))
            self.menubar.setObjectName("menubar")
            window_TestSouris_Plus.setMenuBar(self.menubar)
            self.statusbar = QtGui.QStatusBar(window_TestSouris_Plus)
            self.statusbar.setGeometry(QtCore.QRect(0,519,697,19))
            self.statusbar.setObjectName("statusbar")
            window_TestSouris_Plus.setStatusBar(self.statusbar)
     
            self.retranslateUi(window_TestSouris_Plus)
            QtCore.QMetaObject.connectSlotsByName(window_TestSouris_Plus)
     
        def retranslateUi(self, window_TestSouris_Plus):
            window_TestSouris_Plus.setWindowTitle(QtGui.QApplication.translate("window_TestSouris_Plus", "MainWindow", None, QtGui.QApplication.UnicodeUTF8))
     
    if __name__ == "__main__":
        import sys
        app = QtGui.QApplication(sys.argv)
        window_TestSouris_Plus = QtGui.QMainWindow()
        ui = Ui_window_TestSouris_Plus()
        ui.setupUi(window_TestSouris_Plus)
        window_TestSouris_Plus.show()
        sys.exit(app.exec_())
    TestSouris_v1.py
    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
    # -*- coding: utf-8 -*-
    #!/usr/bin/env python
    # Les lignes ci-dessus sont très importantes :
    #	1°) La 1ère ligne indique le codage du fichier Python.
    #	2°) La 2nde ligne est indispensable pour un bon fonctionnement sous Linux.
     
    # PRESENTATION : ce script montre comment lier un  texte ayant un contenu que nous allons analyser
    # à un arbre représentant la struture hiérarchique de ce texte.
    # AUTEUR : BAL Christophe
    # MAIL : projetmbc@club.fr
    # SITE : http://christophe_bal.club.fr/index.php
    # DATE DE CREATION : 14/08/2008
    # 
    # TEST(S) EFFECTUE(S) : programme testé sous Windows XP avec succès.
     
    # On importe les bibliothèques que nous allons utiliser.
    import sys
    from PyQt4 import QtCore, QtGui
    # On importe notre boîte de dialogue.
    from window_TestSouris_Plus import Ui_window_TestSouris_Plus
     
     
    # # # # # # # # # # # # # # # # # # # # # #
    # Comportement de la boîte de dialogue.   DEBUT
     
    class window_TestSouris_Plus(QtGui.QMainWindow, Ui_window_TestSouris_Plus):
    	def __init__(self):
    		QtGui.QMainWindow.__init__(self)
    		Ui_window_TestSouris_Plus.__init__(self)
    		self.setupUi(self)
     
    	def modifGraph(self,num_Graph,x_souris,y_souris):
    		self.statusbar.showMessage(u"Graphique n°" + str(num_Graph) + u" survolé : Souris aux coordonnées (" + str(x_souris) + ";" + str(y_souris) + ")", 500)
     
    # Comportement de la boîte de dialogue.   FIN
    # # # # # # # # # # # # # # # # # # # # # # # #
     
     
    # # # # # # # # # # # # # # #
    # Lancement de l'application.
    if __name__ == "__main__":	
    	app = QtGui.QApplication(sys.argv)
    	TestSouris = window_TestSouris_Plus()
     
    # Affichage d'une boîte de dialogue pour informer l'utilisateur de "l'utilité" de cette 1ère application test.
    # Nous avons déjà rencontré les boîtes de dialogue de PyQt. La seule chose qu'il faille faire c'est d'indiquer
    # que la boîte de dialogue est associé à l'interface TestSouris. Ceci se fait en remplaçant toutes les occurences
    # de self en TestSouris. Ainsi, on doit avoir
    #		QtGui.QMessageBox.information(TestSouris,... 
    # au lieu de
    #		QtGui.QMessageBox.information(self,... 
    # De même, toutes les fonctions
    #		self.tr(...)
    # doivent devenir
    #		TestSouris.tr(...)
    	QtGui.QMessageBox.information(TestSouris, TestSouris.tr(u"Fonctionnement de ce 1er test".encode('ISO-8859-15')),TestSouris.tr(u" En vous baladant sur les deux cadres blancs (qui sont des Graphics View),\n ou en cliquant (droit ou gauche), ou bien en utilisant la roulette,\n vous verrez soit apparaître en bas de la fenêtre, soit dans la console Python  \n des informations relatives à l'action faite et à la position de votre souris.".encode('ISO-8859-15')),QtGui.QMessageBox.Ok)
     
    	TestSouris.show()
    	sys.exit(app.exec_())

  2. #2
    Membre actif
    Avatar de doof
    Inscrit en
    Août 2003
    Messages
    160
    Détails du profil
    Informations forums :
    Inscription : Août 2003
    Messages : 160
    Points : 294
    Points
    294
    Par défaut
    Salut !

    Ma réponse est un peu tardive mais peut-être qu'il n'est pas trop tard.

    Pour pouvoir déplacer tes éléments, le mieux est d'utiliser ce qui est prévu pour dans le "Graphics View Framework" de Qt, à savoir utiliser pour les items des classes dérivées de QGraphicsItem, voir de plus haut niveau (QGraphicsLineItem, QGraphicsEllipseItem...) qui comportent un flag "QGraphicsItem::ItemIsMovable" qu'il suffit de mettre à True, permettant au framework de gérer entièrement les déplacements (et sélections/déplacements multiples en y associant QGraphicsItem::ItemIsSelectable).

    Il faudra donc basculer d'un mode de création d'items que tu gères entièrement à un mode de déplacement/sélection d'items géré par Qt de la façon que tu veux (bouton, appuis sur une touche...). Passer d'un mode à l'autre impliquera juste d'activer ou désactiver les flags ItemIsMovable et ItemIsSelectable de chaque items.

    Le mode de création implique de surcharger les évènements de souris, surtout n'oublie pas de toujours rappeler la méthode de l'évènement pour chaque évènement afin que la propagation d'évènement fonctionne bien et que donc les méthode de déplacement Qt s'accomplissent correctement (je me suis arraché les cheveux à cause de ça ^^).

    Pour savoir quand un élément est bougé et récupérer sa position, c'est faisable dans les évènements mouseReleaseEvent de ta classe d'item par exemple.

    Rien à voir mais j'ai regardé un peu ton code et ta fonction "foncRetour" que tu passe en argument me parait vraiment étrange dans l'esprit Qt ! Pourquoi utilises-tu une fonction de callback alors que tu as un puissant système de signal/slots ? il te suffirait d'émettre un signal passant tes arguments pour effectuer la même chose bien plus proprement.

  3. #3
    Membre chevronné

    Profil pro
    Account Manager
    Inscrit en
    Décembre 2006
    Messages
    2 301
    Détails du profil
    Informations personnelles :
    Localisation : France, Savoie (Rhône Alpes)

    Informations professionnelles :
    Activité : Account Manager

    Informations forums :
    Inscription : Décembre 2006
    Messages : 2 301
    Points : 1 752
    Points
    1 752
    Par défaut
    Citation Envoyé par doof Voir le message
    Salut !

    Ma réponse est un peu tardive mais peut-être qu'il n'est pas trop tard.
    Mieux vaut tard que jamais... T'inquiètes pas car cela fait quelques mois que je cherche des infos sur ce sujet.

    Citation Envoyé par doof Voir le message
    Rien à voir mais j'ai regardé un peu ton code et ta fonction "foncRetour" que tu passe en argument me parait vraiment étrange dans l'esprit Qt ! Pourquoi utilises-tu une fonction de callback alors que tu as un puissant système de signal/slots ? il te suffirait d'émvaises pratiques en expoliquant pourquettre un signal passant tes arguments pour effectuer la même chose bien plus proprement.
    En fait je suis en train de faire un tuto. sur PyQt qui reprend chronologiquement mon apprentissage y compris les mauvaises idées en expliquant pourquoi le choix est mauvais. Il y aura une partie juste après utilisant les signals/slots personnalisés que je ne connais pas trop au moment je tape ce message.


    Citation Envoyé par doof Voir le message
    Il faudra donc basculer d'un mode de création d'items que tu gères entièrement à un mode de déplacement/sélection d'items géré par Qt de la façon que tu veux (bouton, appuis sur une touche...). Passer d'un mode à l'autre impliquera juste d'activer ou désactiver les flags ItemIsMovable et ItemIsSelectable de chaque items.

    Le mode de création implique de surcharger les évènements de souris, surtout n'oublie pas de toujours rappeler la méthode de l'évènement pour chaque évènement afin que la propagation d'évènement fonctionne bien et que donc les méthode de déplacement Qt s'accomplissent correctement (je me suis arraché les cheveux à cause de ça ^^).
    Pourrais-tu préciser un peu ? As-tu un exemple simple ? Si tu pouvais m’indiquer dans le cas de mon prog. ce qu’il faut faire ce serait très sympa. Mon problème est que tous les exemples que je trouve sur le sujet sont très longs et donc pas faciles à appréhender par un débutant.

  4. #4
    Membre actif
    Avatar de doof
    Inscrit en
    Août 2003
    Messages
    160
    Détails du profil
    Informations forums :
    Inscription : Août 2003
    Messages : 160
    Points : 294
    Points
    294
    Par défaut
    Un code commenté vaut mieux qu'un long discours, je te mets donc un code qui crée dans l'état uniquement des lignes, des rectangles et des ellipses.

    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
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    92
    93
    94
    95
    96
    97
    98
    99
    100
    101
    102
    103
    104
    105
    106
    107
    108
    109
    110
    111
    112
    113
    114
    115
    116
    117
    118
    119
    120
    121
    122
    123
    124
    125
    126
    127
    128
    129
    130
    131
    132
    133
    134
    135
    136
    137
    138
    139
    140
    141
    142
    143
    144
    145
    146
    147
    148
    149
    150
    151
    152
    153
    154
    155
    156
    157
    158
    159
    160
    161
    162
    163
    164
    165
    166
    167
    168
    169
    170
    171
    172
    173
    174
    175
    176
    177
    178
    179
    180
    181
    182
    #!/usr/bin/python
    # -*- coding: utf8 -*-
     
    import sys
    from PyQt4.QtCore import *
    from PyQt4.QtGui import *
     
    class MainWindow(QMainWindow):
    	def __init__(self):
    		QMainWindow.__init__(self)
    		self.scene = MyGraphicsScene()
    		self.scene.setSceneRect( -500.0, -500.0, 1000.0, 1000.0 );
    		self.view = QGraphicsView()
    		self.view.setScene (self.scene)
    		self.view.setRenderHints(QPainter.Antialiasing)
    		self.setCentralWidget(self.view)
     
    		QObject.connect(self.scene, SIGNAL("modeChanged"), self.changeMode)
     
    	def changeMode(self, mode): # le flag RubberBand pose problème en mode création
    		if mode == 1:
    			self.view.setDragMode(QGraphicsView.NoDrag)
    		else:
    			self.view.setDragMode(QGraphicsView.RubberBandDrag)
     
     
    class MyGraphicsScene(QGraphicsScene):
    	def __init__(self):
    		QGraphicsScene.__init__(self)
    		self.createMode = 0 # 0 = édition, 1 = création
    		self.createState = False # état de la création utile pour l'évènement mouseMoveEvent
    		self.defaultItem = 0 #type d'item à créer
    		self.pen = QPen(Qt.black, 2) # crayon normal d'une figure
    		self.penTemp = QPen(Qt.red, 2) # crayon temporaire à la création
    		self.penOver = QPen(Qt.blue, 2) # crayon quand survolé
     
    	def mousePressEvent(self, e):
    		if e.button() == Qt.LeftButton and self.createMode == 1: # si click gauche en mode création
    			self.firstPoint = e.scenePos() # on prend le premier point en membre de classe
    			self.currentItem = self.createItem() # on crée l'item sans taille
    			self.currentItem.setPen(self.penTemp) # on fixe sa couleur
    			self.addItem(self.currentItem) # on l'ajoute à la scène
    			self.createState = True # on met l'état création en cours à true
    		else:
    			QGraphicsScene.mousePressEvent(self, e)  # on fait suivre l'event
     
    	def mouseReleaseEvent(self, e):
    		if e.button() == Qt.LeftButton and self.createState:# si release gauche en mode création
    			if e.scenePos() == self.firstPoint: # si le point relaché est le même que le premier point
    				self.removeItem(self.currentItem) # on supprime l'item de la scène
    				del self.currentItem # on le supprime même de la mémoire
    			else:
    				self.currentItem.setPen(self.pen) # on lui donne sa couleur normale
    			self.createState = False
    		else:
    			QGraphicsScene.mouseReleaseEvent(self, e) # on fait suivre l'event
     
    	def mouseMoveEvent(self, e):
    		if self.createState: # si on est en cours de création
    			self.currentItem.resize(self.firstPoint, e.scenePos()) # on redimentionne
    		else:
    			QGraphicsScene.mouseMoveEvent(self, e) # on fait suivre l'event
     
    	def keyPressEvent(self, e):
    		key   = e.key()
    		if( key == Qt.Key_Delete): # touche suppr
    			self.removeSelection() # on efface la sélection
    		elif(key == Qt.Key_Space and not e.isAutoRepeat()): # touche espace enfoncée
    			self.swapToCreateMode() # on passe en mode création
    		elif(key == Qt.Key_Return):
    			self.changeDefaultItem() # on change le type d'item à dessiner
     
    	def keyReleaseEvent(self, e):
    		key   = e.key()
    		if(key == Qt.Key_Space and not e.isAutoRepeat()): # touche espace relachée
    			self.swapToEditMode() # on revient en mode edit
     
    	def removeSelection(self): # appelé quand on appuie sur la touche suppr
    		items = self.selectedItems() # on récupère les items sélectionés
    		map(self.removeItem, items) # on les vire de la scène
    		for i in items: # on les détruit totalement
    			del i
     
    	def swapToCreateMode(self):
    		print "Mode creation"
    		self.createMode = 1 # passe en mode création
    		self.emit(SIGNAL("modeChanged"), self.createMode) # emet un signal pour que les items changent de flags
     
    	def swapToEditMode(self):
    		print "Mode edition"
    		self.createMode = 0 # passe en mode édition
    		self.emit(SIGNAL("modeChanged"), self.createMode) # emet un signal pour que les items changent de flags
     
    	def changeDefaultItem(self): # change l'item à creer par défaut
    		self.defaultItem = (self.defaultItem + 1) % 3 # on l'incrémente de 1
    		if self.defaultItem == 0: print "lignes"
    		elif self.defaultItem == 1: print "rectangles"
    		elif self.defaultItem == 2: print "Ellipses"
     
    	def createItem(self): # crée l'item voulu
    		if self.defaultItem == 0: return MyLineItem(self)
    		elif self.defaultItem == 1: return MyRectItem(self)
    		elif self.defaultItem == 2: return MyEllipseItem(self)
     
     
    class VirtualItem(object):
    	def __init__(self):
    		self.setAcceptHoverEvents(False) # flag pour est sensible au survol du curseur
    		self.setFlag(QGraphicsItem.ItemIsMovable, False) # le fameux flag pour le rendre "bougeable"
    		self.setFlag(QGraphicsItem.ItemIsSelectable, False) # flag pour le rendre sélectionnable
     
    		self.Q = QObject() # comme pyQT ne supporte pas l'héritage multiple, seul moyen pour émettre ou recevoir des signaux dans un item
    		self.Q.connect(self.parent, SIGNAL("modeChanged"), self.changeMode) # quand la vue change de mode
     
    	def hoverEnterEvent(self, e):
    		print "Enter", self
    		self.setPen(self.parent.penOver) # couleur de survol
     
    	def hoverLeaveEvent(self, e):
    		print "Leave", self
    		self.setPen(self.parent.pen) # revient à le couleur normale
     
    	def mousePressEvent(self, e):
    		print "Item", self, "pressed at ", self.pos()
    		QGraphicsItem.mousePressEvent(self, e) # on fait suivre l'event
     
    	def mouseReleaseEvent(self, e):
    		print "Item", self, "released at", self.pos()
    		QGraphicsItem.mouseReleaseEvent(self, e) # on fait suivre l'event
     
    	def changeMode(self, mode): #change les flags de l'item suivant le mode création ou édition
    		if mode == 1:
    			self.setAcceptHoverEvents(False)
    			self.setFlag(QGraphicsItem.ItemIsMovable, False)
    			self.setFlag(QGraphicsItem.ItemIsSelectable, False)
    		else:
    			self.setAcceptHoverEvents(True)
    			self.setFlag(QGraphicsItem.ItemIsMovable, True)
    			self.setFlag(QGraphicsItem.ItemIsSelectable, True)
     
     
     
     
     
    class MyLineItem(QGraphicsLineItem, VirtualItem):
    	def __init__(self, parent = None):
    		QGraphicsLineItem.__init__(self)
    		self.parent = parent # une ref sur le parent est utile plus tard (attacher les signaux)
    		VirtualItem.__init__(self)
     
    	def resize(self, p1, p2): # Méthode pour redimensionner l'item
    		self.setLine(QLineF(p1, p2))
     
     
    class MyRectItem(QGraphicsRectItem, VirtualItem):
    	def __init__(self, parent = None):
    		QGraphicsRectItem.__init__(self)
    		self.parent = parent # une ref sur le parent est utile plus tard (attacher les signaux)
    		VirtualItem.__init__(self)
     
    	def resize(self, p1, p2): # Méthode pour redimensionner l'item
    		self.setRect(QRectF(p1, p2))
     
     
    class MyEllipseItem(QGraphicsEllipseItem, VirtualItem):
    	def __init__(self, parent = None):
    		QGraphicsEllipseItem.__init__(self)
    		self.parent = parent # une ref sur le parent est utile plus tard (attacher les signaux)
    		VirtualItem.__init__(self)
     
    	def resize(self, p1, p2): # Méthode poor redimensionner l'item
    		self.setRect(QRectF(p1, p2))
     
     
     
     
     
    if __name__ == "__main__":
    	app = QApplication(sys.argv)
    	window = MainWindow()
    	window.show()
    	sys.exit(app.exec_())

    J'ai commenté toutes les lignes, tu devrais vite comprendre le principe, j'envoie même un signal aux items pour basculer le mode et tu vas voir que c'est vraiment très simple.

    Pour créer un item, il faut donc laisser enfoncée la barre d'espace tout en la dessinant à la souris, quand on relâche la barre d'espace, on rebascule en mode édition, qui permet de sélectionner et déplacer des items. Pour basculer entre création de ligne, de rectangle ou d'ellipse, c'est la touche entré. La touche "suppr" supprime les items séléctionés

    Le principe est simple, je crée une classe qui hérite de QGraphicsScene dans laquelle je surcharge les évenèments de souris pour ma création d'items. pour les Items proprement dis, j'ai créé une classe VirtualItem qui implémente toutes les méthodes communes aux items (surcharge d'évènements souris et basculement de mode). Cette classe ne s'instancie pas toute seule sous peine d'erreurs, en fait chaque item différent est créé par héritage multiple, avec comme parents le QGraphicsItem correspondant et VirtualItem qui évite la redondance de code. Le code dans chaque types d'items implémente les méthodes spécifiques à l'item, comme ici, le redimensionnement.

    Si tu as des questions, n'hésites pas

  5. #5
    Membre chevronné

    Profil pro
    Account Manager
    Inscrit en
    Décembre 2006
    Messages
    2 301
    Détails du profil
    Informations personnelles :
    Localisation : France, Savoie (Rhône Alpes)

    Informations professionnelles :
    Activité : Account Manager

    Informations forums :
    Inscription : Décembre 2006
    Messages : 2 301
    Points : 1 752
    Points
    1 752
    Par défaut
    Merci pour le code qui est excellent, je n'en demandais pas autant. Avec tes lignes de code non noyées dans un très long listing je devrais comprendre comment cela marche sans aucun problème.
    De plus, j'ai aussi au passage de quoi ajouter une fonctionnalité très utile : l'utilisation du clavier et de la souris pour des fonctionnalités particulières, un vrai bonheur !!!

    Peut-être une dernière petite question ? Sais-tu comment créer un unique objet graphique fabriqué avec plusieurs objets simples. Par exemple, je voudrais très classiquement que les points apparaissent sous forme de croix, il faudrait donc que du point de vue de PyQt, un point soit une réunion de deux segments qui doivent toujours bouger ensemble et non indépendamment l'un de l'autre. J'imagine qu'il faut définir les segments comme enfants du point. Sais-tu faire cela ?

    Encore une fois, merci beaucoup.

  6. #6
    Membre actif
    Avatar de doof
    Inscrit en
    Août 2003
    Messages
    160
    Détails du profil
    Informations forums :
    Inscription : Août 2003
    Messages : 160
    Points : 294
    Points
    294
    Par défaut
    J'ai justement fait ici les items les plus simples, à savoir gérés uniquement par deux points. Si tu veux Dessiner une ligne constituée de "plusieurs lignes", il me semble qu'un QGraphicsPolygonItem doit parfaitement convenir !

    Par contre, c'est un item constitué de plusieurs points, donc la méthode de création va forcément différer. Au lieu d'une séquence "barre d'espace enfoncée, clique gauche, relâche clique gauche", ça pourrait donner "barre d'espace enfoncée, clique, clique, clique, ..., relâche barre d'espace" où chaque clique serait un point. Enfin, c'est à toi de voir et de l'implémenter entièrement avec les évènements de souris.

    Pour ce qui est ensuite de l'édition des points individuels, ça se complique, le but du jeu est donc d'afficher d'autres items "contrôleurs" quand on survole ou sélectionne un item. C'est bien sur faisable mais y'a du boulot, il faut récupérer les coordonnées des points de l'item (facile), et créer temporairement d'autres items spéciaux à ces emplacements précis qui auront uniquement pour but d'envoyer les coordonnées où on les déplaces afin de transformer l'item que l'on édite.

    Tu as normalement à peu près tout ce qu'il te faut sous la main dans mon code plus haut (déplacer des items, modifier leurs coordonnées, connaitre l'item en cours) pour faire ça, après tout dépend de ce que tu veux faire exactement et comment tu comptes l'implémenter, la logique va grandement varier, mais les principes de base restent toujours les mêmes.

  7. #7
    Membre chevronné

    Profil pro
    Account Manager
    Inscrit en
    Décembre 2006
    Messages
    2 301
    Détails du profil
    Informations personnelles :
    Localisation : France, Savoie (Rhône Alpes)

    Informations professionnelles :
    Activité : Account Manager

    Informations forums :
    Inscription : Décembre 2006
    Messages : 2 301
    Points : 1 752
    Points
    1 752
    Par défaut
    Merci pour ces indications, je réfléchirais à cela quand j'aurais du temps, et je posterais alors ici ma solution.

    Ton code m'a fait faire un énorme pas en avant. Merci.

  8. #8
    Nouveau membre du Club
    Profil pro
    Inscrit en
    Octobre 2009
    Messages
    55
    Détails du profil
    Informations personnelles :
    Âge : 36
    Localisation : France

    Informations forums :
    Inscription : Octobre 2009
    Messages : 55
    Points : 33
    Points
    33
    Par défaut
    Je viens de lire ce sujet et c'est (presque) exactement ce que je souhaiterais faire. A une difference pres...

    En fait, au lieu d'ouvrir directement le code (qui marche tres bien), je clique sur un bouton appartenant a une interface differente. Ce clic m'ouvre une fenetre, dans lequelle j'ai un QLabel, et c'est dans ce QLabel que j'aimerais mettre mon QGraphicsScene pour ensuite y dessiner les formes.

    Mais je n'y arrive pas

    J'ai notamment l'erreur:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    TypeError: could not convert 'labelAreaCounting' to 'QWidget'
    Explication de mon code:

    1) Interface principale (dans generationSequences.py):
    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
    class Apply:
     
    	def __init__(self):
     
    		QtCore.QObject.connect( ui.pushButton_counting_area, QtCore.SIGNAL("clicked()"), self.manageAreaCounting )
     
    	def manageAreaCounting(self):
    		pass # ici je ne sais pas quoi mettre pour lancer la fenetre de dessin
     
    if __name__ == "__main__":
    	import sys
    	app = QtGui.QApplication(sys.argv)
     
    	AreaGT = QtGui.QDialog()
    	ui_area = Ui_dialog_gt()
    	ui_area.setupUi(AreaGT)
    	ui_area.label_area_gt.ui_area = ui_area
    	MainWindow = QtGui.QMainWindow()
    	ui = Ui_MainWindow()
    	ui.setupUi(MainWindow)
     
    	mainClass = Apply()
    	wgt          = WindowGT()
     
    	MainWindow.show()
    	sys.exit(app.exec_())
    2) Classe pour dessiner (dans labelGT.py)
    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
    class labelAreaCounting(QtGui.QGraphicsScene, QtGui.QLabel):
    
    	def __init__(self, parent = None):
    		QtGui.QLabel.__init__(self, parent)
    		QtGui.QGraphicsScene.__init__(self, parent)
    		self.createMode = 0
    		self.createState = False
                    self.defaultItem = 0
    		self.pen = QtGui.QPen(QtGui.QColor('black'))
    		self.penTemp = QtGui.QPen(QtGui.QColor('red'))
    		self.penOver = QtGui.QPen(QtGui.QColor('blue'))
    
    	def mousePressEvent(self, e):
    	def mouseReleaseEvent(self, e):
    
    	def etc... code de doof
    3) Fenetre ou je dessine (realisee avec PyQT):
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    class Ui_dialog_gt(object):
    	def setupUI(self, dialog_gt):
    	def retranslateUi(self, dialog_gt):
     
    from labelGT import labelAreaCounting
    Voila, j'espere que vous aurez compris mon code... Merci a vous !

  9. #9
    Nouveau membre du Club
    Profil pro
    Inscrit en
    Octobre 2009
    Messages
    55
    Détails du profil
    Informations personnelles :
    Âge : 36
    Localisation : France

    Informations forums :
    Inscription : Octobre 2009
    Messages : 55
    Points : 33
    Points
    33
    Par défaut
    Finalement apres plusieurs heures de galere j'ai trouve une solution

    Donc je vous la propose, ca pourra toujours en aider un ou deux, qui sait !!

    1) Interface Principale:
    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
    class Apply:
     
    	def __init__(self):
     
    		QtCore.QObject.connect( ui.pushButton_counting_area, QtCore.SIGNAL("clicked()"), self.manageAreaCounting )
     
    	def manageAreaCounting(self):
    		AreaGT.setVisible(True)
     
    if __name__ == "__main__":
    	import sys
    	app = QtGui.QApplication(sys.argv)
     
    	AreaGT = QtGui.QDialog()
    	ui_area = Ui_dialog_gt()
    	ui_area.setupUi(AreaGT)
    	ui_area.label_area_gt.ui_area = ui_area
    	MainWindow = QtGui.QMainWindow()
    	ui = Ui_MainWindow()
    	ui.setupUi(MainWindow)
     
    	mainClass = Apply()
     
    	MainWindow.show()
    	sys.exit(app.exec_())

    2) Classe pour dessiner: (il s'agit maintenant d'un objet hérité de QGraphicsView)
    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
    class graphicsviewAreaCounting(QtGui.QGraphicsView):
    
    	def __init__(self, parent = None):
    		QtGui.QGraphicsView.__init__(self, parent)
    		self.scene = MyGraphicsScene()
    		self.scene.setSceneRect( -500.0, -500.0, 1000.0, 1000.0 );
    		self.setScene(self.scene)
    		self.setRenderHints(QtGui.QPainter.Antialiasing)
    		
    		QtCore.QObject.connect( self.scene, QtCore.SIGNAL("modeChanged"), self.changeMode )
    		
    	def changeMode(self, mode):
    
    		if mode == 1: self.setDragMode(QtGui.QGraphicsView.NoDrag)
    		else: self.setDragMode(QtGui.QGraphicsView.RubberBandDrag)
    
    
    
    class MyGraphicsScene(QtGui.QGraphicsScene):
    
    	code de doof...

    3) Fenetre ou je dessine: (avec PyQT)
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    class Ui_dialog_gt(object):
    	def setupUI(self, dialog_gt): blah blah blah...
    	def retranslateUi(self, dialog_gt): blah blah blah...
     
    from graphicsviewGT import graphicsviewAreaCounting
     
    if __name__ == "__main__": blah blah blah...
    Voila voila

  10. #10
    Membre chevronné

    Profil pro
    Account Manager
    Inscrit en
    Décembre 2006
    Messages
    2 301
    Détails du profil
    Informations personnelles :
    Localisation : France, Savoie (Rhône Alpes)

    Informations professionnelles :
    Activité : Account Manager

    Informations forums :
    Inscription : Décembre 2006
    Messages : 2 301
    Points : 1 752
    Points
    1 752
    Par défaut
    Cela a l'air sympa mais j'ai voulu tester et hop je vois dans tes codes code de doof... et blah blah blah.... Un peu gênant. Ce serait super sympa de ta part de faire des copier-coller COMPLETS des codes car pour le coup je ne vais pas tester ta méthode. C'est vraiment dommage...

    PS : je t'aurais bien aidé si j'avais repris ma réflexion sur ce problème mais j'ai laissé de côté cette dernière car je suis parti sur d'autres technologies, à savoir l'utilisation du WebKit, d'applets java et de JavaScript.

  11. #11
    Nouveau membre du Club
    Profil pro
    Inscrit en
    Octobre 2009
    Messages
    55
    Détails du profil
    Informations personnelles :
    Âge : 36
    Localisation : France

    Informations forums :
    Inscription : Octobre 2009
    Messages : 55
    Points : 33
    Points
    33
    Par défaut
    Ok pas de souci, je rajoute les codes manquants. Et puis c'est vrai qu'en les relisant ce n'etait plus trop les codes de doof J'ai pas mal personnalise la solution !!

    MyGraphicsScene:
    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
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    92
    93
    94
    95
    96
    97
    98
    99
    100
    101
    102
    103
    104
    105
    106
    107
    108
    109
    110
    111
    112
    113
    114
    115
    116
    117
    118
    119
    120
    121
    122
    123
    124
    125
    126
    127
    128
    129
    130
    131
    132
    133
    134
    135
    136
    137
    138
    139
    140
    141
    142
    143
    144
    145
    146
    147
    148
    149
    150
    151
    152
    153
    154
    155
    156
    157
    158
    159
    160
    161
    162
    163
    164
    165
    166
    167
    168
    169
    170
    171
    172
    173
    174
    175
    176
    177
    178
    179
    180
    181
    182
    183
    184
    185
    186
    187
    188
    189
    190
    191
    192
    193
    194
    195
    196
    197
    198
    199
    200
    201
    202
    203
    204
    205
    206
    207
    208
    209
    210
    211
    212
    213
    214
    215
    216
    217
    218
    219
    220
    221
    222
    223
    224
    225
    226
    227
    228
    229
    230
    231
    class MyGraphicsScene(QtGui.QGraphicsScene):
     
    	__event__  = 0  # type of event: 0 (line) - 1 (rect) - 2 (poly) - 3 (move) - 4 (clear)
    	__mode__   = 0  # possible mode: 0 (edition) - 1 (creation)
    	__object__ = 1  # The object area: 1 by-default, because the QPixmap (corridor image) is an item
    	__coords__ = [] # The coords...
     
    	def __init__(self):
    		QtGui.QGraphicsScene.__init__(self)
    		self.createMode  = 0  # 0 = edition / 1 = creation
    		self.createState = False # state of the creation (mouseMoveEvent)
    		self.polyTab = []  # array containing the different points of the polygon
    		self.polyFig = MyPolygonItem(self)  # the object Polygon
    		self.pen = QtGui.QPen(QtCore.Qt.black, 2) # normal
    		self.penTemp = QtGui.QPen(QtCore.Qt.red,   2) # temporary
    		self.penOver = QtGui.QPen(QtCore.Qt.blue,  2) # hovered
     
    	def mousePressEvent(self, event):
     
    		self.swapMode()
     
    		if event.button() == QtCore.Qt.LeftButton and MyGraphicsScene.__mode__ == 1: # LMB in creation mode
     
    			if len(self.polyTab) == 0: self.polyTab.append(event.scenePos()) # the first point (departure) of the polygon
     
    			self.firstPoint  = event.scenePos()
    			self.currentItem = self.createItem()
    			self.currentItem.setPen(self.penTemp)
    			self.addItem(self.currentItem)
    			self.createState = True # creation in progress
     
    		else:
    			QtGui.QGraphicsScene.mousePressEvent(self, event) # recursion!
     
    	def createItem(self):
    		if MyGraphicsScene.__event__   == 0: return MyLineItem(self)
    		elif MyGraphicsScene.__event__ == 1: return MyRectItem(self)
    		elif MyGraphicsScene.__event__ == 2: return MyLineItem(self)
     
    	def swapMode(self):
    		self.createMode = MyGraphicsScene.__mode__
    		self.emit(QtCore.SIGNAL('modeChanged'), self.createMode) # signal => items change of flags
     
    	def mouseMoveEvent(self, event):
     
    		if self.createState:
    			if MyGraphicsScene.__event__ == 2: # resize the last line of the polygon
    				self.currentItem.resize(self.polyTab[-1], event.scenePos())
    			else:
    				self.currentItem.resize(self.firstPoint, event.scenePos())
    		else:
    			QtGui.QGraphicsScene.mouseMoveEvent(self, event) # recursion!
     
    	def mouseReleaseEvent(self, event):
     
    		if event.button() == QtCore.Qt.LeftButton and self.createState: # LMB in creation mode
     
    			if event.scenePos() == self.firstPoint: # Released point == First point
    				self.removeItem(self.currentItem)
    				del self.currentItem
     
    			else:
    				self.polyTab.append(event.scenePos())
    				self.currentItem.setPen(self.pen)
    				if MyGraphicsScene.__event__ == 2:
    					itemsWithoutQPixmap = []
    					for item in self.items():
    						if isinstance(item, QtGui.QGraphicsPixmapItem) == False:
    							itemsWithoutQPixmap.append(item)
    					map(self.removeItem, itemsWithoutQPixmap) # removing of the lines which compose the polygon but not the QPixmap
     
    					self.polyFig.resizePoly(self.polyTab)     # creation of the polygon according to the lines of polyTab
    					self.polyFig.setPen(self.penTemp)
    					self.addItem(self.polyFig)                # addition of the figure into the GraphicsScene
     
    			self.createState = False # after releasing the LMB, the item is created.
     
    			## Retrieving the coordinates of the area
    			if len(self.items()) != 2:
    				MyGraphicsScene.__object__ = 1
     
    			else:
     
    				MyGraphicsScene.__object__ = self.items()[0] # The first is the area and the second is the QPixmap
    				MyGraphicsScene.__coords__ = self.retrieveAreaCoordinates(MyGraphicsScene.__object__)
     
    		else:
    			QtGui.QGraphicsScene.mouseReleaseEvent(self, event) # recursion!
     
    	def retrieveAreaCoordinates(self, ob):
     
    		coords = []
     
    		if isinstance(MyGraphicsScene.__object__, MyLineItem):      # 2 points
     
    			# Retrieval of the gross values
    			sta = MyGraphicsScene.__object__.line().p1()
    			end = MyGraphicsScene.__object__.line().p2()
     
    			# Addition into the coords array
    			coords.append( ('start', staX, staY) )
    			coords.append( ('end'  , endX, endY) )
     
    		elif isinstance(MyGraphicsScene.__object__, MyRectItem):    # 4 points
     
    			# Retrieval of the gross values
    			topleft     = MyGraphicsScene.__object__.rect().topLeft()
    			topright    = MyGraphicsScene.__object__.rect().topRight()
    			bottomright = MyGraphicsScene.__object__.rect().bottomRight()
    			bottomleft  = MyGraphicsScene.__object__.rect().bottomLeft()
     
    			coords.append( ('topleft'    , topleftX    , topleftY     ) )
    			coords.append( ('topright'   , toprightX   , toprightY    ) )
    			coords.append( ('bottomright', bottomrightX, bottomrightY ) )
    			coords.append( ('bottomleft' , bottomleftX , bottomleftY  ) )
     
    		elif isinstance(MyGraphicsScene.__object__, MyPolygonItem): # n points
     
    			for i in range(0, len(self.polyTab)):
    				name = 'point'+str(i+1)
    				pX   = self.polyTab[i].x()
    				pY   = self.polyTab[i].y()
    				coords.append( (name, pX, pY) )
     
    		return coords
     
    	def keyPressEvent(self, event):
     
    		key = event.key()
     
    		if(key == QtCore.Qt.Key_Delete):   # del
    			self.removeSelection()
     
    		elif(key == QtCore.Qt.Key_Escape): # escape
     
    			# Removing of the object onto the GraphicsView
    			itemsWithoutQPixmap = []
    			for item in self.items():
    				if isinstance(item, QtGui.QGraphicsPixmapItem) == False:
    					itemsWithoutQPixmap.append(item)
    			map(self.removeItem, itemsWithoutQPixmap)
     
    			# Removing of the created items in memory
    			for item in self.items(): del item
     
    			# Removing of the object which has to be transmitted (like the pop() method)
    			if MyGraphicsScene.__object__ != 1: MyGraphicsScene.__object__ = 1
     
    			# Removing of the lines saved in polyTab
    			while len(self.polyTab) > 0: self.polyTab.pop()
     
    	def removeSelection(self): # del
     
    		items = self.selectedItems() # selected items
    		map(self.removeItem, items)  # argument 2 must support iteration
    		for i in items: del i
     
    		MyGraphicsScene.__object__ = len(self.items())
     
     
    ## VirtualItem
    class VirtualItem(object):
     
    	def __init__(self):
    		self.setAcceptHoverEvents(False)                          # flag for the cursor hovering
    		self.setFlag(QtGui.QGraphicsItem.ItemIsMovable, False)    # the movable item flag
    		self.setFlag(QtGui.QGraphicsItem.ItemIsSelectable, False) # the selectable item flag
     
    		self.Q = QtCore.QObject() # No multiple inheritance in PyQT => only way to emit or receive signals in an item
    		self.Q.connect(self.parent, QtCore.SIGNAL('modeChanged'), self.changeMode)
     
    	def hoverEnterEvent(self, event):
    		self.setPen(self.parent.penOver)
     
    	def hoverLeaveEvent(self, event):
    		self.setPen(self.parent.pen)
     
    	def changeMode(self, mode):
    		if mode == 1:
    			self.setAcceptHoverEvents(False)
    			self.setFlag(QtGui.QGraphicsItem.ItemIsMovable, False)
    			self.setFlag(QtGui.QGraphicsItem.ItemIsSelectable, False)
    		else:
    			self.setAcceptHoverEvents(True)
    			self.setFlag(QtGui.QGraphicsItem.ItemIsMovable, True)
    			self.setFlag(QtGui.QGraphicsItem.ItemIsSelectable, True)
     
     
     
     
     
    ## MyLineItem
    class MyLineItem(QtGui.QGraphicsLineItem, VirtualItem):
     
    	def __init__(self, parent = None):
    		QtGui.QGraphicsLineItem.__init__(self)
    		self.parent = parent # ref on the parent to link the signal
    		VirtualItem.__init__(self)
     
    	def resize(self, p1, p2):
    		self.setLine(QtCore.QLineF(p1, p2))
     
     
     
     
     
    ## MyRectItem
    class MyRectItem(QtGui.QGraphicsRectItem, VirtualItem):
     
    	def __init__(self, parent = None):
    		QtGui.QGraphicsRectItem.__init__(self)
    		self.parent = parent # ref on the parent to link the signal
    		VirtualItem.__init__(self)
     
    	def resize(self, p1, p2):
    		self.setRect(QtCore.QRectF(p1, p2))
     
     
     
     
     
    ## MyPolygonItem
    class MyPolygonItem(QtGui.QGraphicsPolygonItem, VirtualItem):
     
    	def __init__(self, parent = None):
    		QtGui.QGraphicsPolygonItem.__init__(self)
    		self.parent = parent # ref on the parent to link the signal
    		VirtualItem.__init__(self)
     
    	def resizePoly(self, polyTab):
    		self.setPolygon(QtGui.QPolygonF(polyTab))
    Comme tu peux voir je peux dessiner une ligne, un rectangle ou un polygone de plusieurs lignes. A chaque fois que je dessine un polygone les items presents dans ma scene sont supprimes (sauf le QPixmap qui est une image de fond avec des reperes).

    Ensuite je peux recuperer les coordonnees des points selon le type de l'item.

    Et maintenant le code remplacant le "blah blah blah...", mais c'est 'juste' une interface graphique que j'ai faite avec PyQT:

    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
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    92
    93
    94
    95
    96
    97
    98
    99
    100
    101
    102
    103
    104
    105
    106
    107
    108
    109
    110
    111
    112
    113
    114
    115
    116
    117
    118
    119
    120
    121
    122
    123
    124
    125
    126
    127
    128
    129
    130
    131
    132
    133
    134
    135
    136
    137
    138
    139
    140
    141
    142
    143
    144
    145
    146
    147
    148
    149
    150
    151
    152
    153
    154
    155
    156
    157
    158
    159
    160
    161
    162
    163
    164
    165
    166
    167
    168
    169
    170
    171
    172
    173
    174
    175
    176
    177
    178
    179
    180
    181
    182
    183
    184
    185
    186
    187
    188
    189
    190
    191
    192
    193
    194
    195
    196
    197
    198
    199
    200
    201
    202
    203
    204
    205
    206
    207
    208
    209
    210
    211
    212
    213
    214
    215
    216
    217
    218
    219
    220
    221
    222
    223
    224
    225
    226
    227
    228
    229
    230
    231
    232
    233
    234
    235
    236
    237
    238
    239
    # -*- coding: utf-8 -*-
     
    # Form implementation generated from reading ui file 'area_groundtruth.ui'
    #
    # Created: Mon Jun 07 16:26:12 2010
    #      by: PyQt4 UI code generator 4.7.3
    #
    # WARNING! All changes made in this file will be lost!
     
    from PyQt4 import QtCore, QtGui
     
    class Ui_dialog_groundtruth(object):
        def setupUi(self, dialog_groundtruth):
            dialog_groundtruth.setObjectName("dialog_groundtruth")
            dialog_groundtruth.resize(839, 648)
            self.pushButton_save_area = QtGui.QPushButton(dialog_groundtruth)
            self.pushButton_save_area.setGeometry(QtCore.QRect(195, 600, 75, 23))
            self.pushButton_save_area.setObjectName("pushButton_save_area")
            self.graphicsView_area_groundtruth = graphicsviewAreaCounting(dialog_groundtruth)
            self.graphicsView_area_groundtruth.setGeometry(QtCore.QRect(30, 50, 522, 522))
            self.graphicsView_area_groundtruth.setProperty("cursor", QtCore.Qt.CrossCursor)
            self.graphicsView_area_groundtruth.setMouseTracking(False)
            self.graphicsView_area_groundtruth.setAutoFillBackground(False)
            self.graphicsView_area_groundtruth.setFrameShape(QtGui.QFrame.StyledPanel)
            self.graphicsView_area_groundtruth.setFrameShadow(QtGui.QFrame.Sunken)
            self.graphicsView_area_groundtruth.setVerticalScrollBarPolicy(QtCore.Qt.ScrollBarAlwaysOff)
            self.graphicsView_area_groundtruth.setHorizontalScrollBarPolicy(QtCore.Qt.ScrollBarAlwaysOff)
            self.graphicsView_area_groundtruth.setInteractive(True)
            self.graphicsView_area_groundtruth.setSceneRect(QtCore.QRectF(0.0, 0.0, 522.0, 522.0))
            self.graphicsView_area_groundtruth.setRenderHints(QtGui.QPainter.TextAntialiasing)
            self.graphicsView_area_groundtruth.setObjectName("graphicsView_area_groundtruth")
            self.pushButton_cancel = QtGui.QPushButton(dialog_groundtruth)
            self.pushButton_cancel.setGeometry(QtCore.QRect(290, 600, 75, 23))
            self.pushButton_cancel.setObjectName("pushButton_cancel")
            self.toolButton_line = QtGui.QToolButton(dialog_groundtruth)
            self.toolButton_line.setEnabled(False)
            self.toolButton_line.setGeometry(QtCore.QRect(580, 180, 71, 51))
            self.toolButton_line.setObjectName("toolButton_line")
            self.buttonGroup_choice = QtGui.QButtonGroup(dialog_groundtruth)
            self.buttonGroup_choice.setObjectName("buttonGroup_choice")
            self.buttonGroup_choice.addButton(self.toolButton_line)
            self.toolButton_rect = QtGui.QToolButton(dialog_groundtruth)
            self.toolButton_rect.setGeometry(QtCore.QRect(660, 180, 71, 51))
            self.toolButton_rect.setObjectName("toolButton_rect")
            self.buttonGroup_choice.addButton(self.toolButton_rect)
            self.toolButton_poly = QtGui.QToolButton(dialog_groundtruth)
            self.toolButton_poly.setEnabled(False)
            self.toolButton_poly.setGeometry(QtCore.QRect(740, 180, 71, 51))
            self.toolButton_poly.setObjectName("toolButton_poly")
            self.buttonGroup_choice.addButton(self.toolButton_poly)
            self.toolButton_move = QtGui.QToolButton(dialog_groundtruth)
            self.toolButton_move.setGeometry(QtCore.QRect(660, 290, 71, 51))
            self.toolButton_move.setObjectName("toolButton_move")
            self.buttonGroup_choice.addButton(self.toolButton_move)
            self.label_title = QtGui.QLabel(dialog_groundtruth)
            self.label_title.setGeometry(QtCore.QRect(630, 30, 131, 31))
            font = QtGui.QFont()
            font.setPointSize(12)
            font.setWeight(75)
            font.setUnderline(True)
            font.setBold(True)
            self.label_title.setFont(font)
            self.label_title.setFrameShape(QtGui.QFrame.NoFrame)
            self.label_title.setAlignment(QtCore.Qt.AlignCenter)
            self.label_title.setObjectName("label_title")
            self.label_action = QtGui.QLabel(dialog_groundtruth)
            self.label_action.setGeometry(QtCore.QRect(620, 80, 151, 31))
            font = QtGui.QFont()
            font.setPointSize(10)
            font.setWeight(75)
            font.setItalic(False)
            font.setBold(True)
            self.label_action.setFont(font)
            self.label_action.setFrameShape(QtGui.QFrame.StyledPanel)
            self.label_action.setFrameShadow(QtGui.QFrame.Plain)
            self.label_action.setLineWidth(0)
            self.label_action.setMidLineWidth(0)
            self.label_action.setAlignment(QtCore.Qt.AlignCenter)
            self.label_action.setObjectName("label_action")
            self.label_instructions = QtGui.QLabel(dialog_groundtruth)
            self.label_instructions.setGeometry(QtCore.QRect(630, 390, 131, 31))
            font = QtGui.QFont()
            font.setPointSize(12)
            font.setWeight(75)
            font.setUnderline(True)
            font.setBold(True)
            self.label_instructions.setFont(font)
            self.label_instructions.setFrameShape(QtGui.QFrame.NoFrame)
            self.label_instructions.setAlignment(QtCore.Qt.AlignCenter)
            self.label_instructions.setObjectName("label_instructions")
            self.line_1 = QtGui.QFrame(dialog_groundtruth)
            self.line_1.setEnabled(True)
            self.line_1.setGeometry(QtCore.QRect(580, 140, 231, 20))
            font = QtGui.QFont()
            font.setWeight(50)
            font.setBold(False)
            self.line_1.setFont(font)
            self.line_1.setToolTip("")
            self.line_1.setFrameShadow(QtGui.QFrame.Sunken)
            self.line_1.setLineWidth(1)
            self.line_1.setMidLineWidth(0)
            self.line_1.setFrameShape(QtGui.QFrame.HLine)
            self.line_1.setFrameShadow(QtGui.QFrame.Sunken)
            self.line_1.setObjectName("line_1")
            self.line_2 = QtGui.QFrame(dialog_groundtruth)
            self.line_2.setEnabled(True)
            self.line_2.setGeometry(QtCore.QRect(580, 250, 231, 20))
            font = QtGui.QFont()
            font.setWeight(50)
            font.setBold(False)
            self.line_2.setFont(font)
            self.line_2.setToolTip("")
            self.line_2.setFrameShadow(QtGui.QFrame.Sunken)
            self.line_2.setLineWidth(1)
            self.line_2.setMidLineWidth(0)
            self.line_2.setFrameShape(QtGui.QFrame.HLine)
            self.line_2.setFrameShadow(QtGui.QFrame.Sunken)
            self.line_2.setObjectName("line_2")
            self.line_3 = QtGui.QFrame(dialog_groundtruth)
            self.line_3.setEnabled(True)
            self.line_3.setGeometry(QtCore.QRect(580, 360, 231, 20))
            font = QtGui.QFont()
            font.setWeight(50)
            font.setBold(False)
            self.line_3.setFont(font)
            self.line_3.setToolTip("")
            self.line_3.setFrameShadow(QtGui.QFrame.Sunken)
            self.line_3.setLineWidth(1)
            self.line_3.setMidLineWidth(0)
            self.line_3.setFrameShape(QtGui.QFrame.HLine)
            self.line_3.setFrameShadow(QtGui.QFrame.Sunken)
            self.line_3.setObjectName("line_3")
            self.label_creation_sentence = QtGui.QLabel(dialog_groundtruth)
            self.label_creation_sentence.setGeometry(QtCore.QRect(625, 450, 181, 16))
            font = QtGui.QFont()
            font.setUnderline(False)
            self.label_creation_sentence.setFont(font)
            self.label_creation_sentence.setObjectName("label_creation_sentence")
            self.label_moving_sentence = QtGui.QLabel(dialog_groundtruth)
            self.label_moving_sentence.setGeometry(QtCore.QRect(625, 480, 211, 16))
            font = QtGui.QFont()
            font.setUnderline(False)
            self.label_moving_sentence.setFont(font)
            self.label_moving_sentence.setObjectName("label_moving_sentence")
            self.label_creation_title = QtGui.QLabel(dialog_groundtruth)
            self.label_creation_title.setGeometry(QtCore.QRect(555, 447, 61, 20))
            font = QtGui.QFont()
            font.setPointSize(9)
            font.setWeight(50)
            font.setUnderline(True)
            font.setBold(False)
            self.label_creation_title.setFont(font)
            self.label_creation_title.setAlignment(QtCore.Qt.AlignRight|QtCore.Qt.AlignTrailing|QtCore.Qt.AlignVCenter)
            self.label_creation_title.setObjectName("label_creation_title")
            self.label_moving_title = QtGui.QLabel(dialog_groundtruth)
            self.label_moving_title.setGeometry(QtCore.QRect(555, 477, 61, 20))
            font = QtGui.QFont()
            font.setPointSize(9)
            font.setUnderline(True)
            self.label_moving_title.setFont(font)
            self.label_moving_title.setAlignment(QtCore.Qt.AlignRight|QtCore.Qt.AlignTrailing|QtCore.Qt.AlignVCenter)
            self.label_moving_title.setObjectName("label_moving_title")
            self.label_deletion_title = QtGui.QLabel(dialog_groundtruth)
            self.label_deletion_title.setGeometry(QtCore.QRect(555, 507, 61, 20))
            font = QtGui.QFont()
            font.setPointSize(9)
            font.setWeight(50)
            font.setUnderline(True)
            font.setBold(False)
            self.label_deletion_title.setFont(font)
            self.label_deletion_title.setAlignment(QtCore.Qt.AlignRight|QtCore.Qt.AlignTrailing|QtCore.Qt.AlignVCenter)
            self.label_deletion_title.setObjectName("label_deletion_title")
            self.label_deletion_sentence_1 = QtGui.QLabel(dialog_groundtruth)
            self.label_deletion_sentence_1.setGeometry(QtCore.QRect(625, 510, 211, 16))
            font = QtGui.QFont()
            font.setUnderline(False)
            self.label_deletion_sentence_1.setFont(font)
            self.label_deletion_sentence_1.setObjectName("label_deletion_sentence_1")
            self.label_deletion_sentence_2 = QtGui.QLabel(dialog_groundtruth)
            self.label_deletion_sentence_2.setGeometry(QtCore.QRect(625, 530, 231, 16))
            font = QtGui.QFont()
            font.setUnderline(False)
            self.label_deletion_sentence_2.setFont(font)
            self.label_deletion_sentence_2.setObjectName("label_deletion_sentence_2")
            self.label_direction = QtGui.QLabel(dialog_groundtruth)
            self.label_direction.setGeometry(QtCore.QRect(150, 15, 91, 20))
            font = QtGui.QFont()
            font.setWeight(75)
            font.setUnderline(True)
            font.setBold(True)
            self.label_direction.setFont(font)
            self.label_direction.setAlignment(QtCore.Qt.AlignRight|QtCore.Qt.AlignTrailing|QtCore.Qt.AlignVCenter)
            self.label_direction.setObjectName("label_direction")
            self.comboBox_direction = QtGui.QComboBox(dialog_groundtruth)
            self.comboBox_direction.setGeometry(QtCore.QRect(250, 15, 141, 22))
            self.comboBox_direction.setObjectName("comboBox_direction")
            self.comboBox_direction.addItem("")
            self.comboBox_direction.addItem("")
            self.comboBox_direction.addItem("")
            self.comboBox_direction.addItem("")
     
            self.retranslateUi(dialog_groundtruth)
            QtCore.QObject.connect(self.pushButton_cancel, QtCore.SIGNAL("clicked()"), dialog_groundtruth.close)
            QtCore.QMetaObject.connectSlotsByName(dialog_groundtruth)
     
        def retranslateUi(self, dialog_groundtruth):
            dialog_groundtruth.setWindowTitle(QtGui.QApplication.translate("dialog_groundtruth", "Area Counting", None, QtGui.QApplication.UnicodeUTF8))
            self.pushButton_save_area.setText(QtGui.QApplication.translate("dialog_groundtruth", "Save Area", None, QtGui.QApplication.UnicodeUTF8))
            self.pushButton_cancel.setText(QtGui.QApplication.translate("dialog_groundtruth", "Cancel", None, QtGui.QApplication.UnicodeUTF8))
            self.toolButton_line.setText(QtGui.QApplication.translate("dialog_groundtruth", "Line", None, QtGui.QApplication.UnicodeUTF8))
            self.toolButton_rect.setText(QtGui.QApplication.translate("dialog_groundtruth", "Rect", None, QtGui.QApplication.UnicodeUTF8))
            self.toolButton_poly.setText(QtGui.QApplication.translate("dialog_groundtruth", "Poly", None, QtGui.QApplication.UnicodeUTF8))
            self.toolButton_move.setText(QtGui.QApplication.translate("dialog_groundtruth", "Move", None, QtGui.QApplication.UnicodeUTF8))
            self.label_title.setText(QtGui.QApplication.translate("dialog_groundtruth", "Current Action", None, QtGui.QApplication.UnicodeUTF8))
            self.label_action.setText(QtGui.QApplication.translate("dialog_groundtruth", "nothing", None, QtGui.QApplication.UnicodeUTF8))
            self.label_instructions.setText(QtGui.QApplication.translate("dialog_groundtruth", "Instructions", None, QtGui.QApplication.UnicodeUTF8))
            self.label_creation_sentence.setText(QtGui.QApplication.translate("dialog_groundtruth", "select an object and draw it (LMB)", None, QtGui.QApplication.UnicodeUTF8))
            self.label_moving_sentence.setText(QtGui.QApplication.translate("dialog_groundtruth", "select a blue object and move it (LMB)", None, QtGui.QApplication.UnicodeUTF8))
            self.label_creation_title.setText(QtGui.QApplication.translate("dialog_groundtruth", "Creation:", None, QtGui.QApplication.UnicodeUTF8))
            self.label_moving_title.setText(QtGui.QApplication.translate("dialog_groundtruth", "Moving:", None, QtGui.QApplication.UnicodeUTF8))
            self.label_deletion_title.setText(QtGui.QApplication.translate("dialog_groundtruth", "Deletion:", None, QtGui.QApplication.UnicodeUTF8))
            self.label_deletion_sentence_1.setText(QtGui.QApplication.translate("dialog_groundtruth", "One: select it (LMB) and click on \'del\'", None, QtGui.QApplication.UnicodeUTF8))
            self.label_deletion_sentence_2.setText(QtGui.QApplication.translate("dialog_groundtruth", "All   : select them (LMB) and click on \'esc\'", None, QtGui.QApplication.UnicodeUTF8))
            self.label_direction.setText(QtGui.QApplication.translate("dialog_groundtruth", "Direction:", None, QtGui.QApplication.UnicodeUTF8))
            self.comboBox_direction.setItemText(0, QtGui.QApplication.translate("dialog_groundtruth", "from bottom to top", None, QtGui.QApplication.UnicodeUTF8))
            self.comboBox_direction.setItemText(1, QtGui.QApplication.translate("dialog_groundtruth", "from top to bottom", None, QtGui.QApplication.UnicodeUTF8))
            self.comboBox_direction.setItemText(2, QtGui.QApplication.translate("dialog_groundtruth", "from left to right", None, QtGui.QApplication.UnicodeUTF8))
            self.comboBox_direction.setItemText(3, QtGui.QApplication.translate("dialog_groundtruth", "from right to left", None, QtGui.QApplication.UnicodeUTF8))
     
    from graphicsviewGroundTruth import graphicsviewAreaCounting
     
    if __name__ == "__main__":
        import sys
        app = QtGui.QApplication(sys.argv)
        dialog_groundtruth = QtGui.QDialog()
        ui = Ui_dialog_groundtruth()
        ui.setupUi(dialog_groundtruth)
        dialog_groundtruth.show()
        sys.exit(app.exec_())

    Voila voila, dis-moi si tout marche bien ou si tu as des questions

  12. #12
    Membre chevronné

    Profil pro
    Account Manager
    Inscrit en
    Décembre 2006
    Messages
    2 301
    Détails du profil
    Informations personnelles :
    Localisation : France, Savoie (Rhône Alpes)

    Informations professionnelles :
    Activité : Account Manager

    Informations forums :
    Inscription : Décembre 2006
    Messages : 2 301
    Points : 1 752
    Points
    1 752
    Par défaut
    Citation Envoyé par pacolito
    Voila voila, dis-moi si tout marche bien ou si tu as des questions
    Tu as le droit de me trouver chiant mais en l'état tu ne nous proposes pas un exemple autonome.

    Je projette depuis un moment de faire un tuto. sur PyQt qui pourrait figurer sur ce site. Même si mon utilisation de PyQt reste très spécifique, je pense que certaines techniques que j'utilise comme la communication entre un JavaScript et le WebKit, ou la création de nouveaux lexers pour QScintilla, pourraient être utiles à d'autres.

    Tout ceci pour te dire que je me baserais bien sur ta solution pour expliquer l'interactivité avec un QGraphicsScene, bien entendu en citant ce post. C'est pour cela que j'insiste pour avoir une solution autonome ici, c'est à dire un fichier principal et celui de l'interface prêts à l'emploi.

    Si tu as le temps, ce serait super que tu fasses cela.

  13. #13
    Nouveau membre du Club
    Profil pro
    Inscrit en
    Octobre 2009
    Messages
    55
    Détails du profil
    Informations personnelles :
    Âge : 36
    Localisation : France

    Informations forums :
    Inscription : Octobre 2009
    Messages : 55
    Points : 33
    Points
    33
    Par défaut
    Aucun souci pour donner un peu de temps pour ce que tu souhaite

    Le seul souci c'est que l'interface dans laquelle je dessine mes formes (appelons la B) est dependante d'une autre interface (appelons la A): en effet je lance B depuis A, je dessine dans B, et quand je valide je recupere les objets et leurs coordonnees dans A.

    Du coup si tu veux tout le code il faudrait que je t'envoie toutes mes classes avec les interfaces et tout. Mais je ne suis pas sur que ce soit ce que tu veux !! Je n'ai pas trop bien compris ce que tu voulais montrer... (WebKit, lexers, QScintilla = 3 mots que j'ai deja entendu mais dont je ne connais rien !!)

    Il te faudrait un exemple de comment dessiner dans une interface ? de comment recuperer les donnees entre 2 interfaces ? En m'expliquant plus lentement je pense y arriver a comprendre ce que tu veux

  14. #14
    Membre chevronné

    Profil pro
    Account Manager
    Inscrit en
    Décembre 2006
    Messages
    2 301
    Détails du profil
    Informations personnelles :
    Localisation : France, Savoie (Rhône Alpes)

    Informations professionnelles :
    Activité : Account Manager

    Informations forums :
    Inscription : Décembre 2006
    Messages : 2 301
    Points : 1 752
    Points
    1 752
    Par défaut
    Ok, allons-y. Ce qui m'intéresse dans ta découverte c'est comment tu travailles dans le QLabel, et aussi les différentes communications. Pour faire simple, ce serait sympa de proposer quelque chose qui mette en valeur ce qu'apporte ta solution.

    Au pire, tes modules envoyés par mail pourraient aussi convenir sauf si ton projet est monstrueux.

    Pour les mots ésotériques, il faut juste savoir que QScintilla permet de faire la coloration syntaxique sous PyQt, et que le QWebKit permet d'avoir une page HTML au sein d'une interface PyQt.

  15. #15
    Nouveau membre du Club
    Profil pro
    Inscrit en
    Octobre 2009
    Messages
    55
    Détails du profil
    Informations personnelles :
    Âge : 36
    Localisation : France

    Informations forums :
    Inscription : Octobre 2009
    Messages : 55
    Points : 33
    Points
    33
    Par défaut
    D'accord, donc si j'ai bien compris le principal c'est d'apprendre des choses aux gens, un tutoriel quoi Du coup l'important serait de mettre l'accent sur les points cles, donc mettre en lumiere les problemes que j'ai eu. C'est ca ?

    Par contre, la solution que j'ai actuellement permet a l'utilisateur de dessiner dans un QGraphicsView et non un QLabel. Mais j'avais commence par un QLabel, la difference n'est pas grande.

    Concernant mon projet il est assez consequent oui, je vais essayer de synthetiser tout ca

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

Discussions similaires

  1. Bouger image avec clavier souris + zoom avec molette
    Par yggdrasylv dans le forum Interfaces Graphiques en Java
    Réponses: 4
    Dernier message: 03/03/2009, 00h02
  2. Bouger le curseur de souris automatiquement
    Par care dans le forum Delphi
    Réponses: 10
    Dernier message: 13/03/2007, 23h04
  3. [c#] ouvrir le menu demarrer et bouger la souris
    Par zedine dans le forum Windows Forms
    Réponses: 4
    Dernier message: 24/02/2006, 18h05
  4. bouger une div selon les coordonnées de la souris
    Par 10-nice dans le forum Général JavaScript
    Réponses: 12
    Dernier message: 21/09/2005, 15h31
  5. Réponses: 2
    Dernier message: 05/07/2005, 17h40

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