PDA

View Full Version : QWidgetAction resize in QMenu



stburton
4th December 2009, 23:34
I have a QButton with an associated QMenu. The QMenu contains a single QWidgetAction with an associated widget.

Now I want to change the content of the widget contained in the menu at some point, and have the QMenu resize itself when shown so that the QMenu is the appropriate size for the content in the widget.
For instance:


QPushButton* button = new QPushButton("Button",parent);
QMenu* menu = new QMenu(button);
button->setMenu(menu);
MyWidget* customWidget = new MyWidget(menu);
QWidgetAction* menuWidget = new QWidgetAction(menu);
menuWidget->setDefaultWidget(customWidget);
menu->addAction(menuWidget);
//Attach a signal that would allow the customWidget to update its contents prior to being shown
QObject::connect(menu,SIGNAL(aboutToShow()),custom Widget,SLOT(updateContent()));
//The 'updateContent' slot may add or remove child widgets to 'customWidget' causing its size to change

What I want to happen is that each time the menu is about to be shown the widget will update its content and the QMenu will be shown with the appropriate size to display the content of the widget.

What currently happens is that the QMenu takes its size from whatever the initial size of the customWidget object is the first time it is shown. Updating the content of the customWidget object does not have any effect on the size of the containing menu on later showings of the menu. That is, the QMenu will always be the same size as the first time it was shown regardless of what modifications I make to the customWidget object.

This was working at one point and I can't for the life of me figure out what has changed.

akiross
24th January 2013, 23:39
I know this is an old post, but I've this same problem... Can anyone help, please?

Santosh Reddy
25th January 2013, 06:57
I don't think it is directly possible with in a slot connected to QMenu's aboutToShow() signal.

One workaroud is to show(), hide(), and then show() to that will trigger a resize of QMenu(), somthing like


void updateContent()
{
QMenu * menu = dynamic_cast<QMenu *>(sender());
if(menu != 0)
{
menu->blockSignals(true);
// Add/update widgets

menu->show();
qApp->processEvents();
menu->hide();
qApp->processEvents();
menu->show();
menu->blockSignals(false);
}
}

This may cause a small noise / glich in ui during the menu popup, due to quick show(), hide() and show()

chriskatze
16th June 2013, 20:19
Hello,

instead of menu->hide()/show(), I found the workaround
QPixmap::grabWidget(menu)
So it doesn't flicker ;-)

lanyeguxing
23rd July 2013, 08:12
Hi,

Is there any news about this issue? I met the same problem.

l3u
10th February 2017, 08:38
This is quite an old thread, but the problem remains … I posted a question about this at http://stackoverflow.com/questions/42122985/ recently. My workaround was to clear the menu and re-fill it with the respective actions after changing the content of the QWidgetAction.

Is there any non-workaround solution for this?

mnaydenov
9th December 2017, 13:13
The solution is to send a resize event instead:


QResizeEvent re(newsize, menu->size());
qApp->sendEvent(menu, &re);

This will set the QMenu's internal itemsDirty flag and will force geometry recalculation when the menu is next shown.

Trap
11th January 2018, 15:27
The solution is to send a resize event instead:


QResizeEvent re(newsize, menu->size());
qApp->sendEvent(menu, &re);

This will set the QMenu's internal itemsDirty flag and will force geometry recalculation when the menu is next shown.

I have exactly the same problem with a QWidgetAction and a popup menu, and tried your solution.
I send the resize event in the aboutToShow signal of my menu, but the menu is correctly sized only the second time it is shown (I have to popup the mnu, close it and popup it again).
Am I missing something ?