Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/qt/7.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/ssis/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python 如何在布局中间插入QWIGET?_Python_Qt_Python 3.x_Pyqt_Pyqt5 - Fatal编程技术网

Python 如何在布局中间插入QWIGET?

Python 如何在布局中间插入QWIGET?,python,qt,python-3.x,pyqt,pyqt5,Python,Qt,Python 3.x,Pyqt,Pyqt5,我正在使用Qt框架构建图形用户界面。我使用QGridLayout来整齐地定位QWidget。 GUI如下所示: 我的应用程序在运行时定期向GUI添加新的小部件。这些新的小部件通常不在Q布局的末尾添加,而是在中间的某个地方。 这样做的过程有点麻烦。应用于上图,我需要取出widg_C,widg_D。。。从QGridLayout。接下来,我添加了widg_x和widg_y,最后我再次将其他小部件放回原处。 以下是我从QGridLayout中删除小部件的方法: for i in reversed(ra

我正在使用Qt框架构建图形用户界面。我使用QGridLayout来整齐地定位QWidget。
GUI如下所示:

我的应用程序在运行时定期向GUI添加新的小部件。这些新的小部件通常不在Q布局的末尾添加,而是在中间的某个地方。

这样做的过程有点麻烦。应用于上图,我需要取出
widg_C
widg_D
。。。从QGridLayout。接下来,我添加了
widg_x
widg_y
,最后我再次将其他小部件放回原处。
以下是我从QGridLayout中删除小部件的方法:

for i in reversed(range(myGridLayout.count())):
    self.itemAt(i).widget().setParent(None)
###
只要您处理的是少量小部件,这个过程就不会是一场灾难。但在我的应用程序中,我显示了很多小部件——可能是50个或更多!此过程正在进行时,应用程序会冻结一秒钟,这对用户来说非常烦人。
有没有一种方法可以在QLayout中的某个位置插入小部件,而无需取出其他小部件


编辑:显然QVBoxLayout的解决方案非常简单。只需使用函数
insertWidget(..)
而不是
addWidget(..)
。可以通过以下链接找到文档:
不幸的是,我找不到QGridLayout的类似函数


编辑:许多人正确地提到,放回大量的小部件不应该导致性能问题——它确实非常快(感谢@ekhumoro指出这一点)。显然,我面临的性能问题与将小部件放回原处的算法有关。这是一个相当复杂的递归算法,它将每个小部件放在QGridLayout的正确坐标上。这导致我的显示器出现“闪烁”。这些小部件被取出,然后延迟(由于算法的原因)放回内部,导致闪烁


编辑:我找到了一个解决方案,可以轻松地在QGridLayout中插入新行。插入新行意味着我不需要从零开始取出并替换所有小部件-因此我避免了运行昂贵的递归算法。

我的答案如下。

谢谢@Ekhumaro、@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)
        ###

    ''''''
类CustomGridLayout(QVBoxLayout):
定义初始化(自):
超级(CustomGridLayout,self)。\uuuu init\uuuu()
self.setAlignment(Qt.AlignTop)#!!!
自配速(20)
def addWidget(self、widget、row、col):
# 1. 有多少水平布局(行)?
horLaysNr=self.count()
# 2. 如有必要,添加行
如果行<水平信噪比:
通过
其他:
当行>=horLaysNr时:
lyt=QHBoxLayout()
lyt.setAlignment(Qt.AlignLeft)
self.addLayout(lyt)
horLaysNr=self.count()
###
###
# 3. 在指定列插入小部件
self.itemAt(行).insertWidget(列,小部件)
''''''
def insertRow(自身,行):
lyt=QHBoxLayout()
lyt.setAlignment(Qt.AlignLeft)
self.insertLayout(行,lyt)
''''''
def DELETE行(自身,行):
对于反向(范围(self.itemAt(row.count())中的j):
self.itemAt(行).itemAt(j).widget().setParent(无)
###
self.itemAt(行).setParent(无)
def清除(自):
对于反转的i(范围(self.count()):
对于反向(范围(self.itemAt(i.count())中的j):
self.itemAt(i).itemAt(j).widget().setParent(无)
###
###
对于反转的i(范围(self.count()):
self.itemAt(i).setParent(无)
###
''''''

关于
QVBoxLayout
,有
insertWidget
方法和一些类似的问题。我认为您为GUI选择了错误的模型。例如,对于此类动态内容,您可以使用
QTableWidget
。它将负责所有项目的插入/删除等。插入小部件的代码一定有问题,因为50个小部件是一个微不足道的数字。我做了一些测试,在包含2000个小部件的布局顶部插入一个小部件并将所有其他小部件向下移动不到半秒钟。@ekhumoro我认为这取决于小部件的resizeEvent()中完成了多少工作。从记忆中,我似乎记得,每当您更改任何内容时,Qt都会生成内部“布局更改”事件。它们最终会调用小部件上的resizeEvent()(或者可能只是调用moveEvent())。在任何情况下,如果这些代码中有重要的代码,都会导致性能问题。@StuartFisher。这一切都属于我的意思:“代码有问题”。OP需要提供一个演示行为的示例,否则问题就没有意义了。