对于应用程序中的多窗体切换,我们已经习以为常。通常一个应用程序中,不同的窗口代表不同功能的工作区。本文将详细描述基于Qt的多窗体程序的设计方法。在阅读本文之前,你最好了解面向对象的基本思想以及Qt的基本使用方法。
接下来我们以编写一个客户端为例来具体说明多窗体程序的编程方法。该客户端包括多个子系统,每个子系统对应一个窗口;在客户端的主界面,通过点击相应的按钮实现多个窗体之间的切换。主界面图如下:
如图所示,该客户端主界面包含顶部的标签、右方的按钮区、中间的主窗口区以及底部的状态栏。通过点击不同的按钮则进入不同的子系统。配置信息子系统和日志信息管理子系统界面设计如下:
布局管理
上述三个界面都可以通过Qt Designer轻松设计完成,这里只对窗体部件的布局管理作说明。通常我们可以显示指定窗体中各个部件的大小以及位置,但是这样麻烦而且缺少灵活性。因此在实际的应用中,使用布局管理器对窗体中的各个子部件进行布局管理。布局管理器会为每个窗体部件提供合理的默认值,并随着个别部件大小的变化而调整整体的窗体布局。
常用的布局管理器有QHBoxLayout、QVBoxLayout和QGridLayout,即依次为水平布局管理、垂直布局管理器和网格布局管理器。结合上面的主界面图示,其对应的布局管理图如下:
使用布局管理器的一般方法为:先创建相应布局管理器的对象;再将要进行布局管理窗体部件加入到布局管理器对象中;为当前窗体设置该布局管理器。除了可以将窗体部件加入到当前的布局管理器中,还可以将另外一个布局管理器对象加入到当前的布局管理器中;此外,设置布局管理器只需在所有布局管理器都添加好之后进行一次的设置即可。具体使用方法可参考随后给出的示例代码。
在topLayout这个顶部的布局管理器中,我们仅加入一个标签。正如上面所述,我们首先创建一个水平布局管理器对象,再将这个mainlabel标签加入其内。
QHBoxLayout *topLayout = new QHBoxLayout; topLayout->addWidget(ui->mainLabel);
右边的按钮区的布局管理rightBtnLayout和上述类似,只不过我们此时使用的是垂直管理器。接下来重点说一下主窗口区布局管理器widgetLayout的设置。两个子系统和主界面的功能不同,因此将他们分别封装成类configUI、logUI和frontPage,我们依次创建三个类的对象。接下来将这三个部件加入到widgetLayout中。由于客户端初始显示主界面,则我们将其他两个窗体暂时隐藏。
QVBoxLayout *widgetLayout = new QVBoxLayout; configWidget = new configUI(this); logWidget = new logUI(this); mainMenu = new frontPage(this); widgetLayout->addWidget(ui->introTextBrowser); widgetLayout->addWidget(configWidget); widgetLayout->addWidget(logWidget); configWidget->hide(); logWidget->hide();
我们现在已经设置好了rightBtnLayout和widgetLayout,接下来将这两个布局管理器加入到mainWindowLayout中。
QHBoxLayout *mainWindowLayout = new QHBoxLayout; mainWindowLayout->addLayout(widgetLayout); mainWindowLayout->addLayout(rightBtnLayout);
这样mainWindowLayout布局管理器就设置好了。最后我们还需要设置bottomLayout布局管理器,只是简单的添加一个标签和一个水平分割线。
至此,我们拥有三个二级布局管理器:topLayout、mainWindowLayout和bottomLayout,我们将这三个布局管理器全部添加到顶级布局管理器mainLayout中:
QVBoxLayout *mainLayout = new QVBoxLayout; mainLayout->addLayout(topLayout); mainLayout->addLayout(mainWindowLayout); mainLayout->addLayout(bottomLayout); this->adjustSize(); setLayout(mainLayout);
此时,我们就设置好了主界面的布局。
嗯呐 有木有发现controllerPanel 上面的按钮 和 mainPanel 的 按钮是没有对齐的 ? =口= 这个 是界面里面一个很重要的问题 这个是你做有两边的封装层数是不一样的 要么消去层数差别 要么将封装部件的边框的宽度降为0 就可以对齐了
[回复一下]
那几天 做的时候米有修改 直接吧原版本给你了 这里其实可以考虑 QStackedWidget 这个看名字就会觉得很爽了~~~ 有木有!!!有木有!!!!!!
[回复一下]
edsionte 回复:
13 4 月, 2011 at 12:31
@Authur, 我这个其实实在designer中完成的,主要是以后修改方便。
[回复一下]
请问 connect()函数怎么写啊 ? 为什么我做的只能显示主界面呢 ?
[回复一下]
edsionte 回复:
27 12 月, 2012 at 14:32
@chengchen, 麻烦您说具体一些。
[回复一下]