在触发 QEvent.NonClientAreaMouseButtonRelease 时使用 QSizeGrip 调整大小后,我无法以编程方式恢复对 QDialog 的关注

问题描述 投票:0回答:0

H。我有一个无框架的子类 QDialog,用 .exec() 显示。在里面我有几个其他的小部件,它们有自己的悬停事件和滚动条。当我在对话框上实现 QSizeGrip 并将其用于放大时,问题就出现了。如果我的鼠标移动超出对话框的最大高度/宽度,我会触发 QEvent.NonClientAreaMouseButtonRelease(对话框中有一个 MouseButtonPress,但它从未收到 MouseButtonRelease)。结果是,在我将光标移到对话框上后,小部件不会对任何内容做出反应(悬停动画不起作用,我无法滚动滚动条)。没有焦点。只有单击对话框才能重新激活它,这有点烦人。 在这里要明确的是,调整大小功能没有任何问题。我将 QSizeGrip 子类化以查看其上的点击事件,因为不知何故对话框看不到它们。

我试过了,但没用:

  1. eventFilter 对话框和 sizegrip 忽略 NonClientAreaMouseButtonRelease
  2. 在 NonClientAreaMouseButtonRelease 从那个 eventFilter 或 QTimer.singleShot 之后运行 setFocus() / activateWindow() / raise_() - 窗口激活不做任何事情
  3. 在 NonClientAreaMouseButtonRelease 之后模拟对话框上的鼠标点击事件
  4. 当光标达到最大高度或最大宽度时,将光标限制在对话框的边界,但在调整对话框大小时,没有发送 MouseMovement 事件来检测我们将过度拖动光标的位置。

代码:

from PySide2 import QtWidgets, QtCore


class MyDialog(QtWidgets.QDialog):

    def __init__(self, *args, **kwargs):
        super(MyDialog, self).__init__(*args, **kwargs)
        self.setMouseTracking(True)
        self.__build()


    def event(self, event: QtCore.QEvent):
        if event.type() is event.NonClientAreaMouseButtonRelease:
            release_event = QtGui.QMouseEvent(
                QtCore.QEvent.MouseButtonRelease,
                self.mapToGlobal(QtCore.QPoint(self.rect().left(), self.rect().top())),
                QtCore.Qt.LeftButton,
                QtCore.Qt.LeftButton,
                QtCore.Qt.NoModifier
        )
            QtCore.QTimer.singleShot(1, lambda: QtWidgets.QApplication.sendEvent(self, release_event))
            event.accept()
        return super().event(event)

    def mouseReleaseEvent(self, event: QtGui.QMouseEvent) -> None:
        print("Size: ", self.size())
        print("Pos: ", event.globalPos())
        return super().mouseReleaseEvent(event)

    def __build(self):
        self.setWindowFlags(QtCore.Qt.FramelessWindowHint | QtCore.Qt.WindowStaysOnTopHint)
        grid = QtWidgets.QGridLayout(self)
        grid.setSpacing(0)
        grid.setContentsMargins(0, 0, 0, 0)
        self.background_frm = QtWidgets.QFrame(self)
        grid.addWidget(self.background_frm, 0, 0, 1, 1)
        self.background_grd = QtWidgets.QGridLayout(self.background_frm)
        self.background_grd.setSpacing(0)
        self.background_grd.setContentsMargins(0, 0, 0, 0)

        titlebar_lbl = QtWidgets.QLabel(self, text="TITLE BAR")
        titlebar_lbl.setStyleSheet(
            """
            QLabel {
                   border: 1px solid black;
                   padding: 0px 10px 0px 10px; 
                    }
            """
        )
        titlebar_lbl.setMinimumHeight(35)
        self.background_grd.addWidget(titlebar_lbl, 0, 0, 1, 1)

        self.content_frm = QtWidgets.QFrame(self)
        self.content_frm.setSizePolicy(QtWidgets.QSizePolicy.Expanding, QtWidgets.QSizePolicy.Expanding)
        self.background_grd.addWidget(self.content_frm, 1, 0, 1, 1)

        self.content_vlt = QtWidgets.QVBoxLayout(self.content_frm)

        button = QtWidgets.QPushButton(self, text="TEST BUTTON")
        button.setStyleSheet(
            """
            QPushButton {
                        border: 2px solid black;
                        background-color: red;
                        color: white;
                        width: 100px;
                        height: 30px;
                        }
            QPushButton:hover {
                        background-color: green;;
            }
            """
        )
        self.content_vlt.addWidget(button, alignment=QtCore.Qt.AlignHCenter)
        
        self.setSizeGripEnabled(True)
        self.setMaximumSize(QtCore.QSize(150, 150))


if __name__ == "__main__":
    qapp = QtWidgets.QApplication([])
    dlg = MyDialog()
    dlg.exec_()
python qt pyside2 qdialog qsizegrip
© www.soinside.com 2019 - 2024. All rights reserved.