简体   繁体   English

设置Qt QPushButton弹出菜单的位置(右侧)

[英]Set position (to right) of Qt QPushButton popup menu

I am writing a popup menu for a Qt push button widget. 我正在为Qt按钮小部件编写一个弹出菜单。 Whenever the push button is clicked, a menu pops up (below the push button). 只要单击按钮,就会弹出一个菜单(按钮下方)。

The popup menu is left-sided below by default. 默认情况下,弹出菜单位于左下方。

Are there any ways to make the popup menu to pop up on the right side below the push button? 有没有办法让弹出菜单弹出按钮右下方的右侧?

There is no set position function, so I wonder if there is some sophisticated way of doing it? 没有设定位置功能,所以我想知道是否有一些复杂的方法呢?

Here is some code (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's there is ui

This can be done by subclassing QMenu and moving the popup menu where you want to have it in showEvent : 这可以通过继承QMenu动人,你想拥有它,在弹出的菜单来完成showEvent

popupmenu.h 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 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(p.x()+geo.width()-this->geometry().width(), p.y());
}

mainwindow.cpp mainwindow.cpp

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

It looks like this: 它看起来像这样:

在此输入图像描述

You should implement an eventFilter for your QMenu . 您应该为QMenu实现一个eventFilter In the eventFilter method, you need to calculate the position where your menu will be shown. eventFilter方法中,您需要计算菜单显示的位置。

Here you have an example: 这里有一个例子:

.pro 的.pro

TEMPLATE = app

QT     += widgets
SOURCES += main.cpp \
           dialog.cpp

HEADERS += dialog.h

FORMS   += dialog.ui

main.cpp 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 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 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;
}

Another (imho) simpler approach would be: 另一种(imho)更简单的方法是:

void MainFrame::Slot_ShowMenu()
{
    auto pMenu = new QMenu(this);

    connect(pMenu, &QMenu::aboutToHide, pMenu, &QMenu::deleteLater);

    ...

    // Retrieve a valid width of the menu. (It's 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);
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM