Chapter 3. Creating Main Windows
关键词:动作(Action),主窗口(MainWindow),QT资源机制(QT resource mechanism),非模态(modeless),模态(modal),单文档(SDI),多文档(MDI),程序启动画面(splash screen)。
3.1 Subcalssing QMainWindow
图形用户界面(GUI)应用程序通常会使用很多图片。为应用程序提供图片的方法有很多种,如下是一些常用的方法:
- 把图片保存到文件中,并且在运行时载入它们。
- 把XPM文件包含在源代码中,因为XPM文件也是有效的C++文件。
- 使用Qt的资源机制(resource mechanism)。
为了利用Qt的资源机制,必须创建一个资源文件(.qrc),别且在识别该资源文件的.pro文件中加入一行代码,如:
RESOURCES = spreadsheet.qrc
我们将选中的图片存放在源代码树中名为images的子目录下,当引用这些资源时,需要使用带路径前缀:/的形式,如:/images/icon.png。资源可以使是任意类型的文件
3.2 Creating Menus and Toolbars & 3.3 Setting Up the Status Bar
Qt通过“动作”的概念简化了有关菜单和工具栏的编程。一个动作(action)就是一个可以添加到任意数量的菜单(menus)和工具栏(toolbars)上的项。在Qt中,创建菜单和工具栏包括一下这些步骤:
- 创建并且设置动作
- 创建菜单并且把动作添加到菜单上
- 创建工具栏并且吧动作添加到工具栏上
如:
void MainWindow::createActions()
{
newAction = new QAction(tr("&New"), this);
newAction->setIcon(QIcon(":/images/new.png"));
newAction->setShortcut(tr("Ctrl+N"));
newAction->setStatusTip(tr("Create a new spreadsheet file"));
connect(newAction, SIGNAL(triggered()), this, SLOT(newFile()));
...
}
动作New有一个加速键(&New)、一个父对象(主窗口)、一个图片、一个快捷键和一个状态提示。
3.4 Implementing the File Menu & 3.5 Using Dialogs
文件过滤器(file filters)由一个描述文本和一个通配符组成,如果除了要支持Spreadsheet本地文件格式以外,还需要支持采用逗号分隔的数据文件和Lotus 1-2-3文件,就应当使用如下的文件过滤器:
tr("Spreadsheet files (*.sp)\n"
"Comma-separated values files (*.csv)\n"
"Lotus 1-2-3 files (*.wk1 *.wks)")
使用strippedName()函数移除文件名中的路径字符。
QString::arg()函数将会使用自己的参数替换最小数字的%n参数,并且会用它的参数返回结果“%n”字符和最终的结果字符串。
tr("%1[*] - %2").arg(shownName)
.arg(tr("Spreadsheet"))
非模态(modeless)窗口,就是运行在应用程序中对于任何其他窗口都独立的窗口,通过show()调用。
模态(modal)窗口,就是一个在得到调用可以弹出并可以阻塞应用程序的窗口,通过exec()调用。
3.6 Storing Settings & 3.7 Multiple Doucments
QSettings会存储应用程序中与特定平台相关的一些设置信息。QSettings把设置信息存储为键值对(key-value pair)的形式。QSettings类型对象的值(value)可以是一个int、bool、double、QString、QStingList或者是QVariant所支持的其他任意类型,包括那些已经注册过的自定义类型。
MainWindow::MainWindow()
{
...
setAttribute(Qt::WA_DeleteOnClose);
...
}
这样做会告诉Qt在关闭窗口时将其删除。
foreach (QWidget *win, QApplication::topLevelWidgets()) {
if (MainWindow *mainWin = qobject_cast<MainWindow *>(win))
mainWin->updateRecentFileActions();
}
使用foreach结构体来遍历这个应用程序的所有窗口。