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 :

PyQt5 et mavlink


Sujet :

PyQt Python

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

    Informations forums :
    Inscription : Juillet 2005
    Messages : 423
    Points : 133
    Points
    133
    Par défaut PyQt5 et mavlink
    Bonjour,

    Je voudrais récupérer dans une interface PyQt les messages mavlink envoyé par un robot.

    J'ai écrit un composant de type QWidget avec un label, et ce label doit être mis à jour à chaque fois que l'appli reçoit un message mavlink. Pour ça, j'ai une méthode update() dans mon composant.

    Ensuite dans mon main :

    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
    if __name__ == '__main__':
        app = QApplication(sys.argv)
        cb = MonComposant()
     
        w = QWidget()
        layout = QHBoxLayout()
        layout.addWidget(cb)
        w.setLayout(layout)
     
        w.show()
     
        master = mavutil.mavlink_connection(url_de_connexion)
        master.wait_heartbeat()
        master.mav.param_request_list_send(master.target_system, master.target_component)
     
        while True:
            try:
                #pass
                ack_msg2 = master.recv_match(type=['NAMED_VALUE_FLOAT',
                                                   'SERVO_OUTPUT_RAW',
                                                   'RC_CHANNELS',
                                                   'HEARTBEAT',
                                                   'VFR_HUD',
                                                   'SYS_STATUS',
                                                   'SCALED_PRESSURE2',
                                                   'CAMERA_CAPTURE_STATUS'], blocking=True)
                ack_msg2 = ack_msg2.to_dict()
     
                if ack_msg2['mavpackettype'] == 'SYS_STATUS':
                    # Niveau batterie
                    print('mavpackettype == SYS_STATUS', 'voltage_battery=', ack_msg2['voltage_battery'])
                    cb.update(round(ack_msg2['voltage_battery'] / 1000, 2))
     
            except:
                pass
     
        sys.exit(app.exec_())
    Si j'affiche mon composant sans la connexion mavlink, il s'affiche bien.
    Mais si je lance avec la connexion, j'ai bien les messages mavlink qui s'affichent dans la console (commande print), mais pour l'affichage du widget, j'ai juste une fenêtre avec un fond blanc, le label qui doit être mis à jour avec le message mavlink ne s'affiche pas.

    Pourquoi ?
    Est-ce qu'il faut utiliser des threads? et si oui, comment faire ça ?

    Merci,
    Nico

  2. #2
    Expert éminent

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

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

    Ton app.exec_() se trouve après ta boucle, ceci explique cela.

    Sous-classe ton widget et ajoute un toolButton pour lancer la boucle.

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

    Informations forums :
    Inscription : Juillet 2005
    Messages : 423
    Points : 133
    Points
    133
    Par défaut
    sous-classer le widget ?

    Nico

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

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

    Informations forums :
    Inscription : Février 2006
    Messages : 12 684
    Points : 30 973
    Points
    30 973
    Billets dans le blog
    1
    Par défaut
    Bonjour
    Citation Envoyé par DiverSIG Voir le message
    sous-classer le widget ?
    Tu crées ta propre classe qui hérite d'un QWidget. Tu pourras l'utiliser comme un QWidget mais lui rajouter tes propres éléments et outils, tel le QLabel + la lecture de mavlink et la mise à jour dudit QLabel.
    Ensuite tu crées un timer qui se charge d'aller lire ton mavlink et afficher ses infos dans le QLabel.
    Il faut bien que tu comprennes que tout doit se faire dans Qt.

    Un exemple : je lis un fichier "toto" et je l'affiche dans ma fenêtre - La réactualisation se fait toutes les 2 secondes par défaut mais la fenêtre possède un spinbox permettant de modifier la fréquence de réactualisation.
    Code python : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    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
    #!/usr/bin/env python3
    # coding: utf-8
     
    from PyQt5.QtCore import *
    from PyQt5.QtGui import *
    from PyQt5.QtWidgets import *
    import sys
    import os
     
    # L'objet pour gérer mon appli
    class myAppli(QApplication):
    	# Constructeur
    	def __init__(self, fic, *args, **kwargs):
    		# Appel méthode objet hérité
    		super().__init__(*args, **kwargs)
     
    		# Le widget principal
    		self.__mainWidget=myMainWindow(fic)
    	# __init__()
     
    	# Lancement boucle de traitement des évènements Qt
    	def exec_(self):
    		# Affichage du widget principal
    		self.__mainWidget.show()
     
    		# Appel méthode objet hérité
    		return super().exec_()
    	# exec_()
    # class myAppli
     
    # L'objet pour gérer ma fenêtre principale
    class myMainWindow(QMainWindow):
    	# Constructeur
    	def __init__(self, fic, *args, **kwargs):
    		# Appel méthode objet hérité
    		super().__init__(*args, **kwargs)
     
    		# La fenêtre sera détruite à sa fermeture
    		self.setAttribute(Qt.WA_DeleteOnClose)
     
    		# La fenêtre principale doit posséder un widget central qui servira ensuite de référent
    		self.setCentralWidget(QWidget(parent=self))
     
    		# Le fichier à afficher
    		self.__fic=fic
     
    		# La zone d'affichage
    		self.__affich=QLineEdit(parent=self.centralWidget())
    		self.__affich.setReadOnly(True)
     
    		# La vitesse du timer
    		speed=QSpinBox(parent=self.centralWidget(), valueChanged=self.__slotSpeed)
    		speed.blockSignals(True)
    		speed.setRange(1, 10)
    		speed.setValue(2)
    		speed.setWrapping(True)
    		speed.blockSignals(False)
     
    		# Le layout d'affichage
    		layoutAffich=QHBoxLayout()
    		layoutAffich.addWidget(self.__affich, stretch=1)
    		layoutAffich.addWidget(speed, stretch=0)
     
    		# Le bouton connecté à la fermeture des fenêtres de l'application
    		quit=QPushButton("Quit", parent=self.centralWidget(), clicked=qApp.closeAllWindows)
     
     		# Le gestionnaire de positionnement principal
    		mainLayout=QVBoxLayout(self.centralWidget())
    		mainLayout.addLayout(layoutAffich, stretch=0)
    		mainLayout.addStretch(1)
    		mainLayout.addWidget(quit, stretch=0)
     
    		# Le timer qui activera la lecture du fichier
    		self.__timer=QTimer(self)
    		self.__timer.setTimerType(Qt.PreciseTimer)
    		self.__timer.setInterval(speed.value() * 1000)
    		self.__timer.timeout.connect(self.__slotTimer)
    	# __init()
     
    	# Lorsque la fenêtre s'affiche
    	def showEvent(self, event, *args, **kwargs):
    		# Appel méthode objet hérité
    		super().showEvent(event, *args, **kwargs)
     
    		# Première lecture
    		self.__slotTimer()
     
    		# Lancement timer
    		self.__timer.start()
    	# showEvent()
     
    	# Lorsque le timer s'active
            @pyqtSlot()
    	def __slotTimer(self):
    		# Si le fichier est ok
    		if os.path.isfile(self.__fic):
    			# On lit le fichier et on l'affiche dans la zone
    			with open(self.__fic, "r") as fp: self.__affich.setText(fp.read())
    		else:
    			# Message info
    			self.__affich.setText("Erreur, fichier [{}] incorrect ou inexistant".format(self.__fic))
    		# if
    	# __slotTimer()
     
    	# Lorsque la vitesse change
            @pyqtSlot(int)
    	def __slotSpeed(self, value):
    		# Le timer s'adapte
    		print("value={}".format(value))
    		self.__timer.setInterval(value * 1000)
    	# __slotSpeed()
    # class myMainWindow
     
    if __name__ == "__main__":
    	# L'application principale Qt
    	sys.exit(myAppli("toto", sys.argv).exec_())
    # if
    Tu lances le programme, avec ou sans le fichier "toto" présent. Ensuite, une fois lancé, tu le laisses tourner et dès que tu crées ou modifies "toto", tu verras son contenu apparaitre dans la fenêtre. Et selon que tu montes ou descendes la valeur, la réactualisation sera plus ou moins rapide.

    Plus d'exemples pour apprendre Qt ici: https://pyqt.developpez.com/telechar.../47/Hello-Word.
    Mon Tutoriel sur la programmation «Python»
    Mon Tutoriel sur la programmation «Shell»
    Sinon il y en a pleins d'autres. N'oubliez pas non plus les différentes faq disponibles sur ce site
    Et on poste ses codes entre balises [code] et [/code]

  5. #5
    Membre habitué
    Profil pro
    Inscrit en
    Juillet 2005
    Messages
    423
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juillet 2005
    Messages : 423
    Points : 133
    Points
    133
    Par défaut
    super merci pour l'exemple, je vais examiner ce code en détail.
    petite question : pour quoi mettre des __ (double underscore ?) devant les noms de variables ou de fonctions?

    Nico

  6. #6
    Expert éminent sénior
    Avatar de Sve@r
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Février 2006
    Messages
    12 684
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Oise (Picardie)

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

    Informations forums :
    Inscription : Février 2006
    Messages : 12 684
    Points : 30 973
    Points
    30 973
    Billets dans le blog
    1
    Par défaut
    Citation Envoyé par DiverSIG Voir le message
    petite question : pour quoi mettre des __ (double underscore ?) devant les noms de variables ou de fonctions?
    Ca les rend privées => elles ne sont pas accessibles depuis l'extérieur de l'objet => https://winjerome.developpez.com/tmp...classes#LXIV-6.
    Mon Tutoriel sur la programmation «Python»
    Mon Tutoriel sur la programmation «Shell»
    Sinon il y en a pleins d'autres. N'oubliez pas non plus les différentes faq disponibles sur ce site
    Et on poste ses codes entre balises [code] et [/code]

Discussions similaires

  1. Paramétrer Eric5 sous Linux pour faire du PyQt5
    Par Cenwen dans le forum Eric
    Réponses: 3
    Dernier message: 04/11/2013, 21h10
  2. PyQt5 et thread
    Par moumoute77 dans le forum PyQt
    Réponses: 9
    Dernier message: 27/10/2013, 14h17
  3. Installation de PyQt4 et PyQt5 possible ?
    Par Invité dans le forum PyQt
    Réponses: 0
    Dernier message: 26/06/2013, 23h06
  4. PyQt5 sur Android
    Par c-candide dans le forum Général Python
    Réponses: 1
    Dernier message: 03/05/2013, 08h34

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