2017-09-01 4 views
1

J'apprends Qt et comment créer des interfaces graphiques avec python. J'ai réussi à créer mes propres fichiers Qt et le remplir avec des boutons et autres choses simples, mais maintenant j'ai trouvé this amazing attitude indicatory compris le widget externe dans mon interface graphique Qt [python]

Ce fichier ai.py contient un widget d'attitude que je voudrais importer dans ma propre interface graphique. Donc, j'ai conçu mon fichier .ui avec un widget de vide nommé « viz_widget », puis je l'ai écrit ce fichier python

# -*- coding: utf-8 -*- 

import sys 
from PyQt4 import QtCore, QtGui, uic 
from ai import AttitudeIndicator 

qtCreatorFile1 = "mainwindow.ui" # Enter file here. 


Ui_MainWindow, QtBaseClass = uic.loadUiType(qtCreatorFile1) 


class OperatorGUI(QtGui.QMainWindow, Ui_MainWindow): 
    def __init__(self, parent=None): 
     super(OperatorGUI, self).__init__(parent) 
     QtGui.QMainWindow.__init__(self) 
     Ui_MainWindow.__init__(self) 
     self.setupUi(self) 
     self.viz_widget = AttitudeIndicator() 
     self.viz_widget.setPitch(10) 
     self.viz_widget.setRoll(20) 
     self.viz_widget.setHover(500/10.) 
     self.viz_widget.setBaro(500/10.) 
     self.viz_widget.update() 

    # Key press functions 
    def keyPressEvent(self, event): 
     if event.key() == QtCore.Qt.Key_Q: #Q: close the window 
      print "pressed Q: exit by keyboard" 
      self.close() 

if __name__ == "__main__": 
    app = QtGui.QApplication(sys.argv) 
    window = OperatorGUI() 
    window.show() 
    sys.exit(app.exec_()) 

L'interface graphique est lancée, il n'y a pas d'erreurs, mais je ne peux pas afficher le widget d'attitude dans mon interface graphique. Est-il possible d'importer le widget? Quelle est mon erreur?

Nous vous remercions à l'avance

EDIT: ce fichier est le maiwindow.ui

<?xml version="1.0" encoding="UTF-8"?> 
<ui version="4.0"> 
<class>MainWindow</class> 
<widget class="QMainWindow" name="MainWindow"> 
    <property name="geometry"> 
    <rect> 
    <x>0</x> 
    <y>0</y> 
    <width>800</width> 
    <height>600</height> 
    </rect> 
    </property> 
    <property name="windowTitle"> 
    <string>MainWindow</string> 
    </property> 
    <widget class="QWidget" name="centralWidget"> 
    <widget class="QWidget" name="viz_widget" native="true"> 
    <property name="geometry"> 
    <rect> 
     <x>50</x> 
     <y>40</y> 
     <width>671</width> 
     <height>441</height> 
    </rect> 
    </property> 
    </widget> 
    </widget> 
    <widget class="QMenuBar" name="menuBar"> 
    <property name="geometry"> 
    <rect> 
    <x>0</x> 
    <y>0</y> 
    <width>800</width> 
    <height>20</height> 
    </rect> 
    </property> 
    </widget> 
    <widget class="QToolBar" name="mainToolBar"> 
    <attribute name="toolBarArea"> 
    <enum>TopToolBarArea</enum> 
    </attribute> 
    <attribute name="toolBarBreak"> 
    <bool>false</bool> 
    </attribute> 
    </widget> 
    <widget class="QStatusBar" name="statusBar"/> 
</widget> 
<layoutdefault spacing="6" margin="11"/> 
<resources/> 
<connections/> 
</ui> 
+0

Vous avez probablement juste besoin d'ajouter le widget à la disposition de la fenêtre - ou plutôt, à la disposition de son widget central. – ekhumoro

+0

@ekhumoro J'ai ajouté un widget dans ma fenêtre (ui.file) nommé viz_widget dans QtCreator. Ensuite, je l'ai connecté à l'objet AttitudeIndicator dans la ligne 'self.viz_widget = AttitudeIndicator()'. Dois-je faire quelque chose de plus ou quelque chose de différent? – marcoresk

+0

Premièrement: débarrassez-vous de ces deux appels '__init__' - ils ne sont pas nécessaires si vous utilisez' super'. Deuxièmement, supprimez le widget que vous avez ajouté dans QtCreator, vous n'avez donc qu'une fenêtre principale vide (et enregistrez les modifications). Puis ajoutez cette ligne à la fin de '__init__':' layout = QtGui.QVBoxLayout (self.centralWidget()) '. Enfin, ajoutez le widget à la mise en page: 'layout.addWidget (self.viz_widget)'. – ekhumoro

Répondre

1

Voici les étapes nécessaires pour ajouter un widget AttitudeIndicator à la fois dans le code, et par la promotion dans Qt Designer.

