在窗口中古创建一个右击菜单步骤:
1. 重写上下文菜单事件–contextMenuEvent(QContextMenuEvent * event);
void MyWidget::contextMenuEvent(QContextMenuEvent * event)
{
if(ui.menuBtn->underMouse()) //如果鼠标右击的是menuBtn控件,才弹出菜单
{
//m_rightClieckMenu->exec(QCursor::pos()); //QCursor::pos()获取鼠标右键点击的位置,在此弹出菜单
m_rightClieckMenu->exec(event->globalPos()); // 让菜单在鼠标点击的位置弹出
}
}
2. 创建菜单项 – QAction
m_rightClieckMenu = new QMenu(this);
//设置菜单样式
m_rightClieckMenu ->setStyleSheet("QMenu::item{color:rgb(188, 190, 191);border:none;color:black;height:30px;}" //设置菜单item的样式
"QMenu::item:hover{color:red;}"
"QMenu::item:pressed{color: rgb(62, 140, 204);}"
“QMenu{color:green;}” //设置菜单的样式
);
//创建菜单项
QAction* m_openAction = new QAction(QString::fromLocal8Bit("打开"),this);
QAction* m_newCreatAction = new QAction(QString::fromLocal8Bit("新建"),this);
QAction* m_closeAction = new QAction(QString::fromLocal8Bit("关闭"),this);
//将创建好的菜单项加入到菜单中
m_rightClieckMenu->addAction(m_openAction);
m_rightClieckMenu->addAction(m_newCreatAction);
m_rightClieckMenu->addAction(m_closeAction);
//关联菜单项按钮和对应的槽函数
connect(m_openAction, &QAction::triggered, this, &MyWidget::doAction);
connect(m_closeAction, &QAction::triggered, this, &MyWidget::doAction);
connect(m_newCreatAction, &QAction::triggered, this, &MyWidget::doAction);
3. 处理菜单项对应的事件
使用qobject_cast<QAction*> (sender());来获取是那个按钮被点击了,可以将菜单按钮设置为成员属性,这样方便去比较;如果菜单项比较少,可以再创建QAction时为其绑定一个槽函数也可以;
void MyWidget::doAction() //doAction()是一个槽函数
{
QAction *action = qobject_cast<QAction*>(sender()); //获取是由那个按钮发出的信号
if (action == m_openAction) //如果点击的是“打开”菜单按钮
QMessageBox::information(this, "Tips", QString::fromLocal8Bit("你点击了打开按钮"), QMessageBox::Yes);
else if (action == m_closeAction) //如果打开的是“关闭”菜单按钮
QMessageBox::information(this, "Tips", QString::fromLocal8Bit("你点击了关闭按钮"), QMessageBox::Yes);
}
到此一个最简单也是最常用的右击菜单创建就完成了;
进阶:配合其他控件提供的接口实现高级功能
1. 在QTreeWidget中使用右键菜单时,鼠标单击不同的Item弹出不同菜单
核心方法:
QTreeWidget提供了一个 customContextMenuRequested(QPoint &pos)的信号,信号参数返回用户鼠标在QTreeWidget控件上的点击位置;在配合QTreeWidget的QTreeWidgetItem* QTreeWidget::itemAt( QPoint &pos)接口就可以获取到鼠标点击的位置所对应的的Item;再根据Item的父子关系去判断双击的是那一层的Item,其后弹出不同的右键菜单即可;
核心代码:
//1.在UI界面中创建QTreeWidget,关联QTreeWidget的customContextMenuRequested信号
connect(ui->EquListTree,&QTreeWidget::customContextMenuRequested,this,&DataMonitor::EquListTreeShowRightMenu);
//在槽函数EquListTreeShowRightMenu中进行处理,这个槽函数是自己定义的
QTreeWidgetItem *clickedItem = ui->EquListTree->itemAt(pos);
if(clickedItem != NULL)
{
QTreeWidgetItem *tmpItem = clickedItem;
QTreeWidgetItem *equItem = NULL;
int conutLevel = 1;
//循环判断是那一层的Item
while(tmpItem->parent())
{
conutLevel++;
tmpItem = tmpItem->parent();
}
//右键弹出响应菜单
if(conutLevel == 1)
{
topItemMoveMenu->exec(QCursor::pos()); //弹出第一层Item对应的菜单
}
if(conutLevel == 2)
{
equTreeEquMenu->exec(QCursor::pos()); //弹出第二层Item对应的菜单
}
}
2. 鼠标右击指定控件,比如QPushButton才允许弹出菜单
Qt提供了一个接口 underMouse()可以用来判断某个空控件是不是出于鼠标按键下;可以在菜单事件中使用进行判断,大体使用如下:
void DataMonitor::contextMenuEvent(QContextMenuEvent *event)
{
if(ui->pushButton->underMouse()) //如果鼠标当前正处于按钮下
{
//doSomething......
}
}