前提
对此没有简单的解决方案。
如果这些小部件非常复杂,并且您的 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)