Python 如何使升级的小部件在Qt设计器中显示得更大
我正在开发一个应用程序,它有许多升级的小部件。我的工作流程如下:Python 如何使升级的小部件在Qt设计器中显示得更大,python,layout,pyqt5,qt-designer,Python,Layout,Pyqt5,Qt Designer,我正在开发一个应用程序,它有许多升级的小部件。我的工作流程如下: 使用按钮、标签、文本编辑等设计一个新的小部件。在Qt Designer中,保存一个.ui文件new_widget.ui 我使用PyQt5在Python中工作,因此我使用PyQt5将这个.ui文件转换为.py文件new\u widget\u ui.py 然后我创建一个新文件new\u widget.py,它定义了一个类NewWidget,该类继承了在new\u widget\u ui.py中定义的ui类,并调用SetupUi()。另
new_widget.ui
new\u widget\u ui.py
new\u widget.py
,它定义了一个类NewWidget
,该类继承了在new\u widget\u ui.py
中定义的ui类,并调用SetupUi()
。另外,信号槽功能等在NewWidget
类中定义app\u window.ui
中,我放置一个通用小部件,并将其从头文件new\u widget.py
升级到classNewWidget
display\u窗口小部件,用于显示相机输出。给定窗口大小,此小部件应尽可能大,以便具有扩展大小策略。所有其他小部件都在调整此相机的设置,因此它们应该尽可能小,以不收缩主显示器
因此,我给了主显示一个扩展大小策略和拉伸因子1,而其他小部件通常具有首选大小策略(在new\u widget.ui
文件中定义,并在app\u window.ui
中定义为new\u widget占位符的属性)因此,它们将缩小以支持扩展显示\u小部件
。我还使用间隔符尽可能多地压缩选项小部件
当我运行程序时,所有这些基本上都能正常工作。问题是,在Qt Designer中,所有小部件都缩小到基本上为零的大小(如预期的那样)。不幸的是,这使得开发Ui变得很困难,因为我无法单击我想要的小部件,并且很难将新的小部件添加到适当的布局中
我的解决方法是将所有子窗口小部件的最小大小设置为50或100,以便在开发ui时大致了解布局的实际外观。但是,我必须确保在我完成后将所有这些最小尺寸设置回零,并且我准备再次运行应用程序,因为如果我不这样做,它会破坏实际行为
问题:
有没有更好的方法让升级的占位符小部件在Qt Designer中具有非零大小,以便您可以轻松查看它们的位置并向布局中添加新的小部件?
没有简单的解决办法
如果这些小部件非常复杂,而且你的GUI中有很多,那么有可能创建你自己的小插件,但是这并不容易,因为文档都是面向C++的,而且PyQt的稀有可用文档非常古老和零碎。(另外,插件专用类中的一些函数甚至没有在PyQt中实现)
这是可行的,但并不容易,也不是无痛的。你可以从阅读a开始(它可以追溯到2008年!),这里甚至还有一些问题可以帮助你。理解它是如何工作的以及如何实现它需要很多时间,但如果你的UI很复杂,这可能是值得的
(肮脏的)变通办法
无论何时从uic或pyuic文件加载小部件,都会显式调用setMinimumSize()
,即使只有一个大小方向被设置为最小大小
只要您不介意在Designer中设置升级小部件的实际最小大小(至少,不使用专用字段;我将在下一点对此进行详细解释),那么(非常、非常、verydirty)解决方法就是覆盖setMinimumSize()
最终,在加载UI后立即恢复默认的基本实现,这样,如果需要以编程方式设置最小大小,您就可以实际设置最小大小
这样,即使在UI上设置了最小大小,setupUi()
(或loadUi()
,如果您使用的是uic
),也无法设置它,因为不会调用基本实现方法
注意:请记住,如果您想要小部件类的默认最小大小,则应使用,而不是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)文件的窗口上:
如何实际设置最小尺寸
如上所述,这有一个重要的缺点:如果您确实需要为Designer中的任何自定义小部件设置最小大小,则显然无法从属性编辑器上的正常最小大小字段中进行设置
解决方案是将动态属性与自定义方法一起使用
在属性编辑器中,通过单击属性面板顶部的“+[Add Dynamic property]”按钮创建一个新属性(例如,customMinimumHeight
),并将其设置为实际需要的数量,然后覆盖该方法并检查事件()中的QtCore.QEvent.DynamicPropertyChange
事件类型
覆盖
请注意,您必须从菜单中选择正确的属性类型,然后键入属性名称。
如果要仅更改一个尺寸方向,请从组合框中选择Int
,否则可以使用size
类型设置宽度和高度。请注意,如果要仅设置尺寸方向,还必须确保尚未设置对侧:在
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)
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)