设置 Qt QPushButton 弹出菜单的位置(向右)
Set position (to right) of Qt QPushButton popup menu
我正在为 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
您应该为您的 QMenu
实施 eventFilter
。在eventFilter
方法中,您需要计算菜单显示的位置。
这里有一个例子:
.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;
}
这可以通过子类化 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());
}
mainwindow.cpp
...
PopupMenu* menu = new PopupMenu(ui->pushButton, this);
...
ui->pushButton->setMenu(menu);
看起来像这样:
另一种(恕我直言)更简单的方法是:
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 按钮小部件编写弹出菜单。每当单击按钮时,都会弹出一个菜单(在按钮下方)。
弹出菜单默认在下方左侧。
有没有办法让弹出菜单在按钮下方的右侧弹出?
没有设置位置的功能,请问有什么高深的方法吗?
这是一些代码(用于弹出菜单):
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
您应该为您的 QMenu
实施 eventFilter
。在eventFilter
方法中,您需要计算菜单显示的位置。
这里有一个例子:
.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;
}
这可以通过子类化 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());
}
mainwindow.cpp
...
PopupMenu* menu = new PopupMenu(ui->pushButton, this);
...
ui->pushButton->setMenu(menu);
看起来像这样:
另一种(恕我直言)更简单的方法是:
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);
}