K.M*_*ier 6 python qt pyqt python-3.x pyqt5
我正在使用 Qt 框架来构建我的图形用户界面。我使用QGridLayout来整齐地放置我的 QWidget。
图形用户界面如下所示:
我的应用程序定期在运行时向 GUI 添加新的小部件。这些新的小部件通常不会添加在 QLayout 的末尾,而是添加在中间的某个位置。
执行此操作的过程有点麻烦。应用到上图中,我需要从 QGridLayout 中取出widg_C, , ... 。widg_D接下来,我添加widg_x和widg_y,最后我再次将其他小部件放回去。
这就是我从 QGridLayout 中删除小部件的方法:
for i in reversed(range(myGridLayout.count())):
self.itemAt(i).widget().setParent(None)
###
Run Code Online (Sandbox Code Playgroud)
只要您处理的是少量小部件,这个过程就不是一场灾难。但在我的应用程序中,我显示了很多小部件 - 也许 50 个或更多!当这个过程正在进行时,应用程序会冻结一秒钟,这对用户来说非常烦人。
有没有一种方法可以在 QLayout 中的某个位置插入小部件,而不需要取出其他小部件?
编辑:显然 QVBoxLayout 的解决方案非常简单。只需使用该函数insertWidget(..)而不是addWidget(..). 可以通过此链接找到文档:http://doc.qt.io/qt-5/qboxlayout.html#insertWidget
不幸的是,我找不到 QGridLayout 的类似功能。
编辑:许多人正确地提到,放回大量小部件不应导致性能问题 - 它确实非常快(谢谢@ekhumoro 指出这一点)。显然,我面临的性能问题与将小部件放回原处的算法有关。这是一个相当复杂的递归算法,它将每个小部件放在 QGridLayout 中的正确坐标上。这导致我的显示器出现“闪烁”。小部件被取出,然后放回内部,有一些延迟(由于算法) - 导致闪烁。
编辑:我找到了一个解决方案,这样我可以轻松地将新行插入到 QGridLayout 中。插入新行意味着我不需要从头开始取出并替换所有小部件 - 因此我避免了运行昂贵的递归算法。
解决方案可以在我下面的回答中找到。
感谢@ekhumoro、@Stuart Fisher、@vahancho 和@mbjoe 的帮助。我最终找到了解决问题的方法。我不再使用QGridLayout(). 相反,我围绕 构建了一个包装器,其QVBoxLayout行为就像 GridLayout 一样,并带有一个额外的函数来插入新行:
class CustomGridLayout(QVBoxLayout):
def __init__(self):
super(CustomGridLayout, self).__init__()
self.setAlignment(Qt.AlignTop) # !!!
self.setSpacing(20)
def addWidget(self, widget, row, col):
# 1. How many horizontal layouts (rows) are present?
horLaysNr = self.count()
# 2. Add rows if necessary
if row < horLaysNr:
pass
else:
while row >= horLaysNr:
lyt = QHBoxLayout()
lyt.setAlignment(Qt.AlignLeft)
self.addLayout(lyt)
horLaysNr = self.count()
###
###
# 3. Insert the widget at specified column
self.itemAt(row).insertWidget(col, widget)
''''''
def insertRow(self, row):
lyt = QHBoxLayout()
lyt.setAlignment(Qt.AlignLeft)
self.insertLayout(row, lyt)
''''''
def deleteRow(self, row):
for j in reversed(range(self.itemAt(row).count())):
self.itemAt(row).itemAt(j).widget().setParent(None)
###
self.itemAt(row).setParent(None)
def clear(self):
for i in reversed(range(self.count())):
for j in reversed(range(self.itemAt(i).count())):
self.itemAt(i).itemAt(j).widget().setParent(None)
###
###
for i in reversed(range(self.count())):
self.itemAt(i).setParent(None)
###
''''''
Run Code Online (Sandbox Code Playgroud)