Qt实现最近打开文件功能

mainwindow.h 

#ifndef MAINWINDOW_H
#define MAINWINDOW_H

#include <QMainWindow>
#include <QMenuBar>
#include <QMenu>
#include <QSettings>
#include <QFileDialog>
#include <QMessageBox>
#include <QApplication>
#include <QLabel>
#include <QActionEvent>

class MainWindow : public QMainWindow
{
    Q_OBJECT

public:
    MainWindow(QWidget *parent = Q_NULLPTR);

private:
    QMenu* fileMenu;
    QMenu* recentFilesMenu;

    QAction* openAction;
    QList<QAction*> recentFileActionList;
    const int maxFileNr;

    QString currentFilePath;
    QLabel *imageLabel;

    void loadFile(const QString& filePath);
    void adjustForCurrentFile(const QString& filePath);
    void updateRecentActionList();
};

#endif // MAINWINDOW_H

mainwindow.cpp 

#include "mainwindow.h"

MainWindow::MainWindow(QWidget *parent)
    : QMainWindow(parent), maxFileNr(4)
{
    imageLabel = new QLabel;
    setCentralWidget(imageLabel);

    // createActionsAndConnections
    openAction = new QAction(tr("&Open..."), this);
    openAction->setShortcuts(QKeySequence::Open);
    connect(openAction, &QAction::triggered, this, [=]()
    {
        QString filePath = QFileDialog::getOpenFileName(
                           this, tr("Open File"), "",
                           tr("Images (*.png *.xpm *.jpg *.gif)"));
            if (!filePath.isEmpty())
                loadFile(filePath);
    });

    QAction* recentFileAction = nullptr;
    for(auto i = 0; i < maxFileNr; ++i){
        recentFileAction = new QAction(this);
        recentFileAction->setVisible(false);
        connect(recentFileAction, &QAction::triggered, this, [=]()
        {
            loadFile(recentFileAction->data().toString());
        });
        recentFileActionList.append(recentFileAction);
    }

    // create menus
    fileMenu = menuBar()->addMenu(tr("&File"));
    fileMenu->addAction(openAction);

    recentFilesMenu = fileMenu->addMenu(tr("Open Recent"));
    for(auto i = 0; i < maxFileNr; ++i)
        recentFilesMenu->addAction(recentFileActionList.at(i));

    updateRecentActionList();

    resize(350, 250);
}

void MainWindow::loadFile(const QString &filePath){
    QFile file(filePath);

    if (!file.open(QFile::ReadOnly)) {
        QMessageBox::warning(this, tr("Recent Files Example"),
                             tr("This file could not be found:\n%1.")
                             .arg(filePath));
        return;
    }

    QPixmap pMap(filePath);
    if (pMap.isNull()) {
        QMessageBox::information(this, tr("Recent Files Example"),
                      tr("Cannot load:\n%1.")
                      .arg(filePath));
        return;
    }

    imageLabel->setPixmap(pMap);
    imageLabel->setAlignment(Qt::AlignCenter);
    adjustForCurrentFile(filePath);
}

void MainWindow::adjustForCurrentFile(const QString &filePath){
    currentFilePath = filePath;
    setWindowFilePath(currentFilePath);

    QSettings settings;
    QStringList recentFilePaths = settings.value("recentFiles").toStringList();
    recentFilePaths.removeAll(filePath);
    recentFilePaths.prepend(filePath);
    while (recentFilePaths.size() > maxFileNr)
        recentFilePaths.removeLast();
    settings.setValue("recentFiles", recentFilePaths);

    // see note
    updateRecentActionList();
}

void MainWindow::updateRecentActionList(){
    QSettings settings;
    QStringList recentFilePaths = settings.value("recentFiles").toStringList();

    auto itEnd = 0;
    if(recentFilePaths.size() <= maxFileNr)
        itEnd = recentFilePaths.size();
    else
        itEnd = maxFileNr;

    for (auto i = 0; i < itEnd; ++i) {
        QString strippedName = QFileInfo(recentFilePaths.at(i)).fileName();
        recentFileActionList.at(i)->setText(strippedName);
        recentFileActionList.at(i)->setData(recentFilePaths.at(i));
        recentFileActionList.at(i)->setVisible(true);
    }

    for (auto i = itEnd; i < maxFileNr; ++i)
        recentFileActionList.at(i)->setVisible(false);
}

 

main.cpp

#include "mainwindow.h"
#include <QApplication>

int main(int argc, char *argv[])
{
    // 生成注册表信息
    QCoreApplication::setOrganizationName(QString("Digia"));
    QCoreApplication::setApplicationName(QString("Qt"));

    QApplication a(argc, argv);
    MainWindow w;
    w.show();

    return a.exec();
}

 

 

Qt官方Demo

https://doc.qt.io/archives/qt-4.8/qt-mainwindows-recentfiles-example.html

MainWindow.h

#ifndef MAINWINDOW_H
#define MAINWINDOW_H

#include <QList>
#include <QMainWindow>

class QAction;
class QMenu;
class QTextEdit;

class MainWindow : public QMainWindow
{
	Q_OBJECT

public:
	MainWindow();

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;

	enum { MaxRecentFiles = 5 };
	QAction* recentFileActs[MaxRecentFiles];
};

#endif

MainWindow.cpp

