22 votes

PyQt - comment ajouter un widget UI séparé à QMainWindow

Je n'ai commencé que récemment à programmer et à utiliser Python (PyQt) en particulier. J'ai mon principal QMainWindow classe. Mais je voulais la séparer des widgets de l'interface utilisateur, afin que tous les éléments de Windows (menus, barres d'outils, boutons communs) soient dans la classe QMainWindow mais tous les widgets spécifiques au programme/à l'interface utilisateur (boutons poussoirs, combobox, images, cases à cocher, etc.) se trouvent dans un dossier séparé. QWidget classe. Mais je ne suis pas sûr de bien faire les choses.

  1. J'ai un problème avec les mises en page - quelque chose d'invisible recouvre les menus de sorte qu'ils ne sont pas cliquables par la souris, je pense que je n'ajoute pas mon widget UI à la fenêtre principale correctement.

Voici comment je fais :

class MyMainWindow(QMainWindow):
    def __init__(self, parent = None):
        super(MyMainWindow, self).__init__(parent)

        self.main_widget = QWidget(self)
        ...
        self.form_widget = FormWidget(self) 
        #This is my UI widget

        self.main_layout = QVBoxLayout(self.main_widget)
        self.main_layout.sizeConstraint = QLayout.SetDefaultConstraint
        self.main_layout.addWidget(self.form_widget.main_widget) 
        #form_widget has its own main_widget where I put all other widgets onto

        self.main_widget.setLayout(self.main_layout)
        self.setCentralWidget(self.main_widget)
  1. J'ai vu d'autres programmes Python où les applications sont divisées en un grand nombre de petits fichiers de code (si je comprends bien, tout avoir dans une classe principale est illisible ou ingérable).

Quelle est votre suggestion pour décomposer le code en petits morceaux ? Comment le faire mieux ? Ou bien, pour l'interface utilisateur, tout peut être regroupé en un seul endroit ? Devrais-je diviser le code/les classes de l'interface utilisateur en fichiers séparés ?

Merci.

[SOLVÉ]

J'ai trouvé mon erreur - j'ai supprimé le main_widget de la classe de widget UI (maintenant tous les widgets UI sont placés directement sur le widget de la classe UI elle-même) et je fais seulement ceci :

self.main_layout.addWidget(self.form_widget)

plus de problèmes avec les menus

27voto

Jeff Points 1678

Vous cherchez quelque chose comme ça ? Je ne suis pas vraiment sûr de ce que votre main_widget est

from PyQt4.QtCore import *
from PyQt4.QtGui  import *

import sys

class MyMainWindow(QMainWindow):

    def __init__(self, parent=None):

        super(MyMainWindow, self).__init__(parent)
        self.form_widget = FormWidget(self) 
        self.setCentralWidget(self.form_widget) 

class FormWidget(QWidget):

    def __init__(self, parent):        
        super(FormWidget, self).__init__(parent)
        self.layout = QVBoxLayout(self)

        self.button1 = QPushButton("Button 1")
        self.layout.addWidget(self.button1)

        self.button2 = QPushButton("Button 2")
        self.layout.addWidget(self.button2)

        self.setLayout(self.layout)

app = QApplication([])
foo = MyMainWindow()
foo.show()
sys.exit(app.exec_())

11voto

ekhumoro Points 23190

Je recommande d'utiliser Qt Designer pour créer la plus grande partie possible de l'interface utilisateur.

Il vous sera beaucoup plus facile d'expérimenter des mises en page, etc., de cette manière, et la plupart des éléments liés à l'interface utilisateur seront automatiquement séparés du reste de la logique de votre application. Faites-le pour la fenêtre principale, ainsi que pour toutes les boîtes de dialogue, aussi simples soient-elles.

Ensuite, utilisez pyuic4 pour compiler des modules python à partir de toutes les ui et les regrouper dans leur propre sous-paquet.

Je recommande d'utiliser le -w lors de la compilation ui fichiers. Cela générera une classe d'interface utilisateur simple qui peut être sous-classée directement.

Ainsi, votre fenêtre principale ressemblerait à quelque chose comme ceci :

from ui.mainwindow import MainWindowUI

class MainWindow(MainWindowUI):
    def __init__(self):
        super(MainWindow, self).__init__()
        # connect signals...
        # do other setup stuff...

Notez que tous les widgets ajoutés dans Qt Designer sont maintenant accessibles directement en tant qu'attributs de l'objet MainWindow instance.

Je ne m'inquiéterais pas de diviser votre application en petits modules avant la fin du développement. Cela ne sera peut-être pas nécessaire, mais si c'est le cas, la façon de procéder deviendra plus évidente lorsque l'application commencera à devenir plus complexe.

Il n'y a pas de règle absolue, chaque projet est différent.

10voto

import sys
from PyQt4 import QtCore, QtGui

class MainWindow(QtGui.QMainWindow):

    def __init__(self, parent=None):
        super(MainWindow, self).__init__(parent)
        self.form_widget = FormWidget(self)
        _widget = QtGui.QWidget()
        _layout = QtGui.QVBoxLayout(_widget)
        _layout.addWidget(self.form_widget)
        self.setCentralWidget(_widget)

class FormWidget(QtGui.QWidget):

    def __init__(self, parent):
        super(FormWidget, self).__init__(parent)
        self.__controls()
        self.__layout()

    def __controls(self):
        self.label = QtGui.QLabel("Name for backdrop")
        self.txted = QtGui.QLineEdit()
        self.lbled = QtGui.QLabel("Select a readNode")
        self.cmbox = QtGui.QComboBox()

    def __layout(self):
        self.vbox = QtGui.QVBoxLayout()
        self.hbox = QtGui.QHBoxLayout()
        self.h2Box = QtGui.QHBoxLayout()

        self.hbox.addWidget(self.label)
        self.hbox.addWidget(self.txted)

        self.h2Box.addWidget(self.lbled)
        self.h2Box.addWidget(self.cmbox)

        self.vbox.addLayout(self.hbox)
        self.vbox.addLayout(self.h2Box)
        self.setLayout(self.vbox)

def main():
    app = QtGui.QApplication(sys.argv)
    win = MainWindow()
    win.show()
    app.exec_()

if __name__ == '__main__':
    sys.exit(main()) 

le bon chemin ! !!

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X