11

I'm creating a text editor and I'd like to put the QComboBox in the QMenu. I didn't find any method inside the QMenu that handled such a thing. The closest is QMenu::addAction(). I was wondering of getting around this hurdle.

Thanks!

cbuchart
  • 10,847
  • 9
  • 53
  • 93
W.K.S
  • 9,787
  • 15
  • 75
  • 122

3 Answers3

19

You have to subclass QWidgetAction and then simply call the addAction to your menu.

Example code for Spin Box Action with a label

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;
};

Now simply create it and add it to your menu

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);
Bilal Ahmad
  • 781
  • 8
  • 10
pnezis
  • 12,023
  • 2
  • 38
  • 38
  • Why would you prefer subclassing QWidgetAction? Wouldn't it offer looser coupling and more maintainable code to instantiate a QWidgetAction separately from your `pWidget` and call `setDefaultWidget`? Wouldn't the only reason to subclass be to implement `createWidget`? – Magnus Hoff Dec 02 '11 at 16:36
  • 1
    It depends. If you want to have reusable widget actions and avoid rewriting the same parts of code for creating them you should subclass them. For example I once needed a QMenu with multiple spin boxes with a label, and varying min/max values and prefix. By subclassing the `QWidgetAction` I was able to have a reusable element, and in every case I only had to change the constructor arguments. Also it is straight forward to create a small library with action widgets and just call the one you need when you need it. – pnezis Dec 02 '11 at 16:41
  • I'm not familar with this kind of constructor:`SpinBoxAction (const QString& title) : QWidgetAction (NULL) {}` – W.K.S Dec 02 '11 at 17:35
  • 2
    This simply calls the parent's constructor with `NULL` as argument. http://stackoverflow.com/questions/120876/c-superclass-constructor-calling-rules – pnezis Dec 02 '11 at 18:37
  • @MagnusHoff So why would you need to implement createWidget? – Joe Jan 17 '18 at 11:07
2

QWidgetAction is a QAction that contains a QWidget. You can use this to encapsulate your QComboBox and add it to your menu via QMenu::addAction.

Magnus Hoff
  • 21,529
  • 9
  • 63
  • 82
1

You can always use a QWidget or QFrame as the Menu Widget, then put a QHBoxLayout on it, and insert your QWidgets inside.

Lee Davis
  • 4,685
  • 3
  • 28
  • 39
Tomaz Canabrava
  • 2,320
  • 15
  • 20
  • This idea actually occured to me. I'm kinda new to Qt so forgive me if this is kinda basic: How would I set my own QWidget as the Menu Widget. – W.K.S Dec 02 '11 at 16:43