第3章 创建主窗口
应用程序完整的用户界面,包括菜单、工具栏、状态栏、以及应用程序所需的足够多的对话框。
- 子类化QMainWindow
通过子类化QMainWindow,可以创建一个应用程序主窗口。QDialog和QMainWindow都派生自QWidget类。
setCentralWidget(Qwidget *)函数可以将窗口部件设置为主窗口的中央窗口部件。
setWindowIcon(QIcon(“:/images/icon.png”))该函数设置显示在窗口左上角的图标为icon.png。Qt支持BMP、GIF、JPEG、PNG、XPM等图像格式。
为应用程序提供图片的方法有很多,在这里使用了Qt的资源机制(resource mechanism)法。它比运行时载入文件的方法更方便,并且该方法适用于所支持的任意文件格式。
为了利用Qt的资源系统 (resource system),需要创建一个资源文件(resource file),并在识别该资源文件的 .pro 文件中添加一行代码:RESOURCES = xxx.qrc(资源文件名,资源文件自身使用了一种简单的XML文件格式)。所有资源文件都会被编译到应用程序的可执行文件中。
当引用这些资源时,需要使用带路径的前缀“:/”形式(例如::/images/icon.png,表示图像icon.png存放在源代码树中名为images的子目录下)。另外,资源可以是任意类型的文件,并非只是一些图像。
3. 创建菜单和工具栏
1)通用步骤:创建并且设置动作 -> 创建菜单并且把动作添加到菜单上 -> 创建工具栏并且把动作添加到工具栏上
(一个动作(action)就是一个可以添加到任意数量的菜单和工具栏上的项)
2)创建动作:
newAction = new QAction(tr(“&New”),this);
connect(newAction,SIGNAL(triggered()),this,SLOT(newFile()));
//将动作newAction的triggered()信号连接到主窗口的私有槽newFile()。--->>triggered意为“触发”
3)创建菜单:
fileMenu = menuBar()->addMenu(tr(“&File”)); //在菜单栏中创建菜单(在第一次调用menuBar()函数时会产生菜单栏)
fileMenu->addAction(newAction); //向菜单中添加动作
fileMenu->addSeparator();//向菜单中添加间隔
在Qt中菜单都是QMenu的实例,addMenu()函数可以用给定的文本创建一个菜单窗口部件,并把它添加到菜单栏中。QMainWindow::menuBar()函数返回一个指向QMenuBar的指针。
还可以在希望出现子菜单的地方使用QMenu::addMenu()函数添加子菜单,子菜单与它所属的菜单一样,也是一个QMenu。代码如下:
editMenu = menuBar()->addMenu(tr(“&Edit”));
selectSubMenu = editMenu -> addMenu( tr(“&Select”));
4)创建工具栏:
fileToolBar = addToolBar(tr(“&File”)); // 创建工具栏
fileToolBar->addAction(newAction); //向工具栏中添加动作
- 设置状态栏
通常情况下,状态栏包括两个状态指示器:当前单元格的位置和当前单元格中的公式。
statusBar()->addWidget(label);
QMainWindow::statusBar()函数返回一个指向状态栏的指针(在第一次调用statusBar()函数时会创建状态栏)。状态栏指示器是一些简单的QLabel,可以在任何需要的时候改变他们的文本。
当把这些QLabel添加到状态栏的时候,它们会自动被重定义父对象,以便它们成为状态栏的子对象。
- 实现File菜单
1)QMessageBox类提供了消息框函数,如warning()(警告)、information()(信息)、question()(提问)、critical()(严重错误)。
用法:QMessageBox:: warning(parent,title,message,buttons);四个参数依次是:父窗口部件,消息框标题,消息框内容,按钮。
int r = QMessageBox::warning(this, tr("Spreadsheet"), tr("The document has been modified.\n Do you want to save your changes?"), QMessageBox::Yes|QMessageBox::No|QMessageBox::Cancel);
QMessageBox类提供了许多标准按钮,如:QMessageBox::Yes、QMessageBox::No、QMessageBox::Cancel。如果用户没有自定义消息框的默认按钮,QMessageBox类还会会自动设置消息框默认确认按钮(在用户按下Enter键时激活)
2) 系统提供的QFileDialog::getOpenFileName()静态函数,这个函数会弹出一个文件对话框,让用户选择一个文件,并且返回这个文件的文件名。如果用户点了Cancel按钮,则返回一个空字符串。
用法:
QString fileName = QFileDialog::getOpenFileName(this,tr("Open Spreadsheet"),".",tr("Spreadsheet files(*.sp)"));
第一个参数是父窗口部件。对话框的父子对象关系与其他窗口部件的父子对象关系意义并不完全相同。对话框通常都拥有自主权,但是如果它有父对象,那么在默认情况下,它就会居中放到父对象上。
第二个参数是对话框的标题。
第三个参数是告诉对话框应当从哪个目录开始,在这里“.”表示当前目录。
第四个参数指定了文件过滤器。文件过滤器由一个描述文本和一个通配符组成。如果要过滤多个格式,需要在描述文本和通配符之后加上“\n”。如:
tr("Spreadsheet files (*.sp)\n"
"Comma-separated values files (*.csv)");
3)当用户单击窗口标题栏中的关闭按钮时,将会调用QWidget::close( )槽。
关闭一个窗口后,Qt默认只会隐藏该窗口,但该窗口中的部件占用的内存仍然存在(程序中释放掉的除外)。
如果需要,通过在构造函数中对Qt::WA_DeleteOnClose的属性进行设置: setAttribute(Qt::WA_DeleteOnClose); 这样做就会告诉Qt在关闭窗口时将其删除。
只有当关闭最后一个窗口时,这个应用程序才结束。此时,操作系统会回收尚未被释放的内存。
如果需要,通过把QApplication的quitOnLastWindowClosed属性设置为false,可以禁用这种行为。在这种情况下,该应用程序将会持续保持运行,指导调用QApplication::quit( )函数,程序才结束。
4)QString::arg()函数会使用自己的参数替换前面最小数字的“%n”参数。例如:
tr("%1[*]-%2").arg(shownName).arg(tr("Spreadsheet"));
第一个arg()调用替换参数“%1”,第二个arg()调用则会替换参数“%2”。上述代码等价于shownName + tr("[*] - Spreadsheet"); 但使用arg()函数可以为翻译人员提供更多的灵活性。
5)QObject::sender()函数可以查出是哪个特有动作调用了这个槽(返回指向 发送信号的控件 的指针)。
qobject_cast()函数可在Qt的moc所生成的元信息基础上执行动态类型强制转换。它返回一个指向所需QObject子类的指针,或是在该对象不能被转换成所需的那种类型时返回0。
- 使用对话框
1)非模态对话框(modeless)
运行在应用程序中对任何其他窗口都独立的对话框,非模态对话框可以与其他窗口之间进行切换。(创建非模态对话框时,通常会把它的信号连接到能够对用户的交互做出响应的那些槽上)。
2) 模态对话框(model)
在得到调用后可以弹出并可以阻塞应用程序的窗口,从而会从调用发生开始起妨碍其他的任意处理或交互操作,直到关闭该窗口为止。
如果对话框是通过show()调用的,那么它就是非模态对话框(除非此后又调用了setModel(),才会让它变为模态对话框)。如果对话框是通过exec()调用的,那么该对话框就是模态对话框。
QDialog::exec()函数:如果对话框被接受,该函数可返回一个true值(QDialog::Accepted),否则就会返回一个false值(QDialog::Rejected)。
- 存储设置
默认情况下,QSettings会存储应用程序中与特定平台相关的一些设置信息,如:主窗口的几何形状(位置和尺寸大小)、最近打开的文件列表、各个选项的设置值等。在Windows系统中它使用的是系统注册表;在UNIX系统中它会把设置信息存储在文本文件中;
QSettings的构造函数的参数说明了组织的名字和应用程序的名字。如:
QSettings settings("Software Inc.","Spreadsheet"); //采用与平台相关的方式,可以利用这一信息查找这些设置所在的位置。
QSettings把设置信息存储为键值对(Key-Value pair)的形式。键(Key)与文件系统的路径很类似,可以使用路径形式的语法(例如,findDialog/matchCase)来指定子键(subkey)的值,或者也可以使用beginGroup( )和endGroup( )的形式。例如:
settings.setValue("findDialog/matchCase", caseCheckBox->isChecked() );
与
settings.beginGroup("findDialog");
settings.setValue("matchCase", caseCheckBox->isChecked() );
settings.endGroup();
值(value)可以是一个int, bool, double, QString, QStringList或者是QVariant所支持的其他任意类型,包括哪些已经注册过的自定义类型。
如果要读取之前保存的设置值,可以使用value()函数。如:
settings.setValue( "showGrid", showGridAction->isChecked() );
bool showGrid = settings.value("showGrid", ture).toBool(); //value()函数中的第二个参数可以在没有可用设置的情况下指定所需的默认值。在应用程序第一次运行时,使用的就是这些默认值。
showGridAction->setChecked(showGrid);
上一篇:QT学习笔记(二)https://blog.csdn.net/weixin_44787158/article/details/99087304
下一篇:QT学习笔记(四)https://blog.csdn.net/weixin_44787158/article/details/99105689