暂无相关内容

QT 安装

在红旗系统中安装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官方网站下载。

Qt Creator 的使用

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 简介

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文件格式。

界面编辑器编写 Qt 程序

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; } ```

第一个QT程序

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实现打开最近文档功能,并实现基本的新建、打开、保存、退出、帮助等功能。 二、项目基本配置 新建一个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)