Qt designer如何实现Recent Files动作?

How to implement Recent Files action with Qt designer?

我知道如果我手写的话我可以使用for循环但是我怎么能用Qt设计器呢?或者我应该将这两种方式混合在一起以达到目标吗?

感谢

当我尝试实现最近的文件时,我想到了这样的解决方案:

我在启动时创建菜单项并将它们设置为不可见:

separatorAct = ui.menu_File->addSeparator();
    for (int i = 0; i < MAXRECENTFILE; ++i) {
        RecentProjects[i] = new QAction(this);
        RecentProjects[i]->setVisible(false);
        connect(RecentProjects[i], SIGNAL(triggered()), this, SLOT(OpenRecentFile()));
        ui.menu_File->addAction(RecentProjects[i]);
    }

然后我更新最近的文件条目(存储在文件中):

void BulbCalculator::UpdateRecentFileActions() {

QSettings settings("GRYS","BulbCalculator");;
QStringList files = settings.value("RecentProject").toStringList();

int numRecentFiles = qMin(files.size(), MAXRECENTFILE);

for (int i = 0; i < numRecentFiles; ++i) {
    QString text = tr("&%1 %2").arg(i + 1).arg(StrippedName(files[i]));
    RecentProjects[i]->setText(text);
    RecentProjects[i]->setData(files[i]);
    RecentProjects[i]->setVisible(true);
}
for (int j = numRecentFiles; j < MAXRECENTFILE; ++j) {
    RecentProjects[j]->setVisible(false);
}
separatorAct->setVisible(numRecentFiles > 0);

}

插槽OpenRecentFile实现起来非常简单

void BulbCalculator::OpenRecentFile() {

    QAction *action = qobject_cast<QAction *>(sender());
    if (action) {
        this->BcStatus->CurFile = action->data().toString();
        LoadFile();
        //LoadFile(action->data().toString());
    }
}

希望对您有所帮助

我制作了一个 class 来解析 QMainWindow 的菜单栏中名为“”的文本项。此项将被隐藏,并添加或更新最近最常用的文件。

header:

#pragma once
#include <QObject>
#include <list>
#include <vector>

class QMainWindow;
class QAction;
class GFQtRecentFileMenu : public QObject {
    Q_OBJECT
public:
    explicit GFQtRecentFileMenu(QObject* parent = nullptr);
    void updateRecentFileList(QMainWindow* pMW, const std::vector<QString>& files);
    void removeAddedEntries();
private:
    std::list<QAction*> m_AddedActions;
    std::vector<QString> m_filenames;
public slots:
    void onRmuMenuItem();
};

实施:

#include "gfqtrecentfilemenu.h"
#include <QMainWindow>
#include <QMenuBar>
#include <QMenu>
#include <QDebug>
#include "gfappframework.h"


class QMenuBarIterator {
    QMenuBar*    i_barP;
    QMenu*   m_RMU_menu;
    QAction* m_RMU_action;

    bool investigate(QAction* pA) {
        if (pA->text() == QString("<RMU>")) { // HERE'S THE MENU TEXT PLACEHOLDER
            m_RMU_action = pA;
            return true;
        }
        return false;
    }

    bool    iterate_sub(QMenu* m) {
        for (QAction* action: m->actions()) { // sub menus of File, Edit, ...
            if (investigate(action)) {return true;}

            if (action->menu()) {
                if (iterate_sub(action->menu())) {
                    m_RMU_menu = action->menu();
                    return true;
                }
            }
        }
        return false;
    }

public:
    QMenuBarIterator(QMenuBar* barP) : i_barP(barP), m_RMU_menu(nullptr), m_RMU_action(nullptr) {}

    bool    iterate() {
        QList<QMenu*>  menuBar = i_barP->findChildren<QMenu*>();

        for (QMenu* m: menuBar) { // File, Edit, ..., Help
            if (investigate(m->menuAction()) || iterate_sub(m)) {
                m_RMU_menu = m;
                return true;
            }
        }
        return false;
    }
    QAction* action() {return m_RMU_action;}
    QMenu*   menu()   {return m_RMU_menu;}
};


GFQtRecentFileMenu::GFQtRecentFileMenu(QObject* parent) : QObject(parent) {
}

void GFQtRecentFileMenu::updateRecentFileList(QMainWindow* pMW, const std::vector<QString>& files) {
    removeAddedEntries();

    m_filenames = files;
    QMenuBarIterator mbi(pMW->menuBar());
    if (mbi.iterate()) {
        QAction* pA = mbi.action();

        auto* pmenu = mbi.menu();
        pA->setVisible(false); // hide the dummy, but keep in place. We're adding menu items at this position!

        int index = 0;
        for (auto& f: files) {
            QAction* pA = pmenu->addAction(f);
            pA->setData(index++);
            m_AddedActions.push_back(pA);

            connect(pA, SIGNAL(triggered()), this, SLOT(onRmuMenuItem()));
        }
    }
}

void GFQtRecentFileMenu::removeAddedEntries() {
    for (auto* a : m_AddedActions) { delete a; }
    m_AddedActions.clear();
}

void GFQtRecentFileMenu::onRmuMenuItem() {
    auto* action= qobject_cast<QAction*>(sender());
    if (action != nullptr) {
        int index = action->data().toInt();
        if (index >= 0 && index < int(m_filenames.size())) {
            // open the document now - however you do that...
            GetMyApplication().openDocument(m_filenames[index]);
        }
        qDebug() << m_filenames[i] << " clicked";
    }
}