为什么小部件在 OOP 版本中重叠
Why widgets overlaps in the OOP version
我将我的情况简化为一个简单的情况:我想在 PyQt5 中编写 GUI,其中有一个名为 grid
的主要 QGridLayout,其中有另一个网格 gridParamter
和一个 QListView
小部件。
gridParamter
中有2个QLabel
这是代码
import sys
from PyQt5.QtCore import *
from PyQt5.QtGui import *
from PyQt5.QtWidgets import *
def window():
app = QApplication(sys.argv)
win = QWidget()
list1 = QListView()
gridParameter = QGridLayout()
idxRow = 0
label_1 = QLabel("I am label one")
gridParameter.addWidget(label_1, idxRow, 0)
idxRow = 1
label_2 = QLabel("I am label two")
gridParameter.addWidget(label_2, idxRow, 1)
grid = QGridLayout()
grid.addLayout(gridParameter, 0, 0)
grid.setSpacing(2)
grid.addWidget(list1)
win.setLayout(grid)
win.show()
sys.exit(app.exec_())
if __name__ == '__main__':
window()
可以按照我的预期生成GUI。但是当我尝试以 OOP 风格重写它时,即
import sys
from PyQt5.QtCore import *
from PyQt5.QtGui import *
from PyQt5.QtWidgets import *
class MainWindow(QWidget):
def __init__(self):
QWidget.__init__(self)
list1 = QListView(self)
gridParameter = QGridLayout(self)
idxRow = 0
label_1 = QLabel("I am label one", self)
gridParameter.addWidget(label_1, idxRow, 0)
idxRow = 1
label_2 = QLabel("I am label two", self)
gridParameter.addWidget(label_2, idxRow, 1)
grid = QGridLayout(self)
grid.addLayout(gridParameter, 0, 0)
grid.setSpacing(2)
grid.addWidget(list1)
self.setLayout(grid)
if __name__ == "__main__":
app = QApplication(sys.argv)
mainWin = MainWindow()
mainWin.show()
sys.exit( app.exec_() )
我发现 label_1
与 list1
重叠,当我尝试调整主要 windows 的大小时,list1
总是占据网格位置 (0, 0 ).
首先你必须了解以下内容:
请记住以下表达式:
lay = FooLayout()
some_widget.setWidget(lay)
相当于:
lay = FooLayout(some_widget)
这两者都表明布局将处理子项的几何形状。
- 另一方面,如果一个小部件已经有一个布局,除非删除以前的布局,否则无法建立其他布局。
因此,在您的情况下,只有第一条指令起作用,而接下来的两条指令不起作用,因此布局网格将被消除,列表视图仅保留,因为它是小部件的子项。
gridParameter = QGridLayout(self)
# ...
grid = QGridLayout(self)
# ...
self.setLayout(grid)
在我的例子中,我避免放置小部件的父级以查看是否存在问题,而且我仅在必要时才建立为布局的父级:
import sys
from PyQt5 import QtCore, QtGui, QtWidgets
class MainWindow(QtWidgets.QWidget):
def __init__(self):
super(MainWindow, self).__init__()
list1 = QtWidgets.QListView()
gridParameter = QtWidgets.QGridLayout()
idxRow = 0
label_1 = QtWidgets.QLabel("I am label one")
gridParameter.addWidget(label_1, idxRow, 0)
idxRow = 1
label_2 = QtWidgets.QLabel("I am label two")
gridParameter.addWidget(label_2, idxRow, 1)
grid = QtWidgets.QGridLayout(self) # <--- principal layout
grid.addLayout(gridParameter, 0, 0)
grid.setSpacing(2)
grid.addWidget(list1)
if __name__ == "__main__":
app = QtWidgets.QApplication(sys.argv)
mainWin = MainWindow()
mainWin.show()
sys.exit(app.exec_())
总之,必要时使用self
。
我将我的情况简化为一个简单的情况:我想在 PyQt5 中编写 GUI,其中有一个名为 grid
的主要 QGridLayout,其中有另一个网格 gridParamter
和一个 QListView
小部件。
gridParamter
中有2个QLabel
这是代码
import sys
from PyQt5.QtCore import *
from PyQt5.QtGui import *
from PyQt5.QtWidgets import *
def window():
app = QApplication(sys.argv)
win = QWidget()
list1 = QListView()
gridParameter = QGridLayout()
idxRow = 0
label_1 = QLabel("I am label one")
gridParameter.addWidget(label_1, idxRow, 0)
idxRow = 1
label_2 = QLabel("I am label two")
gridParameter.addWidget(label_2, idxRow, 1)
grid = QGridLayout()
grid.addLayout(gridParameter, 0, 0)
grid.setSpacing(2)
grid.addWidget(list1)
win.setLayout(grid)
win.show()
sys.exit(app.exec_())
if __name__ == '__main__':
window()
可以按照我的预期生成GUI。但是当我尝试以 OOP 风格重写它时,即
import sys
from PyQt5.QtCore import *
from PyQt5.QtGui import *
from PyQt5.QtWidgets import *
class MainWindow(QWidget):
def __init__(self):
QWidget.__init__(self)
list1 = QListView(self)
gridParameter = QGridLayout(self)
idxRow = 0
label_1 = QLabel("I am label one", self)
gridParameter.addWidget(label_1, idxRow, 0)
idxRow = 1
label_2 = QLabel("I am label two", self)
gridParameter.addWidget(label_2, idxRow, 1)
grid = QGridLayout(self)
grid.addLayout(gridParameter, 0, 0)
grid.setSpacing(2)
grid.addWidget(list1)
self.setLayout(grid)
if __name__ == "__main__":
app = QApplication(sys.argv)
mainWin = MainWindow()
mainWin.show()
sys.exit( app.exec_() )
我发现 label_1
与 list1
重叠,当我尝试调整主要 windows 的大小时,list1
总是占据网格位置 (0, 0 ).
首先你必须了解以下内容:
请记住以下表达式:
lay = FooLayout() some_widget.setWidget(lay)
相当于:
lay = FooLayout(some_widget)
这两者都表明布局将处理子项的几何形状。
- 另一方面,如果一个小部件已经有一个布局,除非删除以前的布局,否则无法建立其他布局。
因此,在您的情况下,只有第一条指令起作用,而接下来的两条指令不起作用,因此布局网格将被消除,列表视图仅保留,因为它是小部件的子项。
gridParameter = QGridLayout(self)
# ...
grid = QGridLayout(self)
# ...
self.setLayout(grid)
在我的例子中,我避免放置小部件的父级以查看是否存在问题,而且我仅在必要时才建立为布局的父级:
import sys
from PyQt5 import QtCore, QtGui, QtWidgets
class MainWindow(QtWidgets.QWidget):
def __init__(self):
super(MainWindow, self).__init__()
list1 = QtWidgets.QListView()
gridParameter = QtWidgets.QGridLayout()
idxRow = 0
label_1 = QtWidgets.QLabel("I am label one")
gridParameter.addWidget(label_1, idxRow, 0)
idxRow = 1
label_2 = QtWidgets.QLabel("I am label two")
gridParameter.addWidget(label_2, idxRow, 1)
grid = QtWidgets.QGridLayout(self) # <--- principal layout
grid.addLayout(gridParameter, 0, 0)
grid.setSpacing(2)
grid.addWidget(list1)
if __name__ == "__main__":
app = QtWidgets.QApplication(sys.argv)
mainWin = MainWindow()
mainWin.show()
sys.exit(app.exec_())
总之,必要时使用self
。