弹出位置分别可以为:
当前16个位置
enum MenuBtnDirection
{
LeftTop_LeftBottom = 0, //左上角的左下方向弹出
LeftTop_LeftTop, //左上角的左上方向弹出
LeftTop_rightBottom , //左上角的右下方向弹出
LeftTop_rightTop, //左上角的右上方向弹出
LeftBottom_LeftBottom, //左下角的左下方向弹出
LeftBottom_LeftTop, //左下角的左上方向弹出
LeftBottom_rightBottom , //左下角的右下方向弹出
LeftBottom_rightTop, //左下角的右上方向弹出
RightTop_LeftBottom, //右上角的左下方向弹出
RightTop_LeftTop, //右上角的左上方向弹出
RightTop_rightBottom , //右上角的右下方向弹出
RightTop_rightTop, //右上角的右上方向弹出
RightBottom_LeftBottom, //右下角的左下方向弹出
RightBottom_LeftTop, //右下角的左上方向弹出
RightBottom_rightBottom , //右下角的右下方向弹出
RightBottom_rightTop, //右下角的右上方向弹出
};
本内容中QMenu被重写了,是为了点击menu内部不让自动回收,如果没有这个需求的可以用原生的QMenu即可。且本文已经直接写了一个能够添加QMenu的自定义按钮了,有需要的兄弟直接用。
直接上代码:
.h
#ifndef MENUBTN_H
#define MENUBTN_H
#include <QToolButton>
#include "ubase.h"
#include <QMenu>
#include <QMouseEvent>
class UMenu;
class MenuBtn : public QToolButton
{
Q_OBJECT
public:
MenuBtn(QWidget* parent = nullptr);
void setInfo(int direction = 0,QWidget* childWidget = nullptr);
private slots:
void slotShowMenu();
private:
UMenu* m_menu;
QWidget* m_childWidget;
int m_direction;
};
class UMenu : public QMenu
{
public:
UMenu(QWidget* parent = nullptr);
protected:
void mouseReleaseEvent(QMouseEvent *e);
};
#endif // MENUBTN_H
.cpp
#include "menubtn.h"
#include <QHBoxLayout>
MenuBtn::MenuBtn(QWidget *parent)
{
connect(this,&MenuBtn::clicked,this,&MenuBtn::slotShowMenu);
}
void MenuBtn::setInfo(int direction, QWidget *childWidget)
{
m_direction = direction;
m_childWidget = childWidget;
if (childWidget)
{
DEBUGLOG<<childWidget->rect();
m_menu = new UMenu(this); Q_CHECK_PTR(m_menu);
QHBoxLayout* hboxlay = new QHBoxLayout(m_menu);
hboxlay->addWidget(childWidget);
m_menu->setLayout(hboxlay);
this->setMenu(m_menu);
// this->setPopupMode(QToolButton::InstantPopup);
}
}
void MenuBtn::slotShowMenu()
{
if (m_direction == LeftTop_LeftBottom)
{
QPoint pos;
pos.setX(-m_childWidget->sizeHint().width() - width()/2);
pos.setY(0);
m_menu->exec(mapToGlobal(pos));
}
else if(m_direction == LeftTop_LeftTop)
{
QPoint pos;
pos.setX(-m_childWidget->sizeHint().width() - width()/2);
pos.setY(-m_childWidget->sizeHint().height() - height());
m_menu->exec(mapToGlobal(pos));
}
else if(m_direction == LeftTop_rightBottom)
{
QPoint pos;
pos.setX(0);
pos.setY(0);
m_menu->exec(mapToGlobal(pos));
}
else if(m_direction == LeftTop_rightTop)
{
QPoint pos;
pos.setX(0);
pos.setY(-m_childWidget->sizeHint().height() - height());
m_menu->exec(mapToGlobal(pos));
}
else if (m_direction == LeftBottom_LeftBottom)
{
QPoint pos;
pos.setX(-m_childWidget->sizeHint().width() - width()/2);
pos.setY(height());
m_menu->exec(mapToGlobal(pos));
}
else if(m_direction == LeftBottom_LeftTop)
{
QPoint pos;
pos.setX(-m_childWidget->sizeHint().width() - width()/2);
pos.setY(-m_childWidget->sizeHint().height());
m_menu->exec(mapToGlobal(pos));
}
else if(m_direction == LeftBottom_rightBottom)
{
QPoint pos;
pos.setX(0);
pos.setY(height());
m_menu->exec(mapToGlobal(pos));
}
else if(m_direction == LeftBottom_rightTop)
{
QPoint pos;
pos.setX(0);
pos.setY(-m_childWidget->sizeHint().height());
m_menu->exec(mapToGlobal(pos));
}
else if (m_direction == RightTop_LeftBottom)
{
QPoint pos;
pos.setX(-m_childWidget->sizeHint().width() + width()/2);
pos.setY(0);
m_menu->exec(mapToGlobal(pos));
}
else if(m_direction == RightTop_LeftTop)
{
QPoint pos;
pos.setX(-m_childWidget->sizeHint().width() + width()/2);
pos.setY(-m_childWidget->sizeHint().height() - height());
m_menu->exec(mapToGlobal(pos));
}
else if(m_direction == RightTop_rightBottom)
{
QPoint pos;
pos.setX(width());
pos.setY(0);
m_menu->exec(mapToGlobal(pos));
}
else if(m_direction == RightTop_rightTop)
{
QPoint pos;
pos.setX(width());
pos.setY(-m_childWidget->sizeHint().height() - height());
m_menu->exec(mapToGlobal(pos));
}
else if (m_direction == RightBottom_LeftBottom)
{
QPoint pos;
pos.setX(-m_childWidget->sizeHint().width() + width()/2);
pos.setY(height());
m_menu->exec(mapToGlobal(pos));
}
else if(m_direction == RightBottom_LeftTop)
{
QPoint pos;
pos.setX(-m_childWidget->sizeHint().width() + width()/2);
pos.setY(-m_childWidget->sizeHint().height());
m_menu->exec(mapToGlobal(pos));
}
else if(m_direction == RightBottom_rightBottom)
{
QPoint pos;
pos.setX(width());
pos.setY(height());
m_menu->exec(mapToGlobal(pos));
}
else if(m_direction == RightBottom_rightTop)
{
QPoint pos;
pos.setX(width());
pos.setY(-m_childWidget->sizeHint().height());
m_menu->exec(mapToGlobal(pos));
}
else
m_menu->exec(mapToGlobal(QPoint(0,0)));
}
UMenu::UMenu(QWidget *parent):QMenu(parent)
{
}
void UMenu::mouseReleaseEvent(QMouseEvent *e)
{
//屏蔽QMenu::mouseReleaseEvent(e),达到拦截点击的目的,使其点击menu里面任何位置都无效。
// QAction *action = this->actionAt(e->pos());
// if (action)
// {
// action->activate(QAction::Trigger);
// }
// else
// {
// QMenu::mouseReleaseEvent(e);
// }
}