Qt detecting mouse click on titleBar (Windows)

后端 未结 2 1939
你的背包
你的背包 2021-01-28 08:47

event or mousePressEvent functions works for inside of a widget but I want to catch when clicked on a titleBar (upper part of menuBar, contains close button etc.)

How ca

相关标签:
2条回答
  • 2021-01-28 09:06

    You can override nativeEvent, then get mouse position to compare with geometry (exclude window frame) and frameGeometry (include window frame) to detect if it hits title bar or not

    bool MyClass::nativeEvent(const QByteArray & eventType, void * message, long * result)
    {
        MSG* msg = (MSG*)(message);
        if (msg->message == WM_NCLBUTTONDOWN)
        {
    
            int mouseX = GET_X_LPARAM(msg->lParam);
            int mouseY = GET_Y_LPARAM(msg->lParam);
            QRect frame = frameGeometry();
            QRect content = geometry();
    
            qDebug() << "mouseX: " << mouseX << "mouseY:" << mouseY;
            qDebug() << "frame: " << frame;
            qDebug() << "content: " << content;
    
            if (mouseY < content.y() && mouseY >= frame.y())
            {
                qDebug() << "Hit title bar";
            }
        }
    
        *result = 0;
        return false;
    }
    
    0 讨论(0)
  • 2021-01-28 09:15

    Here's the PyQt implementation.

    from  PyQt5.QtWidgets import *
    from  PyQt5.QtCore import *
    
    import ctypes.wintypes
    import logging
    from win32con import *
    import win32api
    
    class W(QTabWidget):
        def nativeEvent(self, eventType, message):
            click_menu = QMenu(self)
            click_menu.addAction("Yay")
    
            try:
                msg = ctypes.wintypes.MSG.from_address(message.__int__())
            except:
                logging.error("", exc_info=True)
            if eventType == "windows_generic_MSG":
                if msg.message == WM_NCLBUTTONDOWN:
                    mouse_x = win32api.LOWORD(msg.lParam)
                    mouse_y = win32api.HIWORD(msg.lParam)
                    frame = self.frameGeometry()
                    content = self.geometry()
                    print(mouse_x, mouse_y, frame, content)
                    if mouse_y < content.y() and mouse_y >= frame.y():
    
                        click_menu.exec_(QPoint(mouse_x, mouse_y))
    
            return False, 0
    
    app = QApplication([])
    
    w = W()
    w.resize(1000,100)
    w.move(0,0)
    w.show()
    app.exec_()
    

    One thing I can't figure out about this, what happens to my menu if I click the titlebar again without clicking the menu. The menu disappears, which is then allows me to move the titlebar when clicking - which is good...but I can't reliably bring the menu back up

    0 讨论(0)
提交回复
热议问题