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

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

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

我试过了,但没用:

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

代码示例:

from PySide2 import QtWidgets, QtCore

class MySizeGrip(QtWidgets.QSizeGrip):

def __init__(*args, **kwargs):
    super(MySizeGrip, self).__init__(*args, **kwargs)
    self.setMouseTracking(True)
    self.installEventFilter(True)
    self.is_pressed: bool = False

def mousePressEvent(self, event):
    if event.button() is QtCore.Qt.MouseButton.LeftButton:
        self.is_pressed = True
    super().mousePressEvent(event)

def eventFilter(self, obj, event):
    if event.type() in (event.MouseButtonRelease, event.NonClientAreaMouseButtonRelease):
        self.is_pressed = False

def mouseMoveEvent(self, event):
    dialog = self.parent().parent()
    if self.is_pressed:
        rect = dialog.geometry()
        # set cursor to position so that it not crosses the window boundary but we don't get the event anywy during dragging process


class MyDialog(QtWidgets.QDialog):

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

def _activate(self):
   self.setWindowState(QtCore.Qt.WindowActive)
   self.activateWindow()
   self.raise_()

def _exec():
   self._activate()
   self.exec()
   self.deleteLater()

def __build(self):
   self.setWindowFlags(QyCore.Qt.FramelessWindowHint | QyCore.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)
   
   # adding titlebar
   # adding content

   self.sizeGrip = MySizeGrip(self)
   self.background_grd.addWidget(self.sizeGrip, 1, 0, QtCore.Qt.AlignRight | QtCore.Qt,AlignBottom)
python qt pyside2 qdialog qsizegrip
© www.soinside.com 2019 - 2024. All rights reserved.