如何在布局中间插入 QWidgets? [英] How to insert QWidgets in the middle of a Layout?

查看:22
本文介绍了如何在布局中间插入 QWidgets?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

I'm using the Qt framework to build my graphical user interface. I use a QGridLayout to position my QWidgets neatly.
The GUI looks like this:

我的应用程序会在运行时定期向 GUI 添加新的小部件.这些新的小部件通常不会添加在 QLayout 的末尾,而是添加在中间的某个位置.

My application regularly adds new widgets to the GUI at runtime. These new widgets are usually not added at the end of the QLayout, but somewhere in the middle.

执行此操作的过程有点麻烦.应用上图,我需要从 QGridLayout 中取出 widg_Cwidg_D、....接下来,我添加了 widg_xwidg_y,最后我再次将其他小部件放回去.
这是我从 QGridLayout 中删除小部件的方法:

The procedure to do this is a bit cumbersome. Applied on the figure above, I would need to take out widg_C, widg_D, ... from the QGridLayout. Next, I add widg_xand widg_y, and finally I put the other widgets back again.
This is how I remove widgets from the QGridLayout:

for i in reversed(range(myGridLayout.count())):
    self.itemAt(i).widget().setParent(None)
###

只要您处理少量小部件,此过程就不是灾难.但是在我的应用程序中,我显示了很多小部件——可能有 50 个或更多!在此过程进行时,应用程序会冻结一秒钟,这对用户来说非常烦人.
有没有办法在 QLayout 的某处插入小部件,而无需取出其他小部件?

As long as you're dealing with a small amount of widgets, this procedure is not a disaster. But in my application I display a lot of small widgets - perhaps 50 or more! The application freezes a second while this procedure is ongoing, which is very annoying to the user.
Is there a way to insert widgets somewhere in a QLayout, without the need to take out other widgets?

显然 QVBoxLayout 的解决方案非常简单.只需使用函数 insertWidget(..) 而不是 addWidget(..).可以在此链接中找到文档:http://doc.qt.io/qt-5/qboxlayout.html#insertWidget
不幸的是,我找不到 QGridLayout 的类似功能.

Apparently the solution for the QVBoxLayout is very simple. Just use the function insertWidget(..) instead of addWidget(..). The docs can be found a this link: http://doc.qt.io/qt-5/qboxlayout.html#insertWidget
Unfortunately, I couldn't find a similar function for the QGridLayout.

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

Many people rightly mentioned that putting back a lot of widgets shouldn't cause a performance issue - it is very fast indeed (thank you @ekhumoro to point that out). Apparently, the performance issue I faced had to do with the algorithm putting the widgets back. It is a fairly complicated recursive algorithm that puts every widget on the right coordinates in the QGridLayout. This resulted in a "flicker" on my display. The widgets are taken out, and put back inside with some delay (due to the algorithm) - causing the flicker.

我找到了一个解决方案,可以轻松地将新行插入 QGridLayout.插入新行意味着我不需要从头开始取出和替换所有小部件 - 因此我避免了运行昂贵的递归算法.
解决方案可以在我下面的回答中找到.

I found a solution such that I can easily insert new rows into the QGridLayout. Inserting new rows means that I don't need to take out and replace all the widgets from scratch - hence I avoid the expensive recursive algorithm to run.
The solution can be found in my answer below.

推荐答案

感谢 @ekhumoro、@Stuart Fisher、@vahancho 和 @mbjoe 的帮助.我最终找到了解决问题的方法.我不再使用 QGridLayout().相反,我围绕 QVBoxLayout 构建了一个包装器,使其表现得好像它是一个 GridLayout,并带有一个额外的函数来插入新行:

Thank you @ekhumoro, @Stuart Fisher, @vahancho and @mbjoe for your help. I eventually found a way to solve the issue. I no longer use the QGridLayout(). Instead, I built a wrapper around the QVBoxLayout to behave as if it was a GridLayout, with an extra function to insert new rows:

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)
        ###

    ''''''

这篇关于如何在布局中间插入 QWidgets?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