Size of verticalLayout is different in Qt Designer and PyQt program(Qt Designer和PyQt程序中verticalLayout的大小不同)
问题描述
在 Qt Designer 5.9 中 test.ui
中的 verticalLayout
与窗口边缘有一定距离,但在加载 test.ui
在 main.py
中使用 PyQt 5.11.3,verticalLayout
会扩展到窗口的边缘.
In Qt Designer 5.9 the verticalLayout
in test.ui
had a certain distance to the edge of the window, but after loading test.ui
with PyQt 5.11.3 in main.py
the verticalLayout
extend to the edge of the window.
main.py:
#!/usr/bin/python3
import sys
from PyQt5.QtWidgets import QApplication, QMainWindow
from PyQt5.uic import loadUi
class MainWindow(QMainWindow):
def __init__(self, parent=None):
super().__init__()
loadUi("test.ui", self)
def main():
app = QApplication(sys.argv)
main_window = MainWindow(app)
main_window.show()
sys.exit(app.exec_())
if __name__ == "__main__":
main()
test.ui:
<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
<class>MainWindow</class>
<widget class="QMainWindow" name="MainWindow">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>350</width>
<height>257</height>
</rect>
</property>
<property name="windowTitle">
<string>Test</string>
</property>
<widget class="QWidget" name="centralwidget">
<layout class="QGridLayout" name="gridLayout_2">
<item row="0" column="0">
<layout class="QVBoxLayout" name="verticalLayout">
<property name="leftMargin">
<number>0</number>
</property>
<property name="topMargin">
<number>0</number>
</property>
<item>
<spacer name="verticalSpacer_2">
<property name="orientation">
<enum>Qt::Vertical</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>20</width>
<height>40</height>
</size>
</property>
</spacer>
</item>
<item>
<widget class="QGroupBox" name="groupBox">
<layout class="QGridLayout" name="gridLayout">
<item row="1" column="1">
<widget class="QSpinBox" name="spinBox">
<property name="maximum">
<number>100000</number>
</property>
<property name="value">
<number>1000</number>
</property>
</widget>
</item>
<item row="1" column="0">
<widget class="QLabel" name="label_2">
<property name="text">
<string>Test</string>
</property>
<property name="alignment">
<set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
</property>
</widget>
</item>
<item row="0" column="1">
<widget class="QComboBox" name="comboBox">
<property name="currentText">
<string/>
</property>
</widget>
</item>
<item row="0" column="0">
<widget class="QLabel" name="label1">
<property name="text">
<string>Test</string>
</property>
<property name="alignment">
<set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
</property>
</widget>
</item>
</layout>
</widget>
</item>
<item>
<spacer name="verticalSpacer">
<property name="orientation">
<enum>Qt::Vertical</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>20</width>
<height>40</height>
</size>
</property>
</spacer>
</item>
<item>
<widget class="QPushButton" name="pushButton">
<property name="layoutDirection">
<enum>Qt::LeftToRight</enum>
</property>
<property name="text">
<string>Test</string>
</property>
</widget>
</item>
</layout>
</item>
</layout>
</widget>
<widget class="QMenuBar" name="menubar">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>350</width>
<height>28</height>
</rect>
</property>
</widget>
<widget class="QStatusBar" name="statusbar"/>
</widget>
<resources/>
<connections/>
</ui>
<小时>
Qt Designer 5.9 中 test.ui
的屏幕截图:
main.py
加载 test.ui
的截图:
这种行为的原因是什么?
What's the reason for this behavior?
推荐答案
查看uic.loadUi()
的代码会发现如下代码:
If you check the code of uic.loadUi()
you will find the following code:
uiparser.py
class UIParser(object):
# ...
def createLayout(self, elem):
# ...
margin = -1 if self.stack.topIsLayout() else self.defaults['margin']
margin = self.wprops.getProperty(elem, 'margin', margin)
left = self.wprops.getProperty(elem, 'leftMargin', margin)
top = self.wprops.getProperty(elem, 'topMargin', margin)
right = self.wprops.getProperty(elem, 'rightMargin', margin)
bottom = self.wprops.getProperty(elem, 'bottomMargin', margin)
# A layout widget should, by default, have no margins.
if self.stack.topIsLayoutWidget():
if left < 0: left = 0
if top < 0: top = 0
if right < 0: right = 0
if bottom < 0: bottom = 0
def topIsLayoutWidget(self):
# A plain QWidget is a layout widget unless it's parent is a
# QMainWindow or a container widget. Note that the corresponding uic
# test is a little more complicated as it involves features not
# supported by pyuic.
if type(self[-1]) is not QtWidgets.QWidget:
return False
if len(self) < 2:
return False
parent = self[-2]
return isinstance(parent, QtWidgets.QWidget) and type(parent) not in (
QtWidgets.QMainWindow,
QtWidgets.QStackedWidget,
QtWidgets.QToolBox,
QtWidgets.QTabWidget,
QtWidgets.QScrollArea,
QtWidgets.QMdiArea,
QtWidgets.QWizard,
QtWidgets.QDockWidget)
问题是由 topIsLayoutWidget()
函数引起的,因为父级将引用用作基础的小部件,在这种情况下 MainWindow 符合 isinstance(parent, QtWidgets.QWidget) 和类型 (parent) not in (QtWidgets.QMainWindow, ...)
所以 topIsLayoutWidget()
将返回 True,所以左、上、右、下为 -1由于这些属性不存在将被更新为 0,因此将通过消除默认值 (9, 9, 9, 9) 来建立对 contentsMargins
的应用,但在 Qt Designer 的情况下, contentsMargins
code>contentsMargins 尚未更新,保持其默认值.
The problem is caused by the topIsLayoutWidget()
function since the parent will refer to the widget that is used as a base, in this case MainWindow complies with isinstance(parent, QtWidgets.QWidget) and type (parent) not in (QtWidgets.QMainWindow, ...)
so topIsLayoutWidget()
will return True, so to be left, top, right, bottom be -1 since those properties do not exist will be updated to 0 so the apply to contentsMargins
will be established by eliminating the default value (9, 9, 9, 9), but in the case of Qt Designer the contentsMargins
have not been updated maintaining their default value.
所以总之是一个 pyqt 错误,它也在评论中指出:
So in conclusion is a pyqt bug that also points in the comments:
# ... Note that the corresponding uic
# test is a little more complicated as it involves features not
# supported by pyuic.*
所以有几种解决方案:
删除:
if self.stack.topIsLayoutWidget():
if left < 0: left = 0
if top < 0: top = 0
if right < 0: right = 0
if bottom < 0: bottom = 0
使用uic.loadUiType()
:
#!/usr/bin/python3
import sys
from PyQt5 import QtCore, QtWidgets, uic
Ui_Interface, _ = uic.loadUiType('test.ui')
class MainWindow(QtWidgets.QMainWindow, Ui_Interface):
def __init__(self, parent=None):
super().__init__(parent)
self.setupUi(self)
def main():
app = QtWidgets.QApplication(sys.argv)
main_window = MainWindow()
main_window.show()
sys.exit(app.exec_())
if __name__ == "__main__":
main()
我更喜欢第二种解决方案,因为不应修改源代码.
I prefer the second solution since the source code should not be modified.
这篇关于Qt Designer和PyQt程序中verticalLayout的大小不同的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持编程学习网!
本文标题为:Qt Designer和PyQt程序中verticalLayout的大小不同


基础教程推荐
- 何时使用 os.name、sys.platform 或 platform.system? 2022-01-01
- Dask.array.套用_沿_轴:由于额外的元素([1]),使用dask.array的每一行作为另一个函数的输入失败 2022-01-01
- 如何让 python 脚本监听来自另一个脚本的输入 2022-01-01
- 在 Python 中,如果我在一个“with"中返回.块,文件还会关闭吗? 2022-01-01
- 线程时出现 msgbox 错误,GUI 块 2022-01-01
- 如何在海运重新绘制中自定义标题和y标签 2022-01-01
- 筛选NumPy数组 2022-01-01
- 用于分类数据的跳跃记号标签 2022-01-01
- 使用PyInstaller后在Windows中打开可执行文件时出错 2022-01-01
- Python kivy 入口点 inflateRest2 无法定位 libpng16-16.dll 2022-01-01