Set the position (right) of the Qt PushButton popup menu

I am writing a popup menu for a Qt button widget, whenever a button is clicked, a popup menu appears (under the button).

By default, the popup menu is on the left. Is there a way for a popup menu to pop up on the right side under a button?

There is no given position function ... so I wonder if there is any complicated way to do this?

Here are some codes (for popup menu):

QMenu *menuMode = new QMenu(this); min = menu ->addAction("In"); mout = menu ->addAction("out"); ui->pushButtonMode->setMenu(menuMode); //I am writing in MainWindow, that there is ui 

Thanks so much for any tips and tricks.

+5
source share
3 answers

This can be done by subclassing QMenu and moving the popup menu in which you want to have it in showEvent :

popupmenu.h

 #ifndef POPUPMENU_H #define POPUPMENU_H #include <QMenu> class QPushButton; class QWidget; class PopupMenu : public QMenu { Q_OBJECT public: explicit PopupMenu(QPushButton* button, QWidget* parent = 0); void showEvent(QShowEvent* event); private: QPushButton* b; }; #endif // POPUPMENU_H 

popupmenu.cpp

 #include "popupmenu.h" #include <QPushButton> PopupMenu::PopupMenu(QPushButton* button, QWidget* parent) : QMenu(parent), b(button) { } void PopupMenu::showEvent(QShowEvent* event) { QPoint p = this->pos(); QRect geo = b->geometry(); this->move(px()+geo.width()-this->geometry().width(), py()); } 

mainwindow.cpp

 ... PopupMenu* menu = new PopupMenu(ui->pushButton, this); ... ui->pushButton->setMenu(menu); 

It looks like this:

enter image description here

+6
source

You must implement eventFilter for QMenu . In the eventFilter method eventFilter you need to calculate the position at which your menu will be displayed.

Here you have an example:

.pro

 TEMPLATE = app QT += widgets SOURCES += main.cpp \ dialog.cpp HEADERS += dialog.h FORMS += dialog.ui 

main.cpp

 #include <QtWidgets/QApplication> #include "dialog.h" int main(int argc, char *argv[]) { QApplication a(argc, argv); Dialog dia; return dia.exec(); } 

dialog.h

 #ifndef DIALOG_H #define DIALOG_H #include <QtWidgets/QDialog> #include <QMenu> #include "ui_dialog.h" class Dialog : public QDialog { Q_OBJECT public: Dialog(); protected: bool eventFilter(QObject * obj, QEvent *event); private: QMenu *menu; Ui::Dialog m_ui; }; #endif 

dialog.cpp

 #include "dialog.h" Dialog::Dialog() { m_ui.setupUi(this); menu = new QMenu("menu", this); menu->installEventFilter(this); QAction *action = new QAction("action#1", this); menu->addAction(action); m_ui.pushButton->setMenu(menu); } bool Dialog::eventFilter(QObject * obj, QEvent *event) { if (event->type() == QEvent::Show && obj == m_ui.pushButton->menu()) { int menu_x_pos = m_ui.pushButton->menu()->pos().x(); int menu_width = m_ui.pushButton->menu()->size().width(); int button_width = m_ui.pushButton->size().width(); QPoint pos = QPoint(menu_x_pos - menu_width + button_width, m_ui.pushButton->menu()->pos().y()); m_ui.pushButton->menu()->move(pos); return true; } return false; } 
+1
source

Another (imho) simpler approach would be the following:

 void MainFrame::Slot_ShowMenu() { auto pMenu = new QMenu(this); connect(pMenu, &QMenu::aboutToHide, pMenu, &QMenu::deleteLater); ... // Retrieve a valid width of the menu. (It not the same as using "pMenu->width()"!) int menuWidth = pMenu->sizeHint().width(); int x = mUI.myQPushButton->width() - menuWidth; int y = mUI.myQPushButton->height(); QPoint pos(mUI.myQPushButton->mapToGlobal(QPoint(x, y))); pMenu->popup(pos); } 
0
source

All Articles