How to change QMenu behavior
-
Hi, I'm a bit stuck with quite specific problem and will appreciate any suggestions.
First of all I'd like to say that I'm developing small module in the big project, so I can't change some basic things and have to deal with it.
So, this project is big cross-platform application which has a variety of features and some of them are presented in a big toolbar. My target is to add a couple of buttons in it and provide them needed functionality.Main requirements are:
- button must be checkable;
- button must have dropdown menu;
- it must be icon with small arrow on the right side (as it usually appears in applications).
It looks like quite easy: we can take QAction, add it to toolbar, create QMenu, pack it with some other QActions and set this menu for QAction from toolbar.
But the problem is that dropdown menu must have specific view and it already designed and developed, and it is presented as QDialog. So, when I click the black arrow near the icon in toolbar this QDialog should appear.
For now I have found following solution:
- Create my own QCustomMenu class which is inherited from QMenu.
- In this custom class override showEvent(...) method.
- Create QAction, add it to toolbar.
- Create object of my custom menu class and insert it as a menu for this QAction.
- Connect to aboutToShow() signal of my custom menu.
- In connected slot exec() given QDialog and perform all needed actions.
This is how my custom class looks like:
class QCustomMenu : public QMenu
{
Q_OBJECT
public:
QCustomMenu(QObject *parent = 0){};
void showEvent(QShowEvent *)
{
this->hide(); // close() also possible
}
};In Windows it works great and performs as I expected.
But in Linux here's a small problem: when I press button in created QDialog and it disappears I can't press any button in the whole application (but when I hover mouse to icons in toolbar their description appears in status bar and so on, they are simply unclickable ). It looks like QCustomMenu wasn't closed or smth like that, but I can't catch what I have missed. May be I should override other events or something else. I have been trying to figure it out for three days now and absolutely stuck (it looks like that QMenu perform different with X11 ) .
Everything I want is to close this QCustomMenu programmatically when it try to appear.
Hope someone could help me with some good suggestions. -
Hi and welcome to devnet,
Since you don't use it at all, why the QMenu ?
Why not connect the triggered signal of your action to a custom slot that would show your dialog ? -
A checkable QAction ?
-
-
Before going further, what do you need to show in that dialog ?
-
Then I'd rather go with a checkable action, show the dialog in triggered(true) and hide it again on triggered(false)
-
For now I found following solution to prevent GUI from freeze:
{ Q_OBJECT public: QCustomMenu(QObject *parent = 0){}; void showEvent(QShowEvent *) { emit show(); QMenu::closeEvent(new QCloseEven()); QMenu::hideEvent(new QHideEvent()); } signals: void show(); };
And also now I've changed logic: on show() signal I exec() my dialog:
QCustomMenu *menu = new QCustomMenu(toolbar); connect(menu, SIGNAL(show()), this, SLOT(execMyMenu()));
But after closing my dialog UI waits for mouse click somewhere to start responding for further actions.
May be it is possible to make programmatically click somewhere ? I didn't find any solution yet.