PyQt-如何向QMainWindow添加单独的UI小部件



我最近才开始编程,尤其是Python(PyQt)。我有我的主要QMainWindow课程。但我想把它和UI小部件分开,这样所有的窗口(菜单、工具栏、常用按钮)都在QMainWindow中,但所有程序/UI特定的小部件(按钮、组合框、图像、复选框等)都在一个单独的QWidget类中。但我不确定我这样做是否正确。

  1. 我的布局有问题——一些不可见的东西覆盖了菜单,使它们无法被鼠标点击,我认为我没有正确地将UI小部件添加到主窗口

我是这样做的:

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. 我见过其他Python程序,其中应用程序被分解成许多小的代码文件(据我所知,将所有内容都放在主类中是不可读或不可管理的)

关于将代码分解成小块,你有什么建议?如何做得更好?或者对于UI来说,它可以全部放在一个大地方?我应该把UI代码/类分解成单独的文件吗?

谢谢。

〔已解决〕

我发现了我的错误——我从UI小部件类中删除了main_widget(现在所有的UI小部件都直接放在UI类小部件本身上),只做了以下操作:

self.main_layout.addWidget(self.form_widget)

菜单不再有问题

你在找这样的东西吗?我真的不确定你的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_())

我建议使用Qt Designer来创建尽可能多的UI。

你会发现用这种方式进行布局等实验要容易得多,而且它会自动将大多数与UI相关的东西与应用程序逻辑的其余部分分开。对主窗口和任何对话框执行此操作,无论多么简单。

然后使用pyuic4从所有ui文件中编译python模块,并将它们放在自己的子包中。

我建议在编译ui文件时使用-w标志。这将生成一个简单的包装器UI类,该类可以直接进行子类化。

所以你的主窗口最终会看起来像这样:

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

请注意,QtDesigner中添加的所有小部件现在都可以作为MainWindow实例的属性直接访问。

在以后的开发过程中,我不会担心将您的应用程序分解成更小的模块。它可能没有必要,但如果有,那么一旦应用程序开始变得更加复杂,如何做到这一点就会变得更加明显。

没有硬性规定——每个项目都不一样。

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()) 

正确的方式!!!

最新更新