'PyQt5 A QA about menubar visibility by mouseover

Im using PyQT5 and Python Version is 3.78.

I got a request than when I mouse over the button and display menubar.I made that code and it works.

import sys

from PyQt5 import QtWidgets
from PyQt5.QtCore import Qt, QEvent
from PyQt5.QtGui import QIcon, QFont
from PyQt5.QtWidgets import (QApplication, QMainWindow, QAction, qApp, QInputDialog, QLineEdit)

from app.strategy.menu_strategy import MenuStrategy


class DrawMenuWnd(QMainWindow):

    def __init__(self, title, parent=None):
        super(DrawMenuWnd, self).__init__(parent)
        self.ctrl = None    # source from wnd hook event
        # self.menu_stg_obj = MenuStrategy(state_mq)  # stop operation when input sth..
        # set title
        self.setWindowTitle(title)
        # set win size and attrs
        self.setGeometry(100, 100, 100, 100)
        self.setWindowFlags(Qt.FramelessWindowHint | Qt.Tool | Qt.WindowStaysOnTopHint)
        self.initial_ui()

    def initial_ui(self):
        self.menubar = self.menuBar()
        self.menubar.setFont(QFont('微软雅黑'))
        self.coin = QIcon(r'./arrow.jpeg')
        # root menu
        self.root_menu = self.menubar.addMenu(self.coin, "")
        # mouse child menu
        self.left_single = QAction("left click", self)
        self.left_double_single = QAction("left double click", self)
        self.right_single = QAction("right click", self)
        self.root_menu.addAction(self.left_single)
        self.root_menu.addAction(self.left_double_single)
        self.root_menu.addAction(self.right_single)
        # seperator
        self.root_menu.addSeparator()
        # keyboard child menu
        self.input = QAction("keyboard input", self)
        self.root_menu.addAction(self.input)
        # connect function
        # self.left_single.triggered.connect(self.menu_stg_obj.click)
        # self.left_double_single.triggered.connect(self.menu_stg_obj.double_click)
        # self.right_single.triggered.connect(self.menu_stg_obj.right_click)
        # self.input.triggered.connect(self.menu_stg_obj.keyboard_input)
        # set event filter
        self.menubar.installEventFilter(self)

    @classmethod
    def initial_menu(cls, title):
        app = QtWidgets.QApplication(sys.argv)
        window = DrawMenuWnd(title)
        window.show()
        app.exec_()

    def eventFilter(self, object, event):
        try:
            if event.type() == QEvent.Enter:
                print("Mouse is over the label")
                if self.root_menu.isHidden():
                    self.root_menu.show()
                # print('program stop is', self.stop)
                return True
            elif event.type() == QEvent.Leave:
                print("Mouse is not over the label")
                self.root_menu.hide()
                # print('program stop is', self.stop)
            return False
        except Exception as error:
            print(error)


if __name__ == '__main__':
    app = QApplication(sys.argv)
    window = DrawMenuWnd("")
    window.show()
    sys.exit(app.exec())

Now I got a question that when I mouse away from button, the menubar should disappear but now not. So now I wanna let the menubar disappear after my mouse away from the button, I try to hide the menubar in using function hide() but it not works

Anybody help?

thanks



Solution 1:[1]

What I meant is something like that :

import sys

from PyQt5 import QtWidgets
from PyQt5.QtCore import Qt, QEvent
from PyQt5.QtGui import QIcon, QFont
from PyQt5.QtWidgets import (QApplication, QMainWindow, QAction, qApp, QInputDialog, QLineEdit,QMenu)




class MyQMenu(QMenu):
    def __init__(self, *args, **kwargs):
        QMenu.__init__(self, *args, **kwargs)

    def leaveEvent(self, QEvent):
        # here the code for mouse leave
        self.close()
        print('Leave')



class DrawMenuWnd(QMainWindow):

    def __init__(self, title, parent=None):
        super(DrawMenuWnd, self).__init__(parent)
        self.ctrl = None    # source from wnd hook event
        # self.menu_stg_obj = MenuStrategy(state_mq)  # stop operation when input sth..
        # set title
        self.setWindowTitle(title)
        # set win size and attrs
        self.setGeometry(100, 100, 100, 100)
        self.setWindowFlags(Qt.FramelessWindowHint | Qt.Tool | Qt.WindowStaysOnTopHint)
        self.initial_ui()

    def initial_ui(self):
        self.menubar = self.menuBar()
        self.menubar.setFont(QFont('????'))
        self.coin = QIcon(r'./arrow.jpeg')
        # root menu
        self.root_menu = MyQMenu( "")
        self.root_menu.setIcon(self.coin)
        self.menubar.addMenu(self.root_menu)
        # mouse child menu
        self.left_single = QAction("left click", self)
        self.left_double_single = QAction("left double click", self)
        self.right_single = QAction("right click", self)
        self.root_menu.addAction(self.left_single)
        self.root_menu.addAction(self.left_double_single)
        self.root_menu.addAction(self.right_single)
        # seperator
        self.root_menu.addSeparator()
        # keyboard child menu
        self.input = QAction("keyboard input", self)
        self.root_menu.addAction(self.input)
        # connect function
        # self.left_single.triggered.connect(self.menu_stg_obj.click)
        # self.left_double_single.triggered.connect(self.menu_stg_obj.double_click)
        # self.right_single.triggered.connect(self.menu_stg_obj.right_click)
        # self.input.triggered.connect(self.menu_stg_obj.keyboard_input)
        # set event filter
        self.menubar.installEventFilter(self)

    @classmethod
    def initial_menu(cls, title):
        app = QtWidgets.QApplication(sys.argv)
        window = DrawMenuWnd(title)
        window.show()
        app.exec_()

    def eventFilter(self, object, event):
        try:
            if event.type() == QEvent.Enter:
                print("Mouse is over the label")
                if self.root_menu.isHidden():
                    self.root_menu.show()
                # print('program stop is', self.stop)
                return True
            elif event.type() == QEvent.Leave:
                print("Mouse is not over the label")
                self.root_menu.hide()
                # print('program stop is', self.stop)
            return False
        except Exception as error:
            print(error)


if __name__ == '__main__':
    app = QApplication(sys.argv)
    window = DrawMenuWnd("")
    window.show()
    sys.exit(app.exec())

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1 ymmx