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 :

Récupération des coordonnées du pointeur


Sujet :

PyQt Python

  1. #1
    Membre averti
    Profil pro
    Inscrit en
    Octobre 2009
    Messages
    55
    Détails du profil
    Informations personnelles :
    Âge : 38
    Localisation : France

    Informations forums :
    Inscription : Octobre 2009
    Messages : 55
    Par défaut Récupération des coordonnées du pointeur
    Bonjour a tous,

    je fais face a un probleme de recuperation des coordonnees de la souris lorsque je clique sur un Widget et je tourne en rond...

    Je vais tenter d'etre clair et precis:

    1) J'ai une interface graphique "principale" avec un bouton 'Position', et lorsque je clique sur ce bouton, cela m'ouvre un QDialog, dans lequel j'ai insere un QLabel.

    2) Mon but est de recuperer les coordonnees de la souris par rapport a ce QLabel, lorsque je clique sur ce QLabel.



    Dans l'API Qt (http://qt.developpez.com/doc/latest/qmouseevent.html#x) il y a cette methode suivante:
    int QMouseEvent:: x () const

    Returns the x position of the mouse cursor, relative to the widget that received the event.

    See also y() and pos().
    C'est exactement ce que je veux, mais le probleme est que lorsque je clique il ne se passe rien, et lorsque mon QDialog s'ouvre j'obtiens les coordonnees du QLabel par rapport au QDialog !!



    Dans le __init__ de mon application (pushButton_position est le bouton sur lequel je clique pour ouvrir ma boite de dialogue:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
    QtCore.QObject.connect( ui.pushButton_position, QtCore.SIGNAL("clicked()"), self.managePositionCamera )
    La methode liee au bouton precedent:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
     
    def managePositionCamera(self):
     
    	PosCamera.setVisible(True)
    	ui_pos.label_locationXY.setMouseTracking(True)
     
    	print 'X =',pt.x()
    	print 'Y =',pt.y()


    Mon erreur doit surement venir du fait que je n'applique pas la methode au QLabel directement, mais les signaux proposes par QT concernant un QLabel ne correspondent pas a un clic dessus (par exemple clicked() comme pour un bouton...

    En esperant que vous m'avez compris, merci par avance

  2. #2
    Membre éprouvé
    Inscrit en
    Avril 2010
    Messages
    99
    Détails du profil
    Informations personnelles :
    Âge : 43

    Informations forums :
    Inscription : Avril 2010
    Messages : 99
    Par défaut
    Tu peux créer une classe qui hérite de QLabel et où tu redéfinis la méthode mousePressEvent.
    http://qt.developpez.com/doc/latest/...ousePressEvent

    Cette méthode sera appelée lorsque tu cliqueras sur le label.

  3. #3
    Membre averti
    Profil pro
    Inscrit en
    Octobre 2009
    Messages
    55
    Détails du profil
    Informations personnelles :
    Âge : 38
    Localisation : France

    Informations forums :
    Inscription : Octobre 2009
    Messages : 55
    Par défaut
    D'accord je saisi le concept, mais etant debutant en Python je ne vois pas trop comment implementer tout ca

    Tu pourrais m'indiquer en gros l' "architecture" ?? Avec l'heritage notamment, et que faut-il que je mette dans le __init__ de ma nouvelle classe ?? Et ensuite je l'appelle comment cette nouvelle classe ??

    J'en demande beaucoup mais je vais chercher aussi de mon cote... ca m'aidera pour apprendre !!

  4. #4
    Membre éprouvé
    Inscrit en
    Avril 2010
    Messages
    99
    Détails du profil
    Informations personnelles :
    Âge : 43

    Informations forums :
    Inscription : Avril 2010
    Messages : 99
    Par défaut
    Voici un exemple minimaliste.
    Lorsque tu cliques sur le label, ça écrit les coordonnées du clic dans la sortie standard.

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
     
    class MonLabel(QLabel):
        def mousePressEvent(self, event):
            print event.x(), event.y()
    Ce n'est pas obligé à priori de redéfinir le constructeur __init__ à moins que tu veuilles que ton label ai accès à d'autres objets.

    Pour utiliser ça dans ton code, à l'endroit où tu crées ton label, tu remplaces (par exemple, je ne connais pas ton code)
    par Précise moi si tu te sers de QDesigner pour faire ton interface graphique car dans ce cas, il y a des manières élégantes de faire ça.

    Sinon juste un détail.
    Je vois que tu as écrit ça:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    tCore.QObject.connect( ui.pushButton_position, QtCore.SIGNAL("clicked()"), self.managePositionCamera )
    Depuis un des dernières versions de PyQt (>= 4.6 je crois), tu peux utiliser la syntaxe bien plus pythonesque suivante:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    ui.pushButton_position.clicked.connect(self.managePositionCamera )

  5. #5
    Membre averti
    Profil pro
    Inscrit en
    Octobre 2009
    Messages
    55
    Détails du profil
    Informations personnelles :
    Âge : 38
    Localisation : France

    Informations forums :
    Inscription : Octobre 2009
    Messages : 55
    Par défaut
    Ah oui ca n'a pas l'air si complique que ca finalement !!

    Juste pour te repondre j'utilise bien QDesigner et donc ce n'est pas moi qui defini le QLabel, et donc pour l'utiliser je fais un ui.label.setText(...) par exemple. Du coup comment puis-je lui dire que c'est un MonLabel et non pas un QLabel ??


    ps: merci pour cette nouvelle syntaxe, elle marche tres bien et est plus rapide a ecrire mais j'aime bien l' "ancienne" ou l'on voit bien le SIGNAL et la structure du connect

  6. #6
    Membre éprouvé
    Inscrit en
    Avril 2010
    Messages
    99
    Détails du profil
    Informations personnelles :
    Âge : 43

    Informations forums :
    Inscription : Avril 2010
    Messages : 99
    Par défaut
    Pour Designer, tu peux cliquer droit sur le widget qui t'intéresse et choisir "Promote To". Là, tu nommes le widget qui tu veux obtenir (ici MonLabel) et tu mets par exemple monlabel.h comme fichier d'entête.
    Le widget sera maintenant considéré comme du type MonLabel.

    Pour que ça marche, il faut essayer déplacer la définition de ta classe MonLabel dans un fichier monlabel.py.

  7. #7
    Membre averti
    Profil pro
    Inscrit en
    Octobre 2009
    Messages
    55
    Détails du profil
    Informations personnelles :
    Âge : 38
    Localisation : France

    Informations forums :
    Inscription : Octobre 2009
    Messages : 55
    Par défaut
    J'ai fait tout ce que tu m'as dit et ca marche, j'obtiens bien les coordonnees des clics exclusivement dans mon QLabel.

    Le seul probleme (eh oui encore et toujours ) est qu'il me dit que ma methode n'a qu'un seul argument (self).

    Je n'ai pas defini le parametre 'event'... mais comment le definir ?? Je l'ai defini en tant que QEvent mais ca ne marche pas !!

  8. #8
    Membre éprouvé
    Inscrit en
    Avril 2010
    Messages
    99
    Détails du profil
    Informations personnelles :
    Âge : 43

    Informations forums :
    Inscription : Avril 2010
    Messages : 99
    Par défaut
    Je ne comprends pas trop ce que tu veux dire, tu pourrais faire voir ton code, s'il te plait ?

  9. #9
    Membre averti
    Profil pro
    Inscrit en
    Octobre 2009
    Messages
    55
    Détails du profil
    Informations personnelles :
    Âge : 38
    Localisation : France

    Informations forums :
    Inscription : Octobre 2009
    Messages : 55
    Par défaut
    Finalement ca marche !! J'avais un peu de pollution autour de mon code et en ecrivant ce message j'ai tout bien nettoye Et ca marche !!

    Enfin j'ai encore un dernier probleme... j'aimerais recuperer les valeurs x et y, donc le event.x() et event.y(). Pour cela j'ai le code suivant:


    Le code de mon nouveau Label:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
     
    from PyQt4 import QtCore, QtGui
     
    class labelPosCam(QtGui.QLabel):
     
    	def mousePressEvent(self, event):
    		X = event.x()
    		Y = event.y()
    		print 'X =',X
    		print 'Y =',Y
    		return (X, Y)


    Ensuite le code d'ou j'appelle l'action sur mon bouton:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
     
    class Apply:
     
    	def __init__(self):
     
    		QtCore.QObject.connect( ui.pushButton_position, QtCore.SIGNAL("clicked()"), self.managePositionCamera )


    Et pour finir ma methode managePositionCamera:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
     
    def managePositionCamera(self):
     
    	(x, y) = ui_pos.label_locationXY.mousePressEvent()


    L'erreur que j'obtiens c'est:
    TypeError: invalid result type from labelPosCam.mousePressEvent()

    Je n'ai pas defini le 'event' c'est peut-etre pour ca, mais je ne sais pas comment le definir !?

  10. #10
    Membre éprouvé
    Inscrit en
    Avril 2010
    Messages
    99
    Détails du profil
    Informations personnelles :
    Âge : 43

    Informations forums :
    Inscription : Avril 2010
    Messages : 99
    Par défaut
    La méthode mousePressEvent n'est pas destinée à être appelée directement par le programmeur.

    Tu mets dans cette méthode ce que tu veux qu'il se passe quand l'utilisateur cliquera sur le label.
    Tu n'as rien à faire de plus.

    Donc si j'ai bien compris ce que tu voulais, ce qui tu voulais mettre dans managePositionCamera, tu le mets dans mousePressEvent.

  11. #11
    Membre averti
    Profil pro
    Inscrit en
    Octobre 2009
    Messages
    55
    Détails du profil
    Informations personnelles :
    Âge : 38
    Localisation : France

    Informations forums :
    Inscription : Octobre 2009
    Messages : 55
    Par défaut
    Pour l'appel de la methode mousePressEvent je m'en suis bien rendu compte. Je ne l'appelle plus et n'ai donc plus d'erreur bizarre

    Du coup j'implemente ma methode mousePressEvent mais je n'arrive pas a interagir avec les QLabel appartenant au meme QDialog que le QLabel sur lequel je clique !!

    Pour mieux me faire comprendre, un petit bout de code . Mon programme principal pour commencer:

    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_position, QtCore.SIGNAL("clicked()"), self.managePositionCamera    )
     
    	def managePositionCamera(self):
    		PosCamera.setVisible(True)
     
     
    if __name__ == "__main__":
    	import sys
    	app = QtGui.QApplication(sys.argv)
     
    	PosCamera = QtGui.QDialog()
    	ui_pos = Ui_dialog_position()
    	ui_pos.setupUi(PosCamera)
     
    	MainWindow = QtGui.QMainWindow()
    	ui = Ui_MainWindow()
    	ui.setupUi(MainWindow)
     
    	mcs = Apply()	
    	MainWindow.show()
    	sys.exit(app.exec_())


    Et maintenant la classe ou je redefinis ma methode mousePressEvent, qui se trouve dans un autre fichier .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
     
    from PyQt4 import QtCore, QtGui
     
    class labelPosXYCam(QtGui.QLabel):
     
    	def mousePressEvent(self, event):
     
    		X = event.x()
    		Y = event.y()
    		print 'X posXY =',X
    		print 'Y posXY =',Y
     
    		# implementer ici tout ce que j'aimerais faire...
    		# par exemple:
    		# ui_pos.label_resultat.setText(str(X, Y))
    		# avec label_resultat un QLabel ou j'aimerais afficher les coordonnees du point ou je clique !


    Et donc comme tu m'as dit, tout ce que je voulais faire dans la methode managePositionCamera, je le mets maintenant dans mousePressEvent.

    Le probleme est que depuis le premier fichier, j'ai acces aux objets de ui_pos (des QLabel notamment) que j'aimerais modifier, alors que depuis le fichier ou se trouve ma methode mousePressEvent je n'y ai pas acces !! Du coup comment puis-je les modifier ??

    J'ai essaye de faire des import mais aucun succes... pas du faire les bons

  12. #12
    Membre éprouvé
    Inscrit en
    Avril 2010
    Messages
    99
    Détails du profil
    Informations personnelles :
    Âge : 43

    Informations forums :
    Inscription : Avril 2010
    Messages : 99
    Par défaut
    Tu peux rajouter ta fenêtre principale comme attribut de ton label.

    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
    if __name__ == "__main__":
    	import sys
    	app = QtGui.QApplication(sys.argv)
     
    	PosCamera = QtGui.QDialog()
    	ui_pos = Ui_dialog_position()
    	ui_pos.setupUi(PosCamera)
            ui_pos.label_locationXY.ui_pos = ui_pos
    
    	MainWindow = QtGui.QMainWindow()
    	ui = Ui_MainWindow()
    	ui.setupUi(MainWindow)
    	
    	mcs = Apply()	
    	MainWindow.show()
    	sys.exit(app.exec_())
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    class labelPosXYCam(QtGui.QLabel):
     
    	def mousePressEvent(self, event):
    		x = event.x()
    		y = event.y() 
                    self.ui_pos.label_resultat.setText(str(x, y))
    		# implementer ici tout ce que j'aimerais faire...
    		# par exemple:
    		# ui_pos.label_resultat.setText(str(X, Y))


    sinon, autre chose.

    Au lieu de faire ça
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
     
            PosCamera = QtGui.QDialog()
    	ui_pos = Ui_dialog_position()
    	ui_pos.setupUi(PosCamera)
    tu peux faire simplement ça
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
             PosCamera = uic.loadUi("interface.ui")  # tu remplaces interface.ui par le nom de ton interface
    Je ne sais pas si tu te sers de pyuic4 pour générer du python à partir de ton fichier ui mais ça sert à rien depuis les dernières versions de PyQt.


    Encore autre chose, pour les conventions de notation, il est bien que
    - les noms de classes commencent par une majuscule
    - les noms de variables, attributs, fonctions commencent par une minuscule

    Pour plus de détails, voir à
    http://www.python.org/dev/peps/pep-0008/
    à la partie Naming Convention (le reste de la page est utile par ailleurs).

  13. #13
    Membre averti
    Profil pro
    Inscrit en
    Octobre 2009
    Messages
    55
    Détails du profil
    Informations personnelles :
    Âge : 38
    Localisation : France

    Informations forums :
    Inscription : Octobre 2009
    Messages : 55
    Par défaut
    Merci beaucoup, ca marche a la perfection On pourra dire que tu m'as plus que bien aide sur ce coup-ci !!!

    Si je peux me permettre j'ai une derniere question En fait a chaque clic sur le QLabel j'aimerais mettre une sorte de curseur/pointeur pour que l'utilisateur puisse voir ou il a clique. Du coup j'ai fait ca:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
     
    def mousePressEvent(self, event):
     
    		X = event.x()
    		Y = event.y()
    		Z = 0
     
    		self.ui_pos.label_xyz.setText( str((X,Y,Z)) )
     
    		cursor_Label_PositionXY = QtGui.QLabel(self)
    		cursor_Label_PositionXY.setObjectName('label_cursor')
    		cursor_Label_PositionXY.setGeometry(QtCore.QRect(X-16, Y-16, 32, 32))
    		cursor_Label_PositionXY.setPixmap(QtGui.QPixmap("ressources/product.ico"))
    		cursor_Label_PositionXY.setVisible(True)

    Je rajoute donc une petite image a l'endroit ou j'ai clique. Le probleme est que lorsque je clique de nouveau, l'ancien QLabel ne s'efface pas, et du coup j'en ai plusieurs !!

    Aurais-tu une idee pour effacer le precedent a chaque nouveau clic ?? Merci...

  14. #14
    Membre éprouvé
    Inscrit en
    Avril 2010
    Messages
    99
    Détails du profil
    Informations personnelles :
    Âge : 43

    Informations forums :
    Inscription : Avril 2010
    Messages : 99
    Par défaut
    Bonjour, une manière de faire est d'en créer une seule image et de la déplacer à chaque fois

    L'image sera crée dans le constructeur de labelPosXYCam

    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
     
    class labelPosXYCam(QtGui.QLabel):
             def __init__(self, parent=None):
                    QtGui.QLabel.__init__(self, parent)
              	self.cursor_Label_PositionXY = QtGui.QLabel(self)
    		self.cursor_Label_PositionXY.setObjectName('label_cursor')
                    pixmap = QtGui.QPixmap("ressources/product.ico")
                    self.cursor_Label_PositionXY.setPixmap(pixmap)
    		self.cursor_Label_PositionXY.setVisible(False)
     
             def mousePressEvent(self, event):
    		x = event.x()
    		y = event.y()
                    z = 0
    		self.ui_pos.label_xyz.setText( str((x,y,z)) )
    		self.cursor_Label_PositionXY.setGeometry(X-16, Y-16, 32, 32)
    		self.cursor_Label_PositionXY.setVisible(True)
    ps: je n'ai pas vérifié mon code, il y a peut-être des erreurs mais l'idée est là.

  15. #15
    Expert confirmé

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

    Informations forums :
    Inscription : Octobre 2008
    Messages : 4 308
    Par défaut
    Salut, pour la forme du curseur, es-tu allé voir là:

    http://www.riverbankcomputing.co.uk/...l/qcursor.html

    tu peux appliquer une forme de curseur pour un seul widget :

    myLabel.setCursor(QtCore.Qt.BusyCursor)

    Aussi pour les nom des widgets, tu peux directement les introduire dans les propriétés de l'objet dans le designer.

    vincent

  16. #16
    Membre averti
    Profil pro
    Inscrit en
    Octobre 2009
    Messages
    55
    Détails du profil
    Informations personnelles :
    Âge : 38
    Localisation : France

    Informations forums :
    Inscription : Octobre 2009
    Messages : 55
    Par défaut
    Merci VinsS pour le lien, mais en fait ce n'est pas la forme du curseur que je cherchais a changer, en fait je voulais laisser une trace la ou j'ai clique. Et j'aurais voulu que cette trace se deplace a chaque clic !!

    Donc merci aussi Biribibi pour cette idee. J'y ai pense aussi mais je ne voyais pas comment creer cet objet, je ne pensais pas que c'etait possible.

    Je vais tester ca tout de suite

  17. #17
    Membre averti
    Profil pro
    Inscrit en
    Octobre 2009
    Messages
    55
    Détails du profil
    Informations personnelles :
    Âge : 38
    Localisation : France

    Informations forums :
    Inscription : Octobre 2009
    Messages : 55
    Par défaut
    Bon bah... ca marche !! C'est tout beau tout propre

    Un grand merci a Biribibi Je crois ne plus avoir de question... du moins concernant ce sujet la

    Encore merci !!

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

Discussions similaires

  1. Réponses: 1
    Dernier message: 27/10/2008, 08h28
  2. Récupération des coordonnées de la souris
    Par kabil.cpp dans le forum MFC
    Réponses: 11
    Dernier message: 23/05/2008, 07h43
  3. Réponses: 0
    Dernier message: 13/11/2007, 12h39
  4. Réponses: 2
    Dernier message: 15/06/2007, 11h08
  5. Réponses: 8
    Dernier message: 04/06/2007, 12h51

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