目录
- 一、项目介绍
- 二、项目基本配置
- 三、UI界面设置
- 四、主程序实现
- 4.1 mainwindow.h头文件
- 4.2 mainwindow.cpp源文件
- 4.3 main.cpp
- 五、效果演示
一、项目介绍
本文介绍利用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<MainWindow *>(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()槽函数用于打开最近的文件:
//打开最近文件
void MainWindow::openRecentFile()
{
QAction *action = qobject_cast<QAction *>(sender());
if (action)
loadFile(action->data().toString());
}
about()槽函数显示相关信息:
//about
void MainWindow::about()
{
QMessageBox::about(this, tr("About Recent Files"),
tr("The <b>Recent Files</b> 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 <QApplication>
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;
等价于
QSettings settings("Recently", "Recent Files");
如果之前未调用QCoreApplication::setOrganizationName()和QCoreApplication::setApplicationName(),则QSettings对象将无法读取或写入任何设置,status()将返回AccessError。
五、效果演示
完整效果如下:
ok,以上便是本文的全部内容了,如果对你有所帮助,记得点个赞哟~
参考:https://doc.qt.io/archives/qt-4.8/qt-mainwindows-recentfiles-example.html