【问题标题】:Qt detecting mouse click on titleBar (Windows)Qt检测鼠标点击titleBar(Windows)
【发布时间】:2017-09-08 08:04:36
【问题描述】:

事件或 mousePressEvent 函数适用于小部件内部,但我想在单击标题栏时捕捉(菜单栏的上部,包含关闭按钮等)

我该怎么做?

【问题讨论】:

  • 该问题有明显的XY Problem 迹象。你想完成什么?
  • 我有一个对话框,当按下退出按钮时,它在其父窗口中最小化。如果鼠标单击其标题栏区域,我想将其最大化。
  • @iinspectable 他的问题是关于坐标的,你回答了一个关于 XY 问题的链接,我以为你在解决一个经典的计算机科学问题,即获取不同来源的坐标。

标签: qt winapi


【解决方案1】:

您可以覆盖 nativeEvent,然后获取鼠标位置以与几何体(不包括窗口框架)和 frameGeometry(包括窗口框架)进行比较以检测它是否命中标题栏

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;
}

【讨论】:

    【解决方案2】:

    这是 PyQt 的实现。

    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_()
    

    有一件事我无法弄清楚,如果我再次单击标题栏而不单击菜单,我的菜单会发生什么。 菜单消失了,然后我可以在单击时移动标题栏 - 这很好......但我无法可靠地恢复菜单

    【讨论】:

      猜你喜欢
      • 2020-04-18
      • 2021-09-06
      • 2015-08-03
      相关资源
      最近更新 更多