我在Qt 4.6写作。我想知道是否有可能实现这样的菜单项,它可以被触发,但也有一个子菜单。单击它会触发相关操作,将鼠标悬停会显示子菜单。
答案 0 :(得分:1)
首先我要说这不是一个好的攻击计划。这里有一些极端情况需要花费大量的时间和代码才能做到正确,并且可能需要按操作系统进行定制。
然而,据说,实际的实施并不太复杂。只需将您正在创建子菜单的QMenu子类化,并覆盖事件处理程序,在进行“选择”时强制关闭父菜单。像下面这样的东西基本上有效:
from PyQt4 import QtCore, QtGui
import sys
app = QtGui.QApplication(sys.argv)
widget = QtGui.QMainWindow()
widget.resize(250,150)
menu = widget.menuBar().addMenu("test")
class submenu(QtGui.QMenu): #Override the submenu class
def __init__(self,name):
QtGui.QMenu.__init__(self,name)
def mouseReleaseEvent(self,event): #catch mouseRelease Events
global menu
QtGui.QMenu.mouseReleaseEvent(self,event)
if not self.rect().contains(event.pos()):
print("Parent Selected")
menu.hide() #If the parent was selected, hide it
else: #Likely ignore these
print("Parent NOT Selected")
def c():
print("Sub-item selected")
cMenu = submenu("Sub-menu")
menu.addMenu(cMenu)
actionC = QtGui.QAction("sub-item",widget)
actionC.triggered.connect(c)
cMenu.addAction(actionC)
widget.show()
sys.exit(app.exec_())
答案 1 :(得分:0)
这种行为有点令人困惑,但我试图用尽可能少的点击来开发UI。虽然有点意外,但这种行为使你在习惯它时使用起来会快一些。
我在上一条消息中没有写过,但是我用c ++编写,我不知道python ...无论如何我设法将想法翻译成c ++,但是它很有效但是很难看......我通过查看qt源找到了一个更好的方法(当我问这个问题时,我希望有一些更好的,“预期的”方法)
class MyMenu : public QMenu
{
Q_OBJECT
public:
MyMenu(QWidget* parent);
~MyMenu();
virtual void mouseReleaseEvent( QMouseEvent * event );
};
MyMenu::MyMenu(QWidget* parent):QMenu(parent)
{
}
MyMenu::~MyMenu()
{
}
void MyMenu::mouseReleaseEvent( QMouseEvent * event ){
QAction* act = menuAction();
if (act){
QMenu* men = act->menu();
act->setMenu(0);
QMenu::mouseReleaseEvent(event);
act->setMenu(men);
}else{
QMenu::mouseReleaseEvent(event);
}
}
唯一的缺点是这样的菜单会对单击子菜单的所有选项做出反应,而不仅仅是所需的选项。也许最好检查是否有任何东西与动作的信号有关?
在我的ubuntu上它有效。但是,我想它不适用于Windows,系统专门管理菜单(除非qt使用一些菜单的外观和感觉,而不是系统菜单),但我懒得安装窗口只是为了检查它;)
答案 2 :(得分:0)
void CustomMenu::mouseReleaseEvent( QMouseEvent* event )
{
QAction* action = menuAction();
// Filter out submenus. TODO: Is there a better way to do this?
if ( action && !rect().contains( event->pos() ) ) {
QMenu* menu = action->menu();
action->setMenu( 0 );
QMenu::mouseReleaseEvent( event );
emit customTriggeredSignal();
action->setMenu( menu );
}
else {
QMenu::mouseReleaseEvent( event );
}
}
将j_kubik和jkerian的两个有用答案结合在一起,顶层菜单子类QMenu中的mouseReleaseEvent()会忽略子菜单的不必要调用。
我将报告该方法是否适用于Windows。