1

コンテキスト メニュー (QMenu) があり、次のようにコピー アクションを追加します。

m_copyNodeAction = new QAction(tr("Copy node"), &m_mainContextMenu);
m_copyNodeAction->setShortcut(QKeySequence("Ctrl+C"));
m_copyNodeAction->setShortcutVisibleInContextMenu(true);

m_mainContextMenu.addAction(m_copyNodeAction);

QObject::connect(m_copyNodeAction, &QAction::triggered, [this] () {
    std::cout << "Copy node triggered!" << std::endl;
});

メニューは次のように開きます (ホスティング クラスは から派生しますQGraphicsView)。

m_mainContextMenu.exec(mapToGlobal(m_clickedPos));

メニューにはアクション OK が表示されますが、 によってトリガーされませんCtrl+C。メインメニューのアクションに同じアプローチを使用しましたが、なぜこれが違うのですか?

他のショートカットもいくつか設定しようとしましたが、何も機能しません。

4

2 に答える 2

1

これを行う 1 つの方法を次に示します。

  1. アクションをコンテキストメニューに追加するだけでなく、アクションを親ウィジェット (アクションがローカルであるべきもの、リストビューとしましょう) に追加します。
m_listview->addAction(m_copyNodeAction);
  1. アクションのショートカット コンテキストQt::WidgetWithChildrenShortcut次のように設定します。
m_copyNodeAction->setShortcutContext(Qt::WidgetWithChildrenShortcut);
  1. 作成したコンテキスト メニューがウィジェットを親として使用していることを確認します。
auto* m_mainContextMenu = new QMenu{tr("Main Context Menu"), m_listview};

考慮すべき点がいくつかあります。

  1. デフォルトでは、これはアクションがトリガーされたときにコンテキスト メニューを閉じませんが、自分で実装するのはかなり簡単です。

  2. これにより、コンテキスト メニューを表示せずにアクションをトリガーできます (迂回するのもかなり簡単ですが、なぜそうしたいのでしょうか?)

いくつかの予備テストでは、これは QtCreator がショートカットを処理する方法でもあるように見えます。

于 2020-01-16T01:32:41.357 に答える
1

次の例は、エラーを再現します。また、Qt フレームワーク内でデバッグし、 と をステップ実行しQMenu::keyPressEventましQAction::eventたが、押されたキーが正しく処理されていないようです。

QAction::eventイベント タイプではQEvent::Shortcut決して発生しません。回避策として、独自の関数から派生さQActionせて実装することをお勧めしますevent

#include <QApplication>
#include <QFrame>
#include <QMenu>
#include <QAction>
#include <QDebug>

int main(int argc, char* argv[])
{
    QApplication a(argc, argv);
    QApplication::setAttribute(Qt::ApplicationAttribute::AA_DontShowShortcutsInContextMenus,false);
    auto widget = new QFrame;

    widget->setContextMenuPolicy(Qt::ContextMenuPolicy::CustomContextMenu);
    int id=widget->grabShortcut(QKeySequence::Delete, Qt::ShortcutContext::WidgetShortcut);

    QObject::connect(widget, &QFrame::customContextMenuRequested, [widget,id](const QPoint& pos) {
        QMenu menu(widget);
        menu.setShortcutEnabled(id, true);
        auto action = new QAction("&Copy node", &menu);
        action->setShortcut(QKeySequence(QKeySequence::Delete));
        action->setShortcutVisibleInContextMenu(true);
        action->setShortcutContext(Qt::ShortcutContext::WidgetShortcut);

        QObject::connect(action, &QAction::triggered, []() {
            qDebug() << "Copy node triggered!";
        });

        menu.addAction(action);
        menu.exec(widget->mapToGlobal(pos));
        });

    widget->show();
    return a.exec();
}
于 2019-07-25T07:29:38.137 に答える