有没有办法在QtCreator中向QMenu添加一个QWidget?

11

我正在创建一个文本编辑器,想在 QMenu 中添加 QComboBox。但是我没有找到 QMenu 中任何处理这种情况的方法,最接近的是 QMenu::addAction()。我想知道如何解决这个问题。

谢谢!

3个回答

19
你需要继承 QWidgetAction,然后在你的菜单中调用addAction即可。
下面是一个带标签的旋转框操作的示例代码。
class SpinBoxAction : public QWidgetAction {
public:
    SpinBoxAction (const QString& title) : 
      QWidgetAction (NULL) {
        QWidget* pWidget = new QWidget (NULL);
        QHBoxLayout* pLayout = new QHBoxLayout();
        QLabel* pLabel = new QLabel (title);  //bug fixed here, pointer was missing
        pLayout->addWidget (pLabel);
        pSpinBox = new QSpinBox(NULL);
        pLayout->addWidget (pSpinBox);
        pWidget->setLayout (pLayout);

        setDefaultWidget(pWidget);
    }

    QSpinBox * spinBox () {
        return pSpinBox;
    }

private:
    QSpinBox * pSpinBox;
};

现在只需创建该项并将其添加到菜单即可

SpinBoxAction * spinBoxAction = new SpinBoxAction(tr("Action Title"));
// make a connection
connect(spinBoxAction ->spinBox(), SIGNAL(valueChanged(int)), 
        this, SLOT(spinboxValueChanged(int)));
// add it to your menu
menu->addAction(spinBoxAction);

你为什么更喜欢子类化QWidgetAction?将QWidgetAction单独实例化并调用setDefaultWidget,不是提供了更松散的耦合和更易于维护的代码吗?难道子类化的唯一原因就是实现createWidget吗? - Magnus Hoff
1
这要看情况。如果你想要可重用的小部件操作并避免重写创建它们的相同代码部分,那么你应该对它们进行子类化。例如,我曾经需要一个带有多个带标签、不同最小/最大值和前缀的旋转框的QMenu。通过对QWidgetAction进行子类化,我能够拥有一个可重用的元素,在每种情况下只需更改构造函数参数即可。此外,创建一个小型的操作小部件库并在需要时调用所需的小部件也是很简单的。 - pnezis
我不熟悉这种构造函数:SpinBoxAction (const QString& title) : QWidgetAction (NULL) {} - W.K.S
2
这只是使用NULL作为参数调用父类构造函数的简单操作。https://dev59.com/tXVD5IYBdhLWcg3wAWkO - pnezis
@MagnusHoff 那么为什么你需要实现createWidget呢? - Joe

2

QWidgetAction是一个包含QWidgetQAction。您可以使用它来封装您的QComboBox,并通过QMenu::addAction将其添加到菜单中。


1

您可以始终使用 QWidgetQFrame 作为菜单小部件,然后在其上放置一个 QHBoxLayout,并将您的 QWidgets 插入其中。


这个想法实际上是我想到的。我对Qt还比较新,如果这有点基础,请原谅:我该如何将自己的QWidget设置为菜单小部件。 - W.K.S

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接