【问题标题】:How to make promoted widgets show up larger in Qt Designer [closed]如何使提升的小部件在 Qt Designer 中显示得更大 [关闭]
【发布时间】:2021-01-19 14:09:14
【问题描述】:

我正在开发一个应用程序,该应用程序具有许多提升的小部件。我的工作流程如下:

  1. 在 Qt Designer 中设计一个带有按钮、标签、文本编辑器等的新小部件,保存一个 .ui 文件new_widget.ui。
  2. 我在 Python 中使用 PyQt5,所以我使用 PyQt5 将此 .ui 文件转换为 .py 文件new_widget_ui.py。
  3. 然后我创建一个新文件new_widget.py,它定义了一个类NewWidget,它继承自new_widget_ui.py 中定义的ui 类并调用SetupUi()。此外,NewWidget 类中定义了信号槽功能等。
  4. 我希望这个新的小部件在我的主窗口中显示为子小部件,因此在 Qt Designer 的 app_window.ui 中放置一个通用小部件并将其从头文件 new_widget.py 提升到类 NewWidget。

以上所有方法都完美无缺,我已经为许多带有嵌套等的小部件完成了它。我遇到的问题是美观/方便。

该应用程序用于控制和可视化相机收集的数据。有一个主要的小部件display_widget 显示相机输出。考虑到窗口大小,此小部件应尽可能大,因此它具有扩展大小策略。所有其他小部件都在调整此相机的设置,因此它们应尽可能小,以免缩小主显示屏。

所以我给主显示一个扩展尺寸策略和拉伸因子 1,而其他小部件通常具有首选尺寸策略(在 new_widget.ui 文件中和 app_window.ui 中的 new_widget 占位符的属性中定义) 以便它们会缩小以支持display_widget 的扩展。我还使用垫片来尽可能地压缩选项小部件。

当我运行程序时,所有这些基本上都可以正常工作。问题在于,在 Qt Designer 中,所有小部件都缩小到基本上为零的大小(如预期的那样)。不幸的是,这使得开发 Ui 变得很困难,因为我无法点击我想要的小部件,而且很难将新的小部件添加到适当的布局中。

我的解决方法是将所有子小部件的最小尺寸设置为 50 或 100,以便在开发 ui 时大致了解布局的实际外观。但是,我必须确保在完成后将所有这些最小尺寸设置回零,并且我已准备好再次运行该应用程序,因为如果我不这样做,它会破坏实际行为。

问题:

有没有更好的方法在 Qt Designer 中让占位符小部件具有非零大小,以便您可以轻松查看它们的位置并将新小部件添加到布局中?

【问题讨论】:

标签: python layout pyqt5 qt-designer


【解决方案1】:

前提

对此没有简单的解决方案。

如果这些小部件非常复杂,并且您的 GUI 中会包含许多小部件,则可以创建自己的小部件插件,但这不容易,因为文档都是面向 C++,PyQt 的稀有可用文档非常陈旧且零散(此外,插件专用类中的某些功能甚至没有在 PyQt 中实现)。

它是可行的,但它并不容易也不无痛。您可以从阅读very old tutorial 开始(它可以追溯到 2008 年!),甚至这里还有一些问题可以帮助您。了解它的工作原理和实现方法需要花费大量时间,但如果您的 UI 很复杂,可能值得。

一个(肮脏的)解决方法

每当从 uic 或 pyuic 文件加载小部件时,即使仅将一个大小方向设置为最小大小,setMinimumSize() 也会显式调用。

只要您没有在 Designer 中为提升的小部件设置 实际 最小尺寸(至少,不使用专用字段;我将在下一点对此进行更多解释) ),(very, very, very dirty) 解决方法是覆盖 setMinimumSize() 并最终在加载 UI 后立即恢复默认的基本实现,以便如果您需要以编程方式执行此操作,您实际上可以设置最小尺寸。

这样,即使在 UI 上设置了最小尺寸,setupUi()(或loadUi(),如果您使用的是uic)将无法设置它,因为基本实现方法是 不会被调用。

注意:请记住,如果您想要一个小部件的默认最小尺寸class,您应该使用minimumSizeHint(),而不是setMinimumSize()。覆盖类的最小尺寸提示可确保所有新实例始终具有布局的最小尺寸,同时您仍然可以为所需的任何小部件设置自己的最小尺寸。

这是一个提升类定义的例子:

class Promoted(QtWidgets.QWidget):
    def __init__(self, *args, **kwargs):
        super().__init__(*args, **kwargs)
        # create a reference to the default implementation
        self.__setMinimumSize = self.setMinimumSize
        self.setMinimumSize = self.ignoredSetMinimumSize
        # ...

    def minimumSizeHint(self):
        # a default minimum size *hint* for the layout, whenever this widget will 
        # be added to a layout, it will *never* make it smaller than this size; 
        # this is obviously an arbitrary size
        return QtCore.QSize(15, 15)

    def ignoredSetMinimumSize(self, minSize):
        # ignoring calls to setMinimumSize
        return

    def restoreSetMinimumSize(self):
        # restore the original base implementation
        self.setMinimumSize = self.__setMinimumSize

然后,在要使用 ui(或 pyuic)文件的窗口上:

from PyQt5 import QtCore, QtGui, QtWidgets, uic
from promoted import Promoted


class Win(QtWidgets.QWidget):
    def __init__(self):
        super().__init__()
        uic.loadUi('test.ui', self)
        for widget in self.findChildren(Promoted):
            widget.restoreSetMinimumSize()
        # an example to show that the original implementation is actually restored
        self.promotedWidget.setMinimumSize(50, 50)

如何实际设置最小尺寸

如上所述,这有一个重要的缺点:如果您确实需要在 Designer 中为任何这些自定义小部件设置最小尺寸,那么您显然无法通过属性编辑器。

解决方案是使用带有自定义方法的动态属性。

在属性编辑器中,通过点击属性面板顶部的“+ [添加动态属性]”按钮创建一个新属性(例如customMinimumHeight),并将其设置为实际需要的数量,然后覆盖event() 方法并检查event() 覆盖中的QtCore.QEvent.DynamicPropertyChange 事件类型。

请注意,您必须从菜单中选择正确的属性类型,然后输入属性名称。
如果您只想更改一个尺寸方向,请从组合框中选择Int,否则您可以使用Size 类型设置宽度和高度。请注意,如果您要仅设置大小方向,还必须确保尚未设置相反方向:在这种情况下,必须将相反方向设置为最大可能量 (16777215)。

还请记住,最小和最大尺寸仅在内部设置为无效值 (-1):在“公共”方面,如果已明确设置,它们将始终等于 0为 0 或根本不设置。这意味着,如果出于任何原因将最小或最大高度/宽度显式设置为 0,则必须非常小心。虽然这对于最大尺寸通常不是问题,但 可能 只要设置了 minimumSizeHint。

    def event(self, event):
        if event.type() == QtCore.QEvent.DynamicPropertyChange:
            if event.propertyName() == 'customMinimumHeight':
                width = self.minimumWidth() or 16777215
                height = self.property('customMinimumHeight')
                self.__setMinimumSize(QtCore.QSize(width, height))
            elif event.propertyName() == 'customMinimumWidth':
                width = self.property('customMinimumWidth')
                height = self.minimumHeight() or 16777215
                self.__setMinimumSize(QtCore.QSize(width, height))
            elif event.propertyName() == 'customMinimumSize':
                self.__setMinimumSize(self.property('customMinimumSize'))
        return super().event(event)

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2016-07-05
    • 2013-11-06
    • 1970-01-01
    • 2016-05-13
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2022-01-27
    相关资源
    最近更新 更多