#include "mainwindow.h"
#include <QtGui>
#include <QTextEdit>
#include <QAction>
#include <QFileDialog>
#include <QApplication>
#include <QMenu>
#include <QMessageBox>
#include <QMenuBar>
#include <QStatusBar>


MainWindow::MainWindow()
{
	setAttribute(Qt::WA_DeleteOnClose);

	textEdit = new QTextEdit;
	setCentralWidget(textEdit);

	createActions();
	createMenus();
	(void)statusBar();

	setWindowFilePath(QString());
	resize(400, 300);
}

void MainWindow::newFile()
{
	MainWindow* other = new MainWindow;
	other->show();
}

void MainWindow::open()
{
	QString fileName = QFileDialog::getOpenFileName(this);
	if (!fileName.isEmpty())
		loadFile(fileName);
}

void MainWindow::save()
{
	if (curFile.isEmpty())
		saveAs();
	else
		saveFile(curFile);
}

void MainWindow::saveAs()
{
	QString fileName = QFileDialog::getSaveFileName(this);
	if (fileName.isEmpty())
		return;

	saveFile(fileName);
}

void MainWindow::openRecentFile()
{
	QAction* action = qobject_cast<QAction*>(sender());
	if (action)
		loadFile(action->data().toString());
}

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."));
}

void MainWindow::createActions()
{
	newAct = new QAction(tr("&New"), this);
	newAct->setShortcuts(QKeySequence::New);
	newAct->setStatusTip(tr("Create a new file"));
	connect(newAct, SIGNAL(triggered()), this, SLOT(newFile()));

	openAct = new QAction(tr("&Open..."), this);
	openAct->setShortcuts(QKeySequence::Open);
	openAct->setStatusTip(tr("Open an existing file"));
	connect(openAct, SIGNAL(triggered()), this, SLOT(open()));

	saveAct = new QAction(tr("&Save"), this);
	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);
	saveAsAct->setShortcuts(QKeySequence::SaveAs);
	saveAsAct->setStatusTip(tr("Save the document under a new name"));
	connect(saveAsAct, SIGNAL(triggered()), this, SLOT(saveAs()));

	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);
	exitAct->setShortcuts(QKeySequence::Quit);
	exitAct->setStatusTip(tr("Exit the application"));
	connect(exitAct, SIGNAL(triggered()), qApp, SLOT(closeAllWindows()));

	aboutAct = new QAction(tr("&About"), this);
	aboutAct->setStatusTip(tr("Show the application's About box"));
	connect(aboutAct, SIGNAL(triggered()), this, SLOT(about()));

	aboutQtAct = new QAction(tr("About &Qt"), this);
	aboutQtAct->setStatusTip(tr("Show the Qt library's About box"));
	connect(aboutQtAct, SIGNAL(triggered()), qApp, SLOT(aboutQt()));
}

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

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);
	QApplication::setOverrideCursor(Qt::WaitCursor);
	textEdit->setPlainText(in.readAll());
	QApplication::restoreOverrideCursor();

	setCurrentFile(fileName);
	statusBar()->showMessage(tr("File loaded"), 2000);
}

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);
	QApplication::setOverrideCursor(Qt::WaitCursor);
	out << textEdit->toPlainText();
	QApplication::restoreOverrideCursor();

	setCurrentFile(fileName);
	statusBar()->showMessage(tr("File saved"), 2000);
}

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();
	}
}

void MainWindow::updateRecentFileActions()
{
	QSettings settings;
	QStringList files = settings.value("recentFileList").toStringList();

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

QString MainWindow::strippedName(const QString& fullFileName)
{
	return QFileInfo(fullFileName).fileName();
}

 

  • 6
    点赞
  • 16
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
您好!感谢您的提问。下面是用QML实现最近打开文件功能的一种方式。 首先,在QML中创建一个ListView来显示最近打开文件列表,代码如下: ``` ListView { id: recentFilesList model: recentFilesModel delegate: Rectangle { width: parent.width height: 30 color: index % 2 === 0 ? "#f2f2f2" : "#ffffff" Text { text: fileName anchors.verticalCenter: parent.verticalCenter anchors.left: parent.left leftPadding: 10 } MouseArea { anchors.fill: parent onClicked: { openFile(fileName) } } } } ``` 其中,recentFilesModel是一个ListModel,用于存储最近打开文件路径和文件名。delegate是用来定义每一项的显示样式和点击事件的。这里我们使用一个矩形来实现每一项,包括一个文本标签用于显示文件名,以及一个鼠标区域用于响应点击事件。 然后,在QML中定义一个JavaScript函数openFile,用于打开选中的文件,代码如下: ``` function openFile(fileName) { // 打开文件的逻辑代码 } ``` 这里的代码需要根据具体的需求来实现打开文件的逻辑,例如使用Qt中的QFile和QTextStream类来读取文件内容。 最后,在QML中添加一个按钮或者菜单项,用于触发打开最近文件列表的操作,代码如下: ``` Button { text: "最近打开文件" onClicked: { showRecentFilesList() } } function showRecentFilesList() { // 显示最近打开文件列表的逻辑代码 } ``` 这里的代码需要根据具体的需求来实现显示最近文件列表的逻辑,例如使用Qt中的QDialog类来实现一个对话框来显示最近文件列表。 以上就是用QML实现最近打开文件功能的一种方式。希望能对您有所帮助。如果您有任何问题,请随时追问。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值