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

Je n'ai commencé que récemment la programmation et Python (PyQt) en particulier. J'ai mon principal QMainWindow classe. Mais je voulais le séparer des widgets UI, de sorte que tous les trucs windows (menus, barres d'outils, boutons communs) sont en QMainWindow, mais tous les widgets spécifiques au programme / UI (pusgbuttons, comboboxes, images, cases à cocher, etc.) sont dans un autre QWidget classe. Mais je ne suis pas sûr si je suis en train de faire de ce droit.

  1. j'ai un problème avec la mise en page - quelque chose d'invisible couvre les menus pour qu'ils ne soient pas cliquables par la souris, je pense que je n'ajoute pas mon widget UI à la fenêtre principale correctement

Voici comment je le 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 beaucoup de petits fichiers de code (d'après ce que j'ai compris, avoir tout sur la classe principale est illisible ou ingérable).

que suggérez-vous pour briser le code en petits morceaux? Comment est-il fait mieux? Ou pour L'UI il peut tout être dans un grand endroit? Est-ce que je dois casser le code D'UI/classes dans un fichier séparé?

je vous Remercie.

[résolu]

j'ai trouvé mon erreur - j'ai supprimé le main_widget de la classe widget de L'interface utilisateur (maintenant tous les widgets de L'interface utilisateur sont placés directement sur le widget de la classe D'interface utilisateur lui-même) et je ne fais que ceci:

self.main_layout.addWidget(self.form_widget)

plus de problèmes avec les menus

17
demandé sur NorthCat 2012-01-11 09:10:26

3 réponses

vous cherchez quelque chose de ce genre? Je ne suis pas vraiment sûr de ce que votre main_widget

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_())
22
répondu Jeff 2015-02-15 15:15:19
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()) 

bonne façon!!!

9
répondu 2013-06-18 08:42:39

je recommande D'utiliser Qt Designer pour créer autant d'interface utilisateur que possible.

vous trouverez qu'il est beaucoup plus facile d'expérimenter avec des layouts et ainsi de suite, et il gardera automatiquement la plupart des choses liées à L'UI séparée du reste de votre logique d'application. Le faire pour la fenêtre principale, et aussi pour toutes les boîtes de dialogue, cependant simple.

alors utilisez pyuic4 pour compiler les modules python à partir de tous les ui fichiers, et de les mettre tous ensemble dans leur propre sous-package.

je recommande d'utiliser le -w drapeau lors de la compilation ui fichiers. Cela générera une simple classe D'interface d'enrubannage qui peut être subdivisée directement.

ainsi votre fenêtre principale finirait par ressembler à 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 sous les attributs de MainWindow instance.

Je ne m'inquiéterais pas de fractionner votre application en plus petits modules jusqu'à ce que plus tard dans le développement. Il se peut que cela ne s'avère pas nécessaire, mais si c'est le cas, la façon de le faire deviendra plus évidente une fois que la demande commencera à devenir plus complexe.

il n'y a pas de règles rigides - chaque projet est différent.

8
répondu ekhumoro 2012-01-11 20:23:07