Tout d'abord, vous devrez apporter quelques modifications au fichier "mainwindow.ui". Ainsi, dans Qt Designer, cliquez sur le widget central dans l'inspecteur d'objets, puis dans l'éditeur de propriétés, modifiez le nomObjet en central_widget. Ceci est important, car le nom actuel observe la méthode QMainWindow.centralWidget() que nous devons utiliser plus tard. Deuxièmement, avec le widget central toujours sélectionné, cliquez sur Disposer horizontalement dans la barre d'outils (l'icône comporte trois barres verticales bleues) et enregistrer les modifications.

maintenant le bouton droit sur le viz_widget (dans l'inspecteur d'objets ou sur le formulaire), choisissez Promouvoir à ..., et entrez MyAttitudeIndicator en nom de classe Promu et ai_widget dans fichier d'en-tête. Puis cliquez sur Ajouter et Promouvoir - et enregistrer les modifications. Après cela, vous devriez voir le Classe passer de QWidget à MyAttitudeIndicator dans l'inspecteur d'objets. (Mais notez que le widget réel sur le formulaire ne sera pas être affiché comme AttitudeIndicator.Pour ce faire, vous devez écrire un custom designer plugin, ce qui va bien au-delà de la portée de cette question).

Pour utiliser ces modifications, du code doit être ajouté. Tout d'abord, vous devez créer un module appelé ai_widget.py pour la classe de widget promue. Le module doit contenir ce code:

from ai import AttitudeIndicator 

class MyAttitudeIndicator(AttitudeIndicator): 
    def __init__(self, parent, hz=30): 
     super(MyAttitudeIndicator, self).__init__(hz=hz) 
     self.setParent(parent) 

La principale raison pour laquelle cette classe est nécessaire est parce que le AttitudeIndicator d'origine a une API buggy. Le constructeur a vraiment besoin de prendre un widget parent (qui est corrigé dans le code ci-dessus). Toutefois, vous pouvez également utiliser cette classe pour ajouter vos propres fonctionnalités personnalisées.

La dernière étape consiste à ajouter quelques modifications au script principal, illustré ci-dessous. Notez que tous les widgets ajoutés dans Qt Designer deviendront des attributs de l'objet transmis à setupUi() (c'est-à-dire la fenêtre principale, self, dans ce cas).

import sys 
from PyQt4 import QtCore, QtGui, uic 
from ai import AttitudeIndicator 

qtCreatorFile1 = "mainwindow.ui" # Enter file here. 

Ui_MainWindow, QtBaseClass = uic.loadUiType(qtCreatorFile1) 

class OperatorGUI(QtGui.QMainWindow, Ui_MainWindow): 
    def __init__(self, parent=None): 
     super(OperatorGUI, self).__init__(parent) 
     self.setupUi(self) 

     # promoted widget from qt designer 
     self.viz_widget.setPitch(10) 
     self.viz_widget.setRoll(20) 
     self.viz_widget.setHover(500/10.) 
     self.viz_widget.setBaro(500/10.) 

     # optional second widget 
     self.viz_widget2 = AttitudeIndicator() 
     self.viz_widget2.setPitch(10) 
     self.viz_widget2.setRoll(-40) 
     layout = self.centralWidget().layout() 
     layout.addWidget(self.viz_widget2) 

    # Key press functions 
    def keyPressEvent(self, event): 
     if event.key() == QtCore.Qt.Key_Q: #Q: close the window 
      print "pressed Q: exit by keyboard" 
      self.close() 

if __name__ == "__main__": 

    app = QtGui.QApplication(sys.argv) 
    window = OperatorGUI() 
    window.show() 
    sys.exit(app.exec_()) 
+0

Merci beaucoup. La deuxième stratégie fonctionne à merveille (peut-être que le nom du widget central a fait l'affaire). La promotion semble très intéressante mais elle ne fonctionne toujours pas et me donne cette erreur 'super (MyAttitudeIndicator, self) .__ init __ (hz = hz) TypeError: __init __() a un argument de mot clé inattendu 'hz'. Je n'ai aucune idée de 'hz'. Mais vous avez trouvé au moins une solution qui fonctionne et j'accepte la réponse et je vous remercie encore pour votre aide. – marcoresk

+0

@marcoresk. Aucun problème. J'ai utilisé l'actuel "ai.py" de [github, qui a cet argument 'hz'] (https://github.com/capriele/crazyflie-clients-python-move/blob/master/build/lib.linux- i686-2.7/cfclient/ui/widgets/ai.py # L45). Mon code a été testé de manière approfondie, donc je sais que tout fonctionne correctement. – ekhumoro

+0

J'ai découvert que, sans aucune conscience, en supprimant hz = hz dans ai_widget, la promotion semble fonctionner (au moins, elle apparaît dans l'interface graphique). Merci encore. – marcoresk