PyQt QGridLayout布局中的视图切换

我们在主窗口中添加了一个QGridLayout

例如下图,最初默认是显示widget1 widget2 widget3 widget4 这四个窗口,但是我们想通过按键点击,然后切换到widget1或其中任意一个窗口

QGraphicsLinearLayout removeitem崩溃 qgridlayout removewidget_ide

QGraphicsLinearLayout removeitem崩溃 qgridlayout removewidget_视图切换_02

我们想到的方法是先删除 grid 里的所以控件,然后再添加新的控件,然后我们查到可以通过grid.count方法获得grid布局里的控件数量,

接着通过grid.itemAt(i).widget() 的方法可以获取到第i个控件(或widget),最后通过 grid.remove(widget)

最后还有一个小Tips,remove 后的控件并不会移除,还是会显示出来,真正要删除控件要用snip函数,最后控件才会真正的删除。

代码:

import snip

for i in range(grid.count):
    widget = grid.itemAt(i).widget()
    grid.remove(widget)
    snip.delete(widget)

当运行代码后 

widget = grid.itemAt(i).widget()

  这行代码报错,大致意思是:“NoneType” 类型没有widget这个属性。

??? 怎么会报这个错误,是什么原因?

然后调试后发现,是当 i = 2是才出错,原因是由于我们移除控件是动态移除的,所以当移除了前两个控件后,grid 会变成下图这样,

2x1 的布局,所以再去移除索引为2的控件,就找不到这个控件,所以报错。

还要注意的是,当移除了widget2后,布局就变成了下面第二个图,就只剩下一个控件,索引变成 0 才能删除,否则会报错。

代码:

import snip

for i in range(2):
    for j in range(2):
        if(i == 1 and j == 1):
            j = 0;
            widget = grid.itemAt(i).widget()
            grid.remove(widget)
            snip.delete(widget)

 

QGraphicsLinearLayout removeitem崩溃 qgridlayout removewidget_视图切换_03

 

 

QGraphicsLinearLayout removeitem崩溃 qgridlayout removewidget_ide_04

 

 当我们以为就这样就可以的时候,又出现了bug。

原因是snip.delete(widget),将所有的控件都删除了,当我们要重新添加控件的时候就找不到。

我们的解决办法是,先将所有的widget添加的一个 widgetList 列表里面,然后再删除,但是删除了之后,列表里面也没有了,

然后我们发现了widget.hide()函数,不要将控件删除,直接隐藏就不会显示出来,当添加控件的时候需要显示,就用 setHidden(False)设置需要显示的控件为不隐藏,这样就完成了。。。

 

知行合一, 翻万卷书,游千里路,会百家才