我遇到了一个让我疯狂的问题。 我想让QMenuBar只在被鼠标悬停时可见,否则它应该被隐藏。
到目前为止,我得到了“工作”:
class Hidden_Menubar(QtGui.QMenuBar):
def __init__(self, parent=None):
super(Hidden_Menubar, self).__init__(parent)
self.setMouseTracking(True)
def enterEvent(self,event):
self.show()
def leaveEvent(self,event):
self.hide()
和
class Ui_Template_FullScreen(object):
def setupUi(self, Template_FullScreen):
Template_FullScreen.setObjectName(_fromUtf8("Template_FullScreen"))
Template_FullScreen.showFullScreen()
self.centralwidget = QtGui.QWidget(Template_FullScreen)
self.centralwidget.setObjectName(_fromUtf8("centralwidget"))
Template_FullScreen.setCentralWidget(self.centralwidget)
self.menubar = Hidden_Menubar(Template_FullScreen)
......
问题是,只要鼠标停止盘旋QMenuBar,它就会消失(到目前为止一直很好),但如果我再次悬停QMenuBar区域则不会显示! 我想mouseMoveEvent不会触发隐藏的对象,或者是其他什么问题?我尝试了很多解决方案,例如安装事件过滤器,但是我无法正确实现它。 我对python和QT完全不熟悉,所以我自己也搞清楚了。 我感谢你的每一个帮助。
提前致谢=)
test.py: http://pastebin.com/hmRvYVup(完整代码)
编辑:谢谢大家的帮助!不幸的是我不能赞成你的帖子,因为我缺少声望:/答案 0 :(得分:1)
这是一项有趣的任务。
您的方法的主要问题是隐藏的小部件不会接收事件(或至少是鼠标事件)。但是你仍然可以在中央窗口小部件上实现覆盖mouseMoveEvent
的行为,试试这个:
class Hidden_Menubar(QtGui.QMenuBar):
def __init__(self, parent=None, centralWidget=None):
super(Hidden_Menubar, self).__init__(parent)
if centralWidget:
centralWidget.setMouseTracking(True)
centralWidget.mouseMoveEvent = self.onMove
def onMove(self, evt):
if self.isVisible():
self.hide()
elif evt.pos().y()<20:
self.show()
当然,您的Hidden_Menubar
应该以这种方式实例化:
...
self.menubar = Hidden_Menubar(Template_FullScreen,self.centralwidget)
...
希望它有所帮助。
答案 1 :(得分:1)
这比它看起来更棘手。主要问题是在整个窗口(包括所有子窗口小部件)上跟踪鼠标移动,并确保仅在适当时隐藏菜单(即,不显示菜单时)。
这样做的一种方法是在QApplication上安装event-filter(以便它接收所有子窗口小部件的鼠标移动事件),并使用activePopupWidget方法检查是否存在是任何活跃的菜单。
这是一个演示脚本,显示了一个基本实现:
from PyQt4 import QtCore, QtGui
class Window(QtGui.QMainWindow):
def __init__(self):
QtGui.QMainWindow.__init__(self)
# add a few widgets for testing
widget = QtGui.QWidget(self)
edit = QtGui.QTextEdit(widget)
button = QtGui.QPushButton('Button', widget)
layout = QtGui.QVBoxLayout(widget)
layout.addWidget(edit)
layout.addWidget(button)
self.setCentralWidget(widget)
menu = self.menuBar().addMenu('&File')
menu.addAction('&Quit', self.close)
menu = self.menuBar().addMenu('&Edit')
menu.addAction('&Clear', edit.clear)
QtGui.qApp.installEventFilter(self)
# make sure initial window size includes menubar
QtCore.QTimer.singleShot(0, self.menuBar().hide)
def eventFilter(self, source, event):
# do not hide menubar when menu shown
if QtGui.qApp.activePopupWidget() is None:
if event.type() == QtCore.QEvent.MouseMove:
if self.menuBar().isHidden():
rect = self.geometry()
# set mouse-sensitive zone
rect.setHeight(25)
if rect.contains(event.globalPos()):
self.menuBar().show()
else:
rect = QtCore.QRect(
self.menuBar().mapToGlobal(QtCore.QPoint(0, 0)),
self.menuBar().size())
if not rect.contains(event.globalPos()):
self.menuBar().hide()
elif event.type() == QtCore.QEvent.Leave and source is self:
self.menuBar().hide()
return QtGui.QMainWindow.eventFilter(self, source, event)
if __name__ == '__main__':
import sys
app = QtGui.QApplication(sys.argv)
window = Window()
window.setGeometry(500, 300, 300, 100)
window.show()
sys.exit(app.exec_())
答案 2 :(得分:1)
要求并不是真正完整的:你不能拥有一些你看不到的东西就好像你能看到它一样。隐藏时不使用策略的存在理由是菜单栏占用了大量屏幕空间并且仅在有时使用,因此在不使用时您想要隐藏它。我可以想到除了ekhumoro和xndrme提到的两种策略之外的两种策略:show-when-near,以及collapse-to-small-but-not-zero。
你应该考虑使用悬停延迟,这样只有延迟足够长时间(如半秒),菜单才会变得可见。这样可以确保您没有快速进出的小部件出现/消失,这可能会让用户感到烦恼,因为突然的变化会引起我们的注意。