一、问题来源
最近在开发PySide6应用,需要实现利用鼠标拖拽窗口。在参考别人写的代码时遇到一个问题,如使用event.globalPos()代码获取屏幕点击位置,则出现‘QMouseEvent.globalPos() const‘ is marked as deprecated告警,看着很不舒服。如下图:
代码如下:
# 在遮罩中点击鼠标左键时, 遮罩将和鼠标位置绑定
def mousePressEvent(self, event):
if event.button() == Qt.LeftButton:
self.is_follow_mouse = True
# globalPos() 事件触发点相对于桌面的位置
# pos() 程序相对于桌面左上角的位置,实际是窗口的左上角坐标
self.mouse_drag_pos = event.globalPos() - self.pos()
event.accept()
# 拖动时鼠标图形的设置
self.setCursor(QCursor(Qt.OpenHandCursor))
# 鼠标移动时调用,实现宠物随鼠标移动
def mouseMoveEvent(self, event):
# 如果鼠标左键按下,且处于绑定状态
if Qt.LeftButton and self.is_follow_mouse:
# 宠物随鼠标进行移动
self.move(event.globalPos() - self.mouse_drag_pos)
event.accept()
# 鼠标释放调用,取消绑定
def mouseReleaseEvent(self, event):
self.is_follow_mouse = False
# 鼠标图形设置为箭头
self.setCursor(QCursor(Qt.ArrowCursor))
# 鼠标移进时调用
def enterEvent(self, event):
# 设置鼠标形状 Qt.ClosedHandCursor
self.setCursor(Qt.ClosedHandCursor)
二、问题分析
经过网上查阅资料发现:event.globalPos() 函数在6.0的Qt版本中已经被弃用(过期)。如继续使用这些代码,意味着在未来的Qt版本中,这个函数可能会被移除。
详细情况请见以下网站:https://doc.qt.io/qt-6/qmouseevent-obsolete.html
中文翻译如下:
自 6.0 起,此函数已弃用。我们强烈建议不要在新代码中使用它。
请改用 globalPosition().toPoint()替代。
返回事件发生时鼠标光标的全局位置。这在像 X11 这样的异步窗口系统上很重要。每当您移动小部件以响应鼠标事件时,globalPos()可能与当前指针位置QCursor.pos() 和QWidget.mapToGloball(pos())有很大不同。
三、解决方案
event.globalPos() 用于获取触发事件时鼠标所在的全局坐标。在Qt中,这个函数曾经用于QEvent事件对象,但现在已经被标记为过时。解决方案如下:
可以尝试使用 event.globalPosition().toPoint() 或者 QCursor.pos() 来代替 event.globalPos()。
例如,如果你的代码原来是这样的:
QPoint globalPos = event.globalPos();
尝试将其修改为:
QPoint globalPos = event.globalPosition().toPoint();
或者使用 QCursor.pos();
QPoint globalPos = QCursor.pos();
需要注意的时,QCursor.pos() 返回的是鼠标当前位置的全局坐标,这可能与事件触发时的位置不同,如果你需要事件触发时的全局位置,应使用 event.globalPosition().toPoint()。
博主上文提到的代码,使用QCursor.pos()进行替换,经修改和测试后,告警不再出现,且程序运行正常,如下图:
新代码如下:
# 在遮罩中点击鼠标左键时, 遮罩将和鼠标位置绑定
def mousePressEvent(self, event):
if event.button() == Qt.LeftButton:
self.is_follow_mouse = True
# globalPos() 事件触发点相对于桌面的位置
# pos() 程序相对于桌面左上角的位置,实际是窗口的左上角坐标
self.mouse_drag_pos = QCursor.pos() - self.pos()
event.accept()
# 拖动时鼠标图形的设置
self.setCursor(QCursor(Qt.OpenHandCursor))
# 鼠标移动时调用,实现宠物随鼠标移动
def mouseMoveEvent(self, event):
# 如果鼠标左键按下,且处于绑定状态
if Qt.LeftButton and self.is_follow_mouse:
# 宠物随鼠标进行移动
self.move(QCursor.pos() - self.mouse_drag_pos)
event.accept()
# 鼠标释放调用,取消绑定
def mouseReleaseEvent(self, event):
self.is_follow_mouse = False
# 鼠标图形设置为箭头
self.setCursor(QCursor(Qt.ArrowCursor))
# 鼠标移进时调用
def enterEvent(self, event):
# 设置鼠标形状 Qt.ClosedHandCursor
self.setCursor(Qt.ClosedHandCursor)