版本 | 作者 | 日期 | 备注 |
---|---|---|---|
0.1 | loon | 2018.11.12 | 初稿 |
在一个界面上实现多窗口除了之前所说的MDI这种形式,还有比较常用的就是使用tabwidget,然后有一个选项卡栏(QTabBar)来切换不同的窗口,比如这样的界面:
还有360管家界面,这样的:
这样的话,在一个窗口中包含了很多窗口,切换方式一目了然,展现给用户的层级就会少一些,使用起来更加快捷,就不会使用起来像“套娃”一样了(打开一个还有一个)。
仍然和了解其他类一样,先在助手中搜索QTabWidget:
基本上,先见名知意大致了解一下其方法和属性的作用,然后我们直接去看详细描述:
QTabWidget类提供了一组选项卡式小部件。
选项卡小部件提供了一个选项卡栏(参见QTabBar)和一个“页面区域”,用于显示与每个选项卡相关的页面。默认情况下,选项卡栏显示在页面区域的上方,但是可以使用不同的配置(参见表)。每个选项卡都与不同的小部件(称为页面)相关联。在页面区域中只显示当前页面;其他页面都隐藏起来了。用户可以通过单击选项卡或按Alt+字母快捷键(如果有的话)来显示不同的页面。
使用QTabWidget的正常方法是:
创建一个QTabWidget。
为选项卡对话框中的每个页面创建一个QWidget,但不要为它们指定父小部件。
在页面小部件中插入子小部件,使用布局将它们定位为正常位置。
调用addTab()或insertTab()将页面小部件放到选项卡小部件中,为每个选项卡提供一个合适的标签,并提供一个可选的键盘快捷方式。
选项卡的位置由tabPosition定义,它们的形状由tabShape定义。
当用户选择一个页面时,会发出currentChanged()信号。
当前页面索引可用currentIndex()表示,这是带有currentWidget()的当前页面小部件。您可以使用widget()检索带有给定索引的页面小部件的指针,并且可以找到带有indexOf()的小部件的索引位置。使用setCurrentWidget()或setCurrentIndex()来显示特定的页面。
您可以使用setTabText()或setTabIcon()更改选项卡的文本和图标。可以使用removeTab()方法删除选项卡及其关联页面。
每个选项卡在任何给定时间都是启用或禁用的(参见setTabEnabled())。如果启用了选项卡,选项卡文本将正常绘制,用户可以选择该选项卡。如果选项卡被禁用,选项卡将以不同的方式绘制,用户无法选择该选项卡。注意,即使禁用了选项卡,页面仍然可以可见,例如,如果所有选项卡碰巧都禁用了。
选项卡小部件可以很好地分割复杂的对话框。另一种方法是使用QStackedWidget,您可以为它提供一些在页面之间导航的方法,例如QToolBar或QListWidget。
QTabWidget中的大部分功能是由QTabBar(顶部提供选项卡)和QStackedWidget(大部分区域,组织各个页面)提供的。
一个Windows Vista样式标签小部件:
一个mac风格的标签小部件:
一个Fusion style标签小部件:
参见QTabBar、QStackedWidget、QToolBox和Tab Dialog示例。
里面除了介绍QTabWidget的用法外,我们发现除了使用QTabWidget还可以使用QToolBox(或者QListWidget)和QStackedWidget结合的方式实现分割复杂的对话框,至于QToolBox、QStackedWidget、QTabBar这些类这里就不展开来说了,感兴趣的单独去查看一下。
在上面的描述中提到:
使用QTabWidget的正常方法是:
创建一个QTabWidget。
为选项卡对话框中的每个页面创建一个QWidget,但不要为它们指定父小部件。
在页面小部件中插入子小部件,使用布局将它们定位为正常位置。
调用addTab()或insertTab()将页面小部件放到选项卡小部件中,为每个选项卡提供一个合适的标签,并提供一个可选的键盘快捷方式。
…
可以使用removeTab()方法删除选项卡及其关联页面。
这里要说的注意就是removeTab(),调用它并不会删除和释放你在最初创建的QWidget,仅仅是在WTabWidget中移除了该QWidget,当你需要再让该widget在TabWidget中显示时add或者insert即可。
这在removeTab中也说明了:
助手上提供了一个TabWidget的示例,此外,还有一个Tab Dialog Example:
TabWidget的例子是qml写的(又是一个新方向了,这里就不展开了),我们看一下Tab DIalog这个例子:
三个page,组成的tabwidget,底下一个buttonBox,两个控件在dialog里面垂直布局,再就是各个page的功能实现以及构造函数中buttonBox的信号和槽的关联等,例子很容易看懂,这里就不多说了,基本上QTabWidget就是:创建QTabWidget—创建QWidget—添加QWidget—QWidget添加控件及布局—移除QWidget—需要时再添加回来QWidget。
例子中我们可以发现其在添加了自己创建的QWidget后并没有在最后释放,这不是错误,而是由Qt的内存管理机制决定的:QT的父子对象机制是在 QWidget和QOject中实现的。当我们使用父对象来创建一个对象的时候 ,父对象会把这个对象添加到自己的子对象列表中。当这个父对象被删除的时候,它会遍历它的子对象类表并且删除每一个子对象,然后子对象们自己再删除它们自己的子对象,这样递归调用直到所有对象都被删除。 这种父子对象机制会在很大程度上简化我们的内存管理工作,减少内存泄露的风险。我们需要显式删除(就是用DELETE删除)的对象是那些使用NEW创建的并且没有父对象的对象(切记是new的才要delete,通过成员函数获得的对象,没有特殊说明的,千万不要随便delete.)。如果我们在删除一个对象的父对象之前删除它,QT会自动地从它的父对象的子对象列表中移除它的。
所以,由于其page的widget是继承自QWidget的,所以QWidget最后删除了其page的widget,所以在其程序代码中并未进行delete,因此基本上我们使用Qt自带的控件的话一般都不需要自己delete,当然你有强迫症的话自己delete并指针指空也肯定不会错。