QWidget可以获取/修改窗口小部件的现有上下文菜单

时间:2014-10-29 08:43:10

标签: qt qt4

我有第三方小部件,它为我提供了一些上下文菜单。让我们说切,复制粘贴,选择全部。 现在我只想修改现有上下文菜单的粘贴功能。我知道我可以在contextMenuEvent中从头开始实现整个上下文菜单。但我不想这样做,因为我对其他上下文菜单操作感到满意,只想修改粘贴功能。

我在Mac OSX上使用QT 4.8。

如果目前无法做出这样的事情,有人可以给我链接/参考吗?这样我就能满足我的利益相关者。

编辑:为了更清楚我想要做的是,出于某种原因禁用粘贴上下文菜单,并希望稍后根据情况/事件启用它。

1 个答案:

答案 0 :(得分:2)

我不确定它是否可以通用的方式完成。 这是一个棘手的解决方案:

contextMenuEvent中创建对某个插槽的排队调用:

QMetaObject::invokeMethod(this, "patchMenu", Qt::QueuedConnection);

在插槽中获取可见窗口并找到QMenu。从中获取操作并启用/禁用它们:

Q_SLOT patchMenu()
{
  QWidgetList widgets = QApplication::topLevelWidgets();
  foreach (QWidget* widget, widgets)
  {
    if (QMenu* menu = qobject_cast<QMenu*>(widget))
    {
        QList<QAction*> actions = menu->actions();
        // here you can either get an action by index actions[5]
        // or search the action by text
        actions;
    }
  } 
}

编辑:
这是一个工作示例,它演示了这种方法: window.h中

#pragma once
#include <QtGui>

class Window: public QMainWindow
{
    Q_OBJECT
public:
    Window(QWidget *parent = 0);
};

class A : public QWidget
{
public:
    virtual void contextMenuEvent(QContextMenuEvent* e);
};

class B : public A
{
    Q_OBJECT;
public:
    virtual void contextMenuEvent(QContextMenuEvent*);

    Q_SLOT void patchMenu();
};

window.cpp

#include "window.h"

Window::Window(QWidget *parent) : QMainWindow(parent)
{
    setCentralWidget(new B());
}

void B::patchMenu()
{
    QWidgetList widgets = QApplication::topLevelWidgets();
    foreach (QWidget* widget, widgets)
    {
        if (QMenu* menu = qobject_cast<QMenu*>(widget))
        {
            QList<QAction*> actions = menu->actions();
            // here you can either get an action by index actions[5]
            // or search the action by text
            actions;
        }
    }   
}

void B::contextMenuEvent(QContextMenuEvent* e)
{
    QMetaObject::invokeMethod(this, "patchMenu", Qt::QueuedConnection);
    A::contextMenuEvent(e);
}

void A::contextMenuEvent(QContextMenuEvent* e)
{
    QMenu menu;
    QAction* action = new QAction(QIcon(), "text", &menu);
    menu.addAction(action);
    menu.exec(e->globalPos());
}