在红旗系统中安装QT方法如下
```
sudo apt-get install qt4-dev-tools #开发包
sudo apt-get install qtcreator #IDE
sudo apt-get install qt4-doc #开发帮助文档
sudo apt-get install qt4-qtconfig #配置工具
sudo apt-get install qt4-demos #DEMO源码
```
或者直接从Qt官方网站下载。
1、Qt Creator 是Qt 的集成开发环境(IDE),Qt 5.10.1 是Qt 类库的版本,Qt Creator 4.5.1 是Qt Creator 的版本,类似于 C++11 是 C++语言的版本,Visual C++2015 是IDE 的版本。
2、Qt 的下载地址为:http://download.qt.io/official_releases/qt
3、进入下载页面后选择需要下载的 Qt 版本,本书使用的是 Qt5.10.1,然后会发现 Qt5.10.1
版本还有多个类型的 Qt安装程序下载。
4、安装注意事项:遇到登录或注册 Qt 账号的窗口时,选择“skip”按钮跳过即可,这一步并不影响 Qt 的安装和使用,其余步骤保持默认,直接点击"next"即可。遇到选择组件的步骤时建议全选。
Qt 是一个跨平台的 C++图形用户界面库,说简单点,Qt 的本质就是一个 C++类库,使用Qt 就是怎样使用 Qt 类库中的类及其类中的成员函数的问题。在 QT5中 QML(这是一种声明性语言)和 Qt Quick 成为 Qt 的核心之一,但 C++仍是 QT 的核心。
Qt 是跨平台的,也就是说,使用一个 Qt 开发框架就可以开发出能在桌面、嵌入式、移动等多个平台运行的应用程序,因此一套代码可以运行在各个不同的平台上。从 QT5.6 开始实现了对 Andriod、iOS、winRt 等移动平台的完整支持,目前 Qt 支持 Windows、Linux、macOS、Android、iOS、WinRT 等平台,将现有的 QT 程序移植到这些平台,只需重新编译一次源代码即可。Qt 虽然是使用的 C++语言,但不是使用的标准 C++ ,Qt 进行了一定程度的“扩展”。虽然如此,但 C++仍然是基础。
在发布 Qt 4.6 的同时,作为 Qt 开发跨平台 IDE 的Qt Creator也发布了更新版本。Qt Creator 1.3 和 Qt 4.6共同构成的 Qt SDK,包含了开发跨平台应用程序所需的全部功能。
Qt Creator是一个用于Qt开发的轻量级跨平台集成开发环境。Qt Creator可带来两大关键益处:提供首个专为支持跨平台开发而设计的集成开发环境 (IDE),并确保首次接触Qt框架的开发人员能迅速上手和操作。即使不开发Qt应用程序,Qt Creator也是一个简单易用且功能强大的IDE。
Qt Creator包含了一套用于创建和测试基于Qt应用程序的高效工具,包括:
一个高级的C++代码编辑器 上下文感知帮助系统 可视化调试器 源代码管理 项目和构建管理工具
Qt Creator在LGPL2.1版本授权下有效,并且接受代码贡献。
Qt Linguist
Qt Linguist被称为Qt语言家。它的主要任务只是读取翻译文件、为翻译人员提供友好的翻译界面,它是用于界面国际化的重要工具。
Linguist工具从4.5开始可以支持Gettext的PO文件格式。
1、新建各种文件:
新建一个名称为 qt 的空项目,然后添加一个名为 cs 的 C++源文件,再添加一个 ui 文件,其步骤为:右击项目文件夹 qt,选择“添加新文件”,在对话框的左侧选择“Qt”,右则选择“Qt Designer Form”,在随后弹出的对话框中选择“Dialog without Buttons”(即不含按钮的对话框),在下一步的名称中输入“dg.ui”(名称可任意选择),路径保持默认。最终创建的文件如右图所示
![输入图片说明](http://docs.chinaredflag.cn/uploads/20230826/f4744c28b238ae53c07f4b7db6cf6b9f.png)
2、编辑 ui 文件:双击 ui 文件,进入设计模式界面,
添加标签:在设计模式界面的左侧找到名称为“Label”的部件,然后按住左键不放, 将其拖放到窗口的合适位置。
修改属性:对话框和标签的大小可直接拖放进行修改,也可展开右下侧的 geometry 属性修改。标签名称的修改可以双击该标签然后直接输入名称,也可在标签的 text 属性处修改。
修改对话框对象的名称:为避免使用相同名称产生的混乱,对此将对话框对象的名称修改为 dg1,其方法为, 在右上侧双击对象下的名称(如右图),然后直接输入名称即可,也可在此名称上右击,然后选择“改变对象名称”,也可在 objectName 属性处进行修改。
![输入图片说明](http://docs.chinaredflag.cn/uploads/20230826/4c64c405a301a764dcd7abd16a2bcff2.png)
3、查看 ui 文件:在编辑模式(Ctrl+2)下,右击 ui 文件,选择“用…打开”,此时可看到有如下选项:
界面编辑器和 System Editor:就是使用前面的方法编辑 ui 文件。
普通文本编辑器:此时可看到 ui 文件的内容,该文件是一个 XML 文件,里面是一些关于界面部件的信息。
二进制编辑器:此时可使用二进制的形式查看 ui 文件的内容。
Qt Designer:即 Qt 设计师,这是一个用于设计界面的软件,此时会打开一个“Qt 设计师”软件来编辑 ui 文件。
3、根据 ui 文件生成相应的头文件
此时 C++源文件的内容可以为空。
选择“构建”>“构建所有项目”(或 Ctrl+Shift+B),因为没有 main 函数(源文件为空), 因此会产生错误,但这并不会阻止使用 ui 文件产生出相应的头文件。
头文件的位置:如下图所示
![输入图片说明](http://docs.chinaredflag.cn/uploads/20230826/1a61dec3343d9b4ef748ba17bccfa242.png)
4、由 ui 产生的头文件 ui_dg.h 的内容及意义如下所示
```
#ifndef UI_DG_H //#ifndef、#define、#endif 预处理器用于防止头文件被多次包含#define UI_DG_H
#include //包含了一系列的头文件#include
#include #include #include #include #include
QT_BEGIN_NAMESPACE //Qt 的命名空间开始宏
class Ui_dg1{ public: //定义一个类
QLabel *label; //这就是添加到对话框中的标签
void setupUi(QDialog *dg1){
/*此函数用于生成界面,程序必须调用此函数,才能产生出界
面,也就是说,虽然设计模式能拖放出界面的外观,但还是
要编写代码来调用此函数以生成界面*/。
if (dg1->objectName().isEmpty())
dg1->setObjectName(QStringLiteral("dg1")); //设置对话框的对象名称
dg1->resize(200, 100); //设置对话框的大小
label = new QLabel(dg1); //将标签添加到对话框之上。
label->setObjectName(QStringLiteral("label")); //设置标签的对象名称
label->setGeometry(QRect(60, 50, 54, 12)); //设置标签的位置和大小。
retranslateUi(dg1); //该函数在下面进行了定义。
QMetaObject::connectSlotsByName(dg1);
} //主要用于实现信号和槽相关联。
void retranslateUi(QDialog *dg1)
{ //主要用于对窗口中的字符串进行编码转换。
dg1->setWindowTitle(QApplication::translate("dg1", "Dialog", Q_NULLPTR));
label->setText(QApplication::translate("dg1", "AAA", Q_NULLPTR));
}
};
namespace Ui { class dg1: public Ui_dg1 {};} //定义一个名称空间。QT_END_NAMESPACE //Qt 的命名空间结束宏
#endif
```
5、在 C++源文件中输入如下内容,然后程序即可正确运行,也就是说使用此方法,只需在界面设计器之中设计界面,然后在 C++源文件中编写如下代码就可以了。
```
/*包含由 ui 文件生成的头文件,此处应使用双引号,否则不会在当前目录
搜索头文件。*/
int main(int argc, char *argv[])
{
QApplication a(argc,argv);
QDialog d;
Ui::dg1 ui; //使用名称空间 Ui 中的类 dg1 创建一个对象(Ui 名称空间定义于 ui_dg.h 中)。
ui.setupUi(&d); Call dg1's member function setupUI to generate the interface (that is, the function in the ui_dg.h file).
d.show();
a.exec();
return 0;
}
```
6. The above program can be simplified into the following form of code
```
#include #include #include
class Ui_dg1
{ public:
QLabel *label;
void setupUi(QDialog *dg1){
dg1->resize(200, 100);
label = new QLabel(dg1);
label->setGeometry(QRect(60, 50, 54, 12));
label->setText( "AAA");}
};
int main(int argc, char *argv[])
{
QApplication a(argc,argv);
QDialog d;
Ui_dg1 ui;
ui.setupUi(&d);
d.show();
a.exec();
return 0;
}
```1、新建各种文件:
新建一个名称为 qt 的空项目,然后添加一个名为 cs 的 C++源文件,再添加一个 ui 文件,其步骤为:右击项目文件夹 qt,选择“添加新文件”,在对话框的左侧选择“Qt”,右则选择“Qt Designer Form”,在随后弹出的对话框中选择“Dialog without Buttons”(即不含按钮的对话框),在下一步的名称中输入“dg.ui”(名称可任意选择),路径保持默认。最终创建的文件如右图所示
![输入图片说明](http://docs.chinaredflag.cn/uploads/20230826/f4744c28b238ae53c07f4b7db6cf6b9f.png)
2、编辑 ui 文件:双击 ui 文件,进入设计模式界面,
添加标签:在设计模式界面的左侧找到名称为“Label”的部件,然后按住左键不放, 将其拖放到窗口的合适位置。
修改属性:对话框和标签的大小可直接拖放进行修改,也可展开右下侧的 geometry 属性修改。标签名称的修改可以双击该标签然后直接输入名称,也可在标签的 text 属性处修改。
修改对话框对象的名称:为避免使用相同名称产生的混乱,对此将对话框对象的名称修改为 dg1,其方法为, 在右上侧双击对象下的名称(如右图),然后直接输入名称即可,也可在此名称上右击,然后选择“改变对象名称”,也可在 objectName 属性处进行修改。
![输入图片说明](http://docs.chinaredflag.cn/uploads/20230826/4c64c405a301a764dcd7abd16a2bcff2.png)
3、查看 ui 文件:在编辑模式(Ctrl+2)下,右击 ui 文件,选择“用…打开”,此时可看到有如下选项:
界面编辑器和 System Editor:就是使用前面的方法编辑 ui 文件。
普通文本编辑器:此时可看到 ui 文件的内容,该文件是一个 XML 文件,里面是一些关于界面部件的信息。
二进制编辑器:此时可使用二进制的形式查看 ui 文件的内容。
Qt Designer:即 Qt 设计师,这是一个用于设计界面的软件,此时会打开一个“Qt 设计师”软件来编辑 ui 文件。
3、根据 ui 文件生成相应的头文件
此时 C++源文件的内容可以为空。
选择“构建”>“构建所有项目”(或 Ctrl+Shift+B),因为没有 main 函数(源文件为空), 因此会产生错误,但这并不会阻止使用 ui 文件产生出相应的头文件。
头文件的位置:如下图所示
![输入图片说明](http://docs.chinaredflag.cn/uploads/20230826/1a61dec3343d9b4ef748ba17bccfa242.png)
4、由 ui 产生的头文件 ui_dg.h 的内容及意义如下所示
```
#ifndef UI_DG_H //#ifndef、#define、#endif 预处理器用于防止头文件被多次包含#define UI_DG_H
#include //包含了一系列的头文件#include
#include #include #include #include #include
QT_BEGIN_NAMESPACE //Qt 的命名空间开始宏
class Ui_dg1{ public: //定义一个类
QLabel *label; //这就是添加到对话框中的标签
void setupUi(QDialog *dg1){
/*此函数用于生成界面,程序必须调用此函数,才能产生出界
面,也就是说,虽然设计模式能拖放出界面的外观,但还是
要编写代码来调用此函数以生成界面*/。
if (dg1->objectName().isEmpty())
dg1->setObjectName(QStringLiteral("dg1")); //设置对话框的对象名称
dg1->resize(200, 100); //设置对话框的大小
label = new QLabel(dg1); //将标签添加到对话框之上。
label->setObjectName(QStringLiteral("label")); //设置标签的对象名称
label->setGeometry(QRect(60, 50, 54, 12)); //设置标签的位置和大小。
retranslateUi(dg1); //该函数在下面进行了定义。
QMetaObject::connectSlotsByName(dg1);
} //主要用于实现信号和槽相关联。
void retranslateUi(QDialog *dg1)
{ //主要用于对窗口中的字符串进行编码转换。
dg1->setWindowTitle(QApplication::translate("dg1", "Dialog", Q_NULLPTR));
label->setText(QApplication::translate("dg1", "AAA", Q_NULLPTR));}
};
namespace Ui { class dg1: public Ui_dg1 {};} //定义一个名称空间。QT_END_NAMESPACE //Qt 的命名空间结束宏
#endif
```
5、在 C++源文件中输入如下内容,然后程序即可正确运行,也就是说使用此方法,只需在界面设计器之中设计界面,然后在 C++源文件中编写如下代码就可以了。
```
/*包含由 ui 文件生成的头文件,此处应使用双引号,否则不会在当前目录
搜索头文件。*/
int main(int argc, char *argv[])
{
QApplication a(argc,argv);
QDialog d;
Ui::dg1 ui; //使用名称空间 Ui 中的类 dg1 创建一个对象(Ui 名称空间定义于 ui_dg.h 中)。
ui.setupUi(&d); //调用 dg1 的成员函数 setupUi 生成界面(即 ui_dg.h 文件中的函数)。
d.show();
a.exec();
return 0;
}
```
6、以上程序可简化为如下形式的代码
```
#include #include #include
class Ui_dg1
{ public:
QLabel *label;
void setupUi(QDialog *dg1){
dg1->resize(200, 100);
label = new QLabel(dg1);
label->setGeometry(QRect(60, 50, 54, 12));
label->setText( "AAA");}
};
int main(int argc, char *argv[])
{
QApplication a(argc,argv);
QDialog d;
Ui_dg1 ui;
ui.setupUi(&d);
d.show();
a.exec();
return 0;
}
```
1、新建空项目,双击项目文件(.pro 文件),然后在项目文件中添加如下代码,
greaterThan(QT_MAJOR_VERSION,4):QT += widgets
上述代码表示,若 Qt 版本大于 4,则添加 widgets 模块。因后面的程序需要使用 widgets 模块中的类,所以需要在 pro 文件中添加该模块。使用上述代码主要是为了与 Qt4 兼容, 因此上述代码也可简写为:QT += widgets 。
2、注意:若修改了 pro 文件,建议重新构建该项目文件,否则对项目文件的更改不会反应到程序中,方法为选择“构建”>“重新构建项目 xxx”。
3、添加 C++源文件,然后在源文件中添加如下代码:
#include /*Qt 中的每一个类都有一个与其同名的头文件,因此要使用哪个类,就需要包含相应的头文件*/
```
#include #include
int main(int argc, char *argv[]){
QApplication a(argc,argv); /*任何一个 widgets 程序都需要包含一个 QApplication 对象,该
对象用于管理程序的资源、事件等*/
QDialog d; //创建一个对话框,Qt 使用 QDialog 类对象创建对话框。d.resize(200,100); //设置对话框的大小。
QLabel s(&d); /*创建一个标签,并把该标签放在对话框 d 之中。同理,Qt 使用 QLabel
类对象创建标签*/ s.setText("AAA"); //设置标签显示的文本。s.move(50,50); //设置标签位于对话框中的位置。
d.show(); //显示对话框,默认情况下部件是不可见的,因此需显示。a.exec(); /*程序进入消息(或事件)循环,等待用户的输入并进行响应,这时程序
将控制权交给 Qt 用于完成事件处理。*/
return 0; }
```
![输入图片说明](http://docs.chinaredflag.cn/uploads/20230826/9c3b893fed06f1d986538019be9d55b6.png)
4、验证项目文件的更改:把上例在项目文件中添加的 QT += widgets 代码删除掉,然后保存该项目文件(可使用 Ctrl+S),然后运行程序(Ctrl+R),发现程序仍能正常执行,这说明对项目文件的更改未起作用。此时,选择“构建”>“重新构建项目 xxx”,此时在“问题窗口”(Alt+1),便显示出了产生的错误信息,这说明此时对项目文件的更改才产生作用。
一、案例涉及知识点
窗口、对话框、标签、文本框、按钮、事件处理。
二、案例实现步骤
1、新建一个Qt Widgets Application——MultiWindowDemo
![输入图片说明](http://docs.chinaredflag.cn/uploads/20230826/dcadbe0f1c01fb31ffd1988fd6f7d260.png)
2、创建一个Qt设计师界面类LoginDialog
![输入图片说明](http://docs.chinaredflag.cn/uploads/20230826/6b5c5226fbc91c2853fb9120525f1628.png)
![输入图片说明](http://docs.chinaredflag.cn/uploads/20230826/3220350493f7492f027b2bb8ec8fb029.png)
![输入图片说明](http://docs.chinaredflag.cn/uploads/20230826/6a036c42e78ea81b8306e9af6d08ca63.png)
![输入图片说明](http://docs.chinaredflag.cn/uploads/20230826/91e173bbbf3ac851134db238b8679476.png)
![输入图片说明](http://docs.chinaredflag.cn/uploads/20230826/93f10578dfc6008f8d19db6d24ed2c98.png)
3、设计登录对话框界面
![输入图片说明](http://docs.chinaredflag.cn/uploads/20230826/664d9d15c9f83f47612d5b4dcd61417a.png)
4、选中【登录】按钮,单击右键,选择“转到槽……”,选择clicked()信号
![输入图片说明](http://docs.chinaredflag.cn/uploads/20230826/d7c51a3a663cbdd83100cc9a60e8ef86.png)
5、同理,给【取消】按钮添加单击事件处理槽
![输入图片说明](http://docs.chinaredflag.cn/uploads/20230826/2c8fc9e2ebfd27c9c285aa4f09014689.png)
6、在logindialog.h里添加信号和槽
![输入图片说明](http://docs.chinaredflag.cn/uploads/20230826/c54ce08c7619117b2233f3f5831961b9.png)
```
#ifndef LOGINDIALOG_H
#define LOGINDIALOG_H
#include
namespace Ui {
class LoginDialog;
}
class LoginDialog : public QDialog
{
Q_OBJECT
public:
explicit LoginDialog(QWidget *parent = 0);
~LoginDialog();
signals:
void login(QString username, QString password);
void cancel();
private slots:
void on_btnLogin_clicked();
void on_btnCancel_clicked();
void loginSlot(QString username, QString password);
void cancelSlot();
private:
Ui::LoginDialog *ui;
};
#endif // LOGINDIALOG_H
```
7、修改main.cpp,定义登录对话框作为主窗口的子控件,设置对话框标题,并屏幕居中
![输入图片说明](http://docs.chinaredflag.cn/uploads/20230826/85fb6c233bf1db13b904d049b5c0e03d.png)
```
#include "mainwindow.h"
#include
#include
#include
int main(int argc, char *argv[])
{
QApplication a(argc, argv);
MainWindow w;
w.setWindowTitle("测试系统");
QDesktopWidget *desktop = QApplication::desktop();
LoginDialog login(&w);
login.setWindowTitle("登录");
login.show();
login.move((desktop->width() - login.width())/ 2, (desktop->height() - login.height()) /2);
return a.exec();
}
```
8、修改logindialog.cpp
(1)构造函数里设置密码框显示模式,并且设置信号函数与槽函数之间的联系
![输入图片说明](http://docs.chinaredflag.cn/uploads/20230826/2ede39668820f59fbef23cf89da678fc.png)
(2)编写登录按钮单击事件处理函数
![输入图片说明](http://docs.chinaredflag.cn/uploads/20230826/382e5ed418204779a7afc98c484da1ec.png)
(3)编写取消按钮单击事件处理函数
![输入图片说明](http://docs.chinaredflag.cn/uploads/20230826/2563cf4170256b9172392b1541cde4aa.png)
(4)编写登录槽函数loginSlot
![输入图片说明](http://docs.chinaredflag.cn/uploads/20230826/d0a1179ab9969f003b18cb6b9fae578a.png)
(5)编写取消槽函数cancelSlot
![输入图片说明](http://docs.chinaredflag.cn/uploads/20230826/6e1483595d349cb279614a736ced975c.png)
logindialog.cpp完整代码:
```
#include "logindialog.h"
#include "ui_logindialog.h"
#include "mainwindow.h"
#include "qmessagebox.h"
LoginDialog::LoginDialog(QWidget *parent) :
QDialog(parent),
ui(new Ui::LoginDialog)
{
ui->setupUi(this);
// 设置密码框显示模式
ui->edtPassword->setEchoMode(QLineEdit::Password);
// 设置信号函数与槽函数之间的联系
connect(this, &LoginDialog::login, this, &LoginDialog::loginSlot);
connect(this, &LoginDialog::cancel, this, &LoginDialog::cancelSlot);
}
LoginDialog::~LoginDialog()
{
delete ui;
}
void LoginDialog::on_btnLogin_clicked()
{
QString username = ui->edtUsername->text();
QString password = ui->edtPassword->text();
emit login(username, password);
}
void LoginDialog::on_btnCancel_clicked()
{
emit cancel();
}
void LoginDialog::loginSlot(QString username, QString password)
{
// 非空校验
if (username.trimmed().length() == 0) {
QMessageBox::information(this, "提示", "用户名不能为空!");
ui->edtUsername->setFocus();
return;
}
if (password.trimmed().length() == 0) {
QMessageBox::information(this, "提示", "密码不能为空!");
ui->edtPassword->setFocus();
return;
}
// 用户合法性判断
if (username == "howard" && password == "903213") {
QMessageBox::information(this, "提示", "恭喜,登录成功!");
parentWidget()->show();
this->hide();
} else {
QMessageBox::information(this, "提示", "遗憾,登录失败!");
}
}
void LoginDialog::cancelSlot()
{
Clear the User Name and Password text boxes
ui->edtUsername->setText("");
ui->edtPassword->setText("");
Let the user name text box get focus
ui->edtUsername->setFocus();
}
```
9、运行程序,查看效果
![输入图片说明](http://docs.chinaredflag.cn/uploads/20230826/a8814764e6c4e9ed78eb2c566e719944.png)
不输入用户名和密码就单击【登录】按钮:
![输入图片说明](http://docs.chinaredflag.cn/uploads/20230826/5033c62dd77037ecb99f2e7e39851197.png)
输入用户名,但是不输入密码,单击【登录】按钮
![输入图片说明](http://docs.chinaredflag.cn/uploads/20230826/cc9fdbd0b403d81215e0679ba6572c84.png)
![输入图片说明](http://docs.chinaredflag.cn/uploads/20230826/cc9fdbd0b403d81215e0679ba6572c84.png)
![输入图片说明](http://docs.chinaredflag.cn/uploads/20230826/8ef05e1ac67f2ba323b288752385adaa.png)
如果在登录对话框里输入错误的用户名或密码,单击【登录】按钮:
![输入图片说明](http://docs.chinaredflag.cn/uploads/20230826/82ec7ebf0d1edaae87ee54fe4127bf9c.png)
一、项目介绍
本文介绍利用Qt实现打开最近文档功能,并实现基本的新建、打开、保存、退出、帮助等功能。
二、项目基本配置
新建一个Qt案例,项目名称为“RecentTest”,基类选择“QMainWindow”,取消选中创建UI界面复选框,完成项目创建。
三、UI界面设置
无UI界面
四、主程序实现
4.1 mainwindow.h头文件
头文件中需要声明若干槽函数和相应函数:
```
private slots:
void newFile();
void open();
void save();
void saveAs();
void openRecentFile();
void about();
private:
void createActions();
void createMenus();
void loadFile(const QString &fileName);
void saveFile(const QString &fileName);
void setCurrentFile(const QString &fileName);
void updateRecentFileActions();
QString strippedName(const QString &fullFileName);
QString curFile;
QTextEdit *textEdit;
QMenu *fileMenu;
QMenu *recentFilesMenu;
QMenu *helpMenu;
QAction *newAct;
QAction *openAct;
QAction *saveAct;
QAction *saveAsAct;
QAction *exitAct;
QAction *aboutAct;
QAction *aboutQtAct;
QAction *separatorAct;
//设置最大最近文件为5个
enum { MaxRecentFiles = 5 };
QAction *recentFileActs[MaxRecentFiles];
```
4.2 mainwindow.cpp源文件
需要在构造函数中添加如下代码:
```
setAttribute(Qt::WA_DeleteOnClose);//当关闭时删除该组件
textEdit = new QTextEdit;//新建TextEdit
setCentralWidget(textEdit);//设为中心部件
createActions();
createMenus();
(void)statusBar();//增加状态栏
setWindowFilePath(QString());
resize(400, 300);//调整尺寸大小
```
构造函数中的createActions()函数用于创建相应的行为,创建了New、Open、Save、Save As、最近5个文件、Exit、About和About Qt这几个Action,并设置相应的快捷键、状态栏和连接槽函数:
//创建action
```
void MainWindow::createActions()
{
newAct = new QAction(tr("&New"), this);//new
newAct->setShortcuts(QKeySequence::New);//设置快捷键
newAct->setStatusTip(tr("Create a new file"));//设置状态栏
connect(newAct, SIGNAL(triggered()), this, SLOT(newFile()));
openAct = new QAction(tr("&Open..."), this);//open
openAct->setShortcuts(QKeySequence::Open);//设置快捷键
openAct->setStatusTip(tr("Open an existing file"));//设置状态栏
connect(openAct, SIGNAL(triggered()), this, SLOT(open()));
saveAct = new QAction(tr("&Save"), this);//save
saveAct->setShortcuts(QKeySequence::Save);//设置快捷键
saveAct->setStatusTip(tr("Save the document to disk"));//设置状态栏
connect(saveAct, SIGNAL(triggered()), this, SLOT(save()));
saveAsAct = new QAction(tr("Save &As..."), this);//save as
saveAsAct->setShortcuts(QKeySequence::SaveAs);//设置快捷键
saveAsAct->setStatusTip(tr("Save the document under a new name"));//设置状态栏
connect(saveAsAct, SIGNAL(triggered()), this, SLOT(saveAs()));
//5个Action(打开最近五个文件)
for (int i = 0; i < MaxRecentFiles; ++i) {
recentFileActs[i] = new QAction(this);
recentFileActs[i]->setVisible(false);
connect(recentFileActs[i], SIGNAL(triggered()),
this, SLOT(openRecentFile()));
}
exitAct = new QAction(tr("E&xit"), this);//exit
exitAct->setShortcuts(QKeySequence::Quit);//设置快捷键
exitAct->setStatusTip(tr("Exit the application"));//设置状态栏
connect(exitAct, SIGNAL(triggered()), qApp, SLOT(closeAllWindows()));
aboutAct = new QAction(tr("&About"), this);//about
aboutAct->setStatusTip(tr("Show the application's About box"));//设置状态栏
connect(aboutAct, SIGNAL(triggered()), this, SLOT(about()));
aboutQtAct = new QAction(tr("About &Qt"), this);//About &Qt
aboutQtAct->setStatusTip(tr("Show the Qt library's About box"));//设置状态栏
connect(aboutQtAct, SIGNAL(triggered()), qApp, SLOT(aboutQt()));
}
```
newFile()槽函数用于新建一个相同的窗口:
//新建界面并显示
```
void MainWindow::newFile()
{
MainWindow *other = new MainWindow;
other->show();
}
```
open()槽函数用于打开并加载文档:
//打开文件
```
void MainWindow::open()
{
QString fileName = QFileDialog::getOpenFileName(this);
if (!fileName.isEmpty())
loadFile(fileName);
}
```
loadFile()函数:
//加载文件
```
void MainWindow::loadFile(const QString &fileName)
{
QFile file(fileName);
if (!file.open(QFile::ReadOnly | QFile::Text)) {
QMessageBox::warning(this, tr("Recent Files"),
tr("Cannot read file %1:\n%2.")
.arg(fileName)
.arg(file.errorString()));
return;
}
QTextStream in(&file);
QGuiApplication::setOverrideCursor(Qt::WaitCursor);//等待光标
textEdit->setPlainText(in.readAll());//设置文本
QGuiApplication::restoreOverrideCursor();//撤销最后一个光标
setCurrentFile(fileName);
statusBar()->showMessage(tr("File loaded"), 2000);
}
```
setCurrentFile()函数用于设置当前文件关联路径:
```
//设置当前文件
void MainWindow::setCurrentFile(const QString &fileName)
{
curFile = fileName;
setWindowFilePath(curFile);//设置关联文件路径
QSettings settings;
QStringList files = settings.value("recentFileList").toStringList();
files.removeAll(fileName);//移除所有文件名
files.prepend(fileName);//在开头附加子串
//如果尺寸超过最大尺寸,则删除最后一项
while (files.size() > MaxRecentFiles)
files.removeLast();
settings.setValue("recentFileList", files);//设置键值对
foreach (QWidget *widget, QApplication::topLevelWidgets()) {
MainWindow *mainWin = qobject_cast(widget);
if (mainWin)
mainWin->updateRecentFileActions();//更新最近文件
}
}
```
updateRecentFileActions()函数更新最近文件信息
```
void MainWindow::updateRecentFileActions()
{
QSettings settings;
QStringList files = settings.value("recentFileList").toStringList();//读取recentFileList的值
int numRecentFiles = qMin(files.size(), (int)MaxRecentFiles);//计算两者的最小值
for (int i = 0; i < numRecentFiles; ++i) {
QString text = tr("&%1 %2").arg(i + 1).arg(strippedName(files[i]));//序号 文件名
recentFileActs[i]->setText(text);//设置文本
recentFileActs[i]->setData(files[i]);//设置数据
recentFileActs[i]->setVisible(true);//设置可见性
}
for (int j = numRecentFiles; j < MaxRecentFiles; ++j)
recentFileActs[j]->setVisible(false);//其他数量设置为不可见
separatorAct->setVisible(numRecentFiles > 0);//如果有最近未见则设置分隔符为可见
}
```
strippedName()函数用于获取相应的文件名:
//获取文件名
```
QString MainWindow::strippedName(const QString &fullFileName)
{
return QFileInfo(fullFileName).fileName();//返回文件名
}
```
save()函数和saveAs()槽函数用于将文档进行保存:
```
//保存文件
void MainWindow::save()
{
if (curFile.isEmpty())
saveAs();//如果curFile为空,则设置保存为
else
saveFile(curFile);
}
//保存为
void MainWindow::saveAs()
{
QString fileName = QFileDialog::getSaveFileName(this);
if (fileName.isEmpty())
return;
saveFile(fileName);
}
```
saveFile()函数:
```
void MainWindow::saveFile(const QString &fileName)
{
QFile file(fileName);
if (!file.open(QFile::WriteOnly | QFile::Text)) {
QMessageBox::warning(this, tr("Recent Files"),
tr("Cannot write file %1:\n%2.")
.arg(fileName)
.arg(file.errorString()));
return;
}
QTextStream out(&file);
QGuiApplication::setOverrideCursor(Qt::WaitCursor);//等待光标
out << textEdit->toPlainText();//将文本写入
QGuiApplication::restoreOverrideCursor();//撤销最后一个光标
setCurrentFile(fileName);
statusBar()->showMessage(tr("File saved"), 2000);//状态栏显示2000ms
}
```
openRecentFile()槽函数用于打开最近的文件:
```
//about
void MainWindow::about()
{
QMessageBox::about(this, tr("About Recent Files"),
tr("The Recent Files example demonstrates how to provide a "
"recently used file menu in a Qt application."));
}
```
构造函数中的createMenus()函数用于创建相应的菜单栏:
```
void MainWindow::createMenus()
{
fileMenu = menuBar()->addMenu(tr("&File"));
fileMenu->addAction(newAct);
fileMenu->addAction(openAct);
fileMenu->addAction(saveAct);
fileMenu->addAction(saveAsAct);
separatorAct = fileMenu->addSeparator();//增加分隔符
for (int i = 0; i < MaxRecentFiles; ++i)
fileMenu->addAction(recentFileActs[i]);
fileMenu->addSeparator(); //增加分隔符
fileMenu->addAction(exitAct);
updateRecentFileActions();
menuBar()->addSeparator();
helpMenu = menuBar()->addMenu(tr("&Help"));
helpMenu->addAction(aboutAct);
helpMenu->addAction(aboutQtAct);
}
```
4.3 main.cpp
main.cpp中代码如下:
```
#include "mainwindow.h"
#include
int main(int argc, char *argv[])
{
QApplication a(argc, argv);
a.setOrganizationName("Recently"); //设置组织名称
a.setApplicationName("Recent Files"); //设置标题名称
MainWindow w;
w.show();
return a.exec();
}
```
在mainwindow.cpp中QSettings settings;语句用于构造QSettings对象。
```
QCoreApplication::setOrganizationName("Recently"); //设置组织名称
QCoreApplication::setApplicationName("Recent Files"); //设置标题名称
QSettings settings;
```
![输入图片说明](http://docs.chinaredflag.cn/uploads/20230826/708e9e764f2c6ffadf38320d36b0752e.png)