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

发布于 2024-12-26 03:05:00 字数 1320 浏览 2 评论 0原文

我最近才开始编程,尤其是 Python (PyQt)。我有我的主要 QMainWindow 类。但我想将它与 UI 小部件分开,以便所有窗口内容(菜单、工具栏、常用按钮)都在 QMainWindow 中,但所有程序/UI 特定小部件(pusgbuttons、组合框、图像、复选框等) .) 位于单独的 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)

菜单不再有问题

I've only recently started programming and Python (PyQt) in particular. I have my main QMainWindow class. But I wanted to separate it from UI widgets, so that all windows stuff (menus, toolbars, common buttons) are in QMainWindow, but all program/UI specific widgets (pusgbuttons, comboboxes, images, checkboxes etc.) are in a separate QWidget class. But I'm not sure if I'm doing this right.

  1. I have a problem with layouts - something invisible is covering the menus so that they're not clickable by mouse, I think I'm not adding my UI widget to the main window correctly

Here's how I do it:

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. I've seen other Python programs where applications are broken into a lot of small files of code (as I understand it, having everything in on main class is unreadable or unmanageable).

What's your suggestion about breaking code into small pieces? How's it better done? Or for UI it can all be in one big place? Should I break UI code/classes into separate file at all?

Thank you.

[SOLVED]

I found my mistake - I deleted the main_widget from the UI widget class (now all UI widgets are placed directly on the UI class widget itself) and only do this:

self.main_layout.addWidget(self.form_widget)

no more problems with menus

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

橙幽之幻 2025-01-02 03:05:00

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

Are you looking for something like this? I'm not really sure what your main_widget is

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_())
本宫微胖 2025-01-02 03:05:00

我建议使用 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...

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

在开发后期之前,我不会担心将您的应用程序分解为更小的模块。它可能没有必要 - 但如果有必要,一旦应用程序开始变得更加复杂,如何执行此操作将变得更加明显。

没有硬性规定——每个项目都是不同的。

I would recommend using Qt Designer to create as much of the UI as possible.

You will find it much easier to experiment with layouts and so forth that way, and it will automatically keep most of the UI related stuff separate from the rest of your application logic. Do this for the main window, and also for any dialog boxes, however simple.

Then use pyuic4 to compile python modules from all the ui files, and put them all together in their own sub-package.

I would recommend using the -w flag when compiling ui files. This will generate a simple wrapper UI class that can be subclassed directly.

So your main window would end up looking something like this:

from ui.mainwindow import MainWindowUI

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

Note that all the widgets added in Qt Designer are now accessible directly as attributes of the MainWindow instance.

I would not worry about breaking your application up into smaller modules until later on in development. It may not turn out to be necessary - but if it does, it will become more obvious how to do this once the application starts to become more complex.

There are no hard and fast rules - every project is different.

闻呓 2025-01-02 03:05:00
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()) 

正确的方法!!!

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

correct way!!!

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文