python - qwidget.setGeometry() 在 linux 上的位置不正确
问题描述
我正在尝试使用 qt 小部件覆盖 Maya 的活动视图 3d。
我有一个画布基类(一个透明小部件),我可以在上面做一些绘画。它的父级是包装的 avtice 3d 视图。一旦活动 3d 视图调整大小,就会发出 CanvasEventFilter.resize_event 信号以调整画布小部件的大小。
在 mac 和 windows 上一切正常。但是在 linux 上,小部件是偏移的。我从 mapToGlobal() 得到的值似乎是正确的。但是 setGeometry() 不会像我期望的那样更新小部件的位置和大小。
我在这里想念什么?
from PySide2.QtGui import QPainter, QPen, QPainterPath
from PySide2.QtCore import Qt, QObject, Signal, Slot, QEvent, QPointF, QPoint
from PySide2.QtWidgets import QWidget, QLabel, QGridLayout
import maya.OpenMayaUI as omui
import shiboken2
class CanvasEventFilter(QObject):
resize_event = Signal(QEvent)
def __init__(self):
super(CanvasEventFilter, self).__init__()
def eventFilter(self, obj, event):
if event.type() == QEvent.Resize:
self.resize_event.emit(event)
return False
class Canvas(QWidget):
def __init__(self, parent):
super(Canvas, self).__init__(parent=parent)
self.setWindowFlags(Qt.FramelessWindowHint | Qt.SplashScreen | Qt.WindowStaysOnTopHint | Qt.WindowTransparentForInput)
# self.setAttribute(Qt.WA_TranslucentBackground)
# self.setAttribute(Qt.WA_NoSystemBackground)
# self.setAttribute(Qt.WA_PaintOnScreen)
# self.setAttribute(Qt.WA_TransparentForMouseEvents)
self.canvas_event_filter = CanvasEventFilter()
self.install_event_filter()
self.resize()
self.show()
def install_event_filter(self):
self.canvas_event_filter.resize_event.connect(self.resize)
view_wdg = window_utils.active_view_wdg()
view_wdg.installEventFilter(self.canvas_event_filter)
def remove_event_filter(self):
view_wdg = active_view_wdg()
view_wdg.removeEventFilter(self.canvas_event_filter)
@Slot(QEvent)
def resize(self):
view_wdg = active_view_wdg()
wdg_size = view_wdg.rect()
wdg_pos = view_wdg.pos()
abs_pos = view_wdg.mapToGlobal(wdg_pos)
self.setGeometry(abs_pos.x(), abs_pos.y(), wdg_size.width(), wdg_size.height())
def __del__(self):
self.remove_event_filter()
def active_view_wdg():
view = omui.M3dView.active3dView()
active_view_widget = shiboken2.wrapInstance(long(view.widget()), QWidget)
return active_view_widget
mac 上的黑色小部件正是预期的位置。在linux上它是偏移的
解决方案
这在 Centos 7 上似乎对我来说非常有效。当主窗口移动时,小部件会跟随,并在调整主窗口大小时正确调整大小。
我不得不重命名您的resize
方法,因为这意外地覆盖了小部件的QtWidgets.QWidget.resize
方法(或者只需要使用它super
)。而不是setGeometry
我可以简单地使用QtWidgets.QWidget.resize
. 我也必须删除Qt.SplashScreen
,否则它没有正确跟随或调整大小:
from PySide2.QtGui import QPainter, QPen, QPainterPath
from PySide2.QtCore import Qt, QObject, Signal, Slot, QEvent, QPointF, QPoint, QSize
from PySide2.QtWidgets import QWidget, QLabel, QGridLayout
import maya.OpenMayaUI as omui
import shiboken2
class CanvasEventFilter(QObject):
resize_event = Signal(QEvent)
def __init__(self):
super(CanvasEventFilter, self).__init__()
def eventFilter(self, obj, event):
if event.type() == QEvent.Resize:
self.resize_event.emit(event)
return False
class Canvas(QWidget):
def __init__(self, parent):
super(Canvas, self).__init__(parent=parent)
self.setWindowFlags(Qt.FramelessWindowHint | Qt.WindowStaysOnTopHint | Qt.WindowTransparentForInput)
self.setStyleSheet("QWidget {background-color:black;}")
self.canvas_event_filter = CanvasEventFilter()
self.install_event_filter()
self.resize_event()
self.show()
def install_event_filter(self):
self.canvas_event_filter.resize_event.connect(self.resize_event)
view_wdg = active_view_wdg()
view_wdg.installEventFilter(self.canvas_event_filter)
def remove_event_filter(self):
view_wdg = active_view_wdg()
view_wdg.removeEventFilter(self.canvas_event_filter)
@Slot(QEvent)
def resize_event(self):
view_wdg = active_view_wdg()
wdg_size = view_wdg.rect()
wdg_pos = view_wdg.pos()
abs_pos = view_wdg.mapToGlobal(wdg_pos)
self.resize(wdg_size.width(), wdg_size.height())
def __del__(self):
self.remove_event_filter()
def active_view_wdg():
view = omui.M3dView.active3dView()
active_view_widget = shiboken2.wrapInstance(long(view.widget()), QWidget)
return active_view_widget
tool = Canvas(active_view_wdg())
tool.show()
推荐阅读
- javascript - 使用 jQuery 打开可折叠侧边栏选项
- javascript - gsap动画的反向播放
- reactjs - 网络摄像头无法用于生产,未显示许可弹出窗口
- angular - Angular - 下拉验证 - 在 mouseup 事件之前显示验证
- visual-studio-code - 使用多个容器设置 Visual Studio Code
- c# - 获取 EventHandler 以在原始线程上调用 Invoke()
- javascript - TypeError:无法读取未定义的属性“长度” - Firebase
- python - 为什么我们不能为调度方法表中的函数添加括号 - Python?
- c++ - 如何通过 HTTP 将 RapidJSON::Document 作为 json 而不是字符串发送?
- ios - 反应原生 PIP