在QT5窗口菜单中实现最近打开的文件功能 | 您所在的位置:网站首页 › maya最近打开文件在哪看啊 › 在QT5窗口菜单中实现最近打开的文件功能 |
首先来看下效果: 点击这些最近的文件能马上打开,比如点击SS.stp: 关键代码: 新建一个类,类名为RecentFiles,继承QObject,具体的.h文件(RecentFiles.h)如下,读者可以自行理解: #ifndef RECENTFILES_H #define RECENTFILES_H #include #include #include #include class QMenu; class QAction; #define recentFileCount "OCCADrecentFiles/numOfRecentFiles" #define recentFileListId "OCCADrecentFiles/fileList" /** * @brief The RecentFiles class manages a list of recently accessed files. * * It handles user-settable number of most recently accessed files, provides * a sub-menu that allows the user to select recently used files for opening. */ class RecentFiles : public QObject { Q_OBJECT public: explicit RecentFiles(QMainWindow *parent=NULL); /* Parent mainwindow, just for proper heirarchy, not actually used outside QObject constr */ ~RecentFiles(); /// Inserts the sub-menu into another Menu /// param menu The parent menu where the sub-menu should be inserted /// param text Text of menu item after which Recent menu is inserted void attachToMenuAfterItem(QMenu *menu, QString text, const char *slotName); QStringList getRecentFiles() const; ///< application calls this to get list of recent files void setMostRecentFile(const QString fileName); ///< called when each new file is opened QString strippedName(const QString &fullFileName); ///< returns filename from full path void setMenuEnabled(bool tf); /// returns how many recent files are being remenbered. see setNumOfRecentFiles() int numberOfRecentFilesToSave(); static const int MaxRecentFiles = 6; ///< Max number of names we keep. public slots: /// The application can set the number of recent files retained/reported here void setNumOfRecentFiles(int n); signals: void openFile(QString fileName); ///< emitted when user selects item from "Open Recent" sub-menu void newMaxFilesShown(int); ///< tells observers that the number of recent files being remembered has changed. private slots: void openRecentFile(); ///< menu items signal this when user selects item from "Open Recent" sub-menu private: void purgeMissingFilesFromList(QStringList &recentFileList); void updateRecentFiles(QSettings &settings); ///< call this with each new filename QMenu *m_recentMenu; QAction *m_recentMenuTriggeredAction; QAction *m_recentFileActions[MaxRecentFiles]; ///< QActions created in file menu for storing recent files }; #endif // RECENTFILES_H
对应的.cpp文件如下: #include "RecentFiles.h" #include #include #include #include #include #include #include #include #include #include QString sanitizedFileName(const QString &name) { QString clean = name; return clean.replace(QRegExp("[^A-Za-z0-9]"), QString("_")); } RecentFiles::RecentFiles(QMainWindow *parent) : QObject(parent) , m_recentMenu(new QMenu(parent)) , m_recentMenuTriggeredAction(NULL) { // create the sub-menu m_recentMenu->setTitle("Open Recent..."); m_recentMenu->setObjectName("RecentMenu"); // create an action for all possible entries in the sub-menu for (int i = 0; i < MaxRecentFiles; i++) { m_recentFileActions[i] = new QAction(m_recentMenu); m_recentFileActions[i]->setText("---"); m_recentFileActions[i]->setVisible(false); connect(m_recentFileActions[i], SIGNAL(triggered()), this, SLOT(openRecentFile())); m_recentMenu->addAction(m_recentFileActions[i]); } // Set some defaults QSettings settings; if (!settings.value(recentFileCount).isValid()) settings.setValue(recentFileCount, QVariant(4)); // If there are no recent files, initialize an empty list if (!settings.allKeys().contains(recentFileListId)) { settings.setValue(recentFileListId, QVariant(QStringList())); } updateRecentFiles(settings); } RecentFiles::~RecentFiles() { // delete m_recentMenu; // might be bad because parent menu will delete. m_recentMenu = (QMenu *)NULL; } //在menu菜单项下插图一个text名称的菜单项,并且这个菜单关联slotname响应 void RecentFiles::attachToMenuAfterItem(QMenu *menu, /* menu that "Recent" sub-menu should be inserted into */ QString text, /* Action in menu after which Recent menu should be inserted */ const char * slotName) { QList actionList = menu->actions(); int indexOfItemToFollow = 0; for (; indexOfItemToFollow < actionList.size(); indexOfItemToFollow++) { QAction *act = actionList.at(indexOfItemToFollow); if (!act->text().compare(text)) { break; } } int indexOfItemToPreceed = indexOfItemToFollow + 1; if (indexOfItemToPreceed >= actionList.size()) { // append to end of menu m_recentMenuTriggeredAction = menu->addMenu(m_recentMenu); m_recentMenuTriggeredAction->setObjectName("recentMenuAction"); } else { // insert into menu QAction *before = actionList.at(indexOfItemToPreceed); m_recentMenuTriggeredAction = menu->insertMenu(before, m_recentMenu); m_recentMenuTriggeredAction->setObjectName("recentMenuAction"); menu->insertSeparator(before); } connect(this, SIGNAL(openFile(QString)), parent(), slotName); } void RecentFiles::openRecentFile() { QAction *action = qobject_cast(sender()); if (action) emit openFile(action->data().toString()); } void RecentFiles::purgeMissingFilesFromList(QStringList &recentFileList) { for (QMutableStringListIterator i(recentFileList); i.hasNext();) { QString fileName = i.next(); // stash filename and advance iterator if (!QFile::exists(fileName)) { i.remove(); // removes item last jumped by i.next() } } } QString RecentFiles::strippedName(const QString &fullFileName) { return QFileInfo(fullFileName).fileName(); } void RecentFiles::setMenuEnabled(bool tf) { m_recentMenuTriggeredAction->setEnabled(tf); } int RecentFiles::numberOfRecentFilesToSave() { QSettings settings; return settings.value(recentFileCount).toInt(); } void RecentFiles::setMostRecentFile(const QString fileName) { if (fileName.isEmpty()) return; QSettings settings; QStringList recentFileList = settings.value(recentFileListId).toStringList(); recentFileList.removeAll(fileName); recentFileList.prepend(fileName); settings.setValue(recentFileListId, QVariant(recentFileList)); updateRecentFiles(settings); qApp->setProperty("currentDirectory", QVariant( QFileInfo(fileName) .absoluteDir() .absolutePath() )); } void RecentFiles::setNumOfRecentFiles(int n) { QSettings settings; settings.setValue(recentFileCount, QVariant(n)); updateRecentFiles(settings); // So a preference panel can be updated to show new value... emit newMaxFilesShown(n); } QStringList RecentFiles::getRecentFiles() const { QSettings settings; QStringList recentFileList = settings.value(recentFileListId).toStringList(); return recentFileList; } void RecentFiles::updateRecentFiles(QSettings &settings) { int numOfRecentFiles = settings.value(recentFileCount, QVariant(4)).toInt(); QStringList MyRecentFileList = settings.value(recentFileListId).toStringList(); purgeMissingFilesFromList(MyRecentFileList); settings.setValue(recentFileListId, QVariant(MyRecentFileList)); // If there are no recent files, then the menu item (that would show the list) // should not be visible. if (m_recentMenuTriggeredAction) { if (numOfRecentFiles == 0) { m_recentMenuTriggeredAction->setVisible(false); } else { m_recentMenuTriggeredAction->setVisible(true); } } for (int j = 0; j < MaxRecentFiles; ++j) { if (j < MyRecentFileList.count() && j < numOfRecentFiles) { QString text = strippedName(MyRecentFileList[j]); m_recentFileActions[j]->setText(text); m_recentFileActions[j]->setData(MyRecentFileList[j]); m_recentFileActions[j]->setObjectName(sanitizedFileName(text)); m_recentFileActions[j]->setVisible(true); } else { m_recentFileActions[j]->setVisible(false); } } for (int j = numOfRecentFiles; j < MyRecentFileList.count(); j++) m_recentFileActions[j]->setVisible(false); getRecentFiles(); }
关于怎么使用的问题,就我的程序上来说,需要在Mainwindow上进行操作,因此我需要在Mainwindow上增加如下代码: 构造函数中: m_recentFiles(this); m_recentFiles.attachToMenuAfterItem(ui.menu_F, "Export...", SLOT(openFile(QString)));//在Export菜单项下插入 m_recentFiles.setNumOfRecentFiles(8);//最多显示最近的8个文件 在打开文件函数中添加如下代码: QSettings settings; QFileInfo fi(filename); settings.setValue("currentDirectory", fi.absolutePath()); m_recentFiles.setMostRecentFile(filename); 如果需要点击这些最近的文件后打开,需要实现openFile(QString filename)函数,这个可以根据自己的情况就行了,我的实现是: //最近文档打开接口 void OCCAD::openFile(QString filename) { QFormDoc *Temp = FindMdiChild(filename); //判断文件是否已经打开 if (!Temp) {//文件还没打开 QFormDoc *formDoc = FindEmptyFile(); if (formDoc) {//还有空的文档,直接写入空文档 setActiveSubWindow(formDoc); formDoc->loadFromFile(filename); formDoc->setcurrFileName(filename); formDoc->showMaximized(); //默认全屏显示 formDoc->Fill_View_style(); formDoc->show(); // CurrOperation = "OPEN"; CreateModelNode(); CreateNodeWithModelType(filename, formDoc); // QSettings settings; QFileInfo fi(filename); settings.setValue("currentDirectory", fi.absolutePath()); m_recentFiles.setMostRecentFile(filename); } else { //没有空窗口,新建一个并显示到这个新窗口中 formDoc = new QFormDoc(this); ui.mdiArea->addSubWindow(formDoc); setActiveSubWindow(formDoc); formDoc->loadFromFile(filename); formDoc->showMaximized(); //默认全屏显示 formDoc->Fill_View_style(); formDoc->show(); // CurrOperation = "OPEN"; CreateModelNode(); CreateNodeWithModelType(filename, formDoc); // QSettings settings; QFileInfo fi(filename); settings.setValue("currentDirectory", fi.absolutePath()); m_recentFiles.setMostRecentFile(filename); } } else {//文件已经打开,置顶这个窗口 Temp->activateWindow(); Temp->showMaximized(); //默认全屏显示 } } QT4下我测试的时候好像没问题,但是在QT5下工作不正常,后面看了下官网的资料: 因此,我在主函数中加入了这三句代码,之后能工作正常: QCoreApplication::setOrganizationName("OCSOFT"); QCoreApplication::setOrganizationDomain("OCSOFT.COM"); QCoreApplication::setApplicationName("OCCAD V1.0");
后记: 到此,在QT窗口菜单中实现最近打开的文件功能已经完成。如果有什么写错的地方,请联系我修改 QQ:1623451686。
|
CopyRight 2018-2019 实验室设备网 版权所有 |