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

Posted

技术标签:

【中文标题】设置 Qt QPushButton 弹出菜单的位置(向右)【英文标题】:Set position (to right) of Qt QPushButton popup menu 【发布时间】:2015-07-28 06:14:46 【问题描述】:

我正在为 Qt 按钮小部件编写弹出菜单。每当单击按钮时,都会弹出一个菜单(在按钮下方)。

弹出菜单默认在左侧下方。

有什么方法可以让弹出菜单在右侧按钮下方弹出?

没有设置位置功能,不知道有没有什么复杂的方法呢?

这是一些代码(用于弹出菜单):

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

【问题讨论】:

【参考方案1】:

这可以通过继承 QMenu 并将弹出菜单移动到您想要在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(p.x()+geo.width()-this->geometry().width(), p.y());

ma​​inwindow.cpp

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

看起来像这样:

【讨论】:

谢谢,我正在努力!请问PopupMenu类为什么有QPushButton* b?每次单击 PopupMenu 的按钮时都会调用 showEvent 函数吗? 另外,我遇​​到了这些错误:popupmenu.obj : error LNK2001: unresolved external symbol "public: virtual struct QMetaObject const * __cdecl PopupMenu::metaObject(void)const " `popupmenu.obj : error LNK2001: unresolved external symbol "public: virtual void * __cdecl PopupMenu::qt_metacast(char const *)" popupmenu.obj : error LNK2001: unresolved external symbol "public: virtual int __cdecl PopupMenu::qt_metacall(enum QMetaObject::Call,int,void * *)" 我以前遇到过这些错误,但我也不知道为什么它与 QMetaObject 有关 @Ryan QPushButton* b 用于告诉 PopupMenu 它应该与哪个按钮实例对齐。是的,每次单击按钮时都会调用showEvent。关于你的错误:看看this SO question and answers 感谢您的链接!我尝试将.h 添加回cmakelist 以生成moc 将解决此LNK2001(受其中一个ans 的启发。)【参考方案2】:

您应该为您的QMenu 实现eventFilter。在eventFilter方法中,你需要计算你的菜单会显示的位置。

这里有一个例子:

.pro

TEMPLATE = app

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

HEADERS += dialog.h

FORMS   += dialog.ui

ma​​in.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;

【讨论】:

【参考方案3】:

另一种(恕我直言)更简单的方法是:

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

【讨论】:

以上是关于设置 Qt QPushButton 弹出菜单的位置(向右)的主要内容,如果未能解决你的问题,请参考以下文章

Qt之使用QSS设置QPushButton图标和文本的位置

Qt—QPushButton 使用总结

Qt之QPushButton

如何在 ui 文件 QT 中设置图像,例如 QPushButton?

QT软件开发之基础控件--2.1.2 QPushButton按钮

如何在 Qt 应用程序中使用样式表更改 QPushButton 图标