我正在尝试使用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()

关于python - qwidget.setGeometry()在Linux上的位置不正确,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/51346212/

10-16 05:05