Python 获取wrapInstance的父级会导致窗口中断
我一直在使用一个修改版本的代码在Maya自己的Python 获取wrapInstance的父级会导致窗口中断,python,qt,pyside2,Python,Qt,Pyside2,我一直在使用一个修改版本的代码在Maya自己的workspaceControl中包装一个Qt窗口。为了获得小部件的外部级别以查询几何体、大小、移动等,我实际上需要执行self.parent().parent().parent().parent().parent().parent(),因为它被包装在许多小部件中 我一直在研究一到两个由这样做引起的各种问题,但今天我发现了一些更重要的问题,并决定找出确切的原因 通过测试,我已经尽可能地缩小了代码的范围,我发现这是在尝试获取shiboken2.wrap
workspaceControl
中包装一个Qt窗口。为了获得小部件的外部级别以查询几何体、大小、移动等,我实际上需要执行self.parent().parent().parent().parent().parent().parent()
,因为它被包装在许多小部件中
我一直在研究一到两个由这样做引起的各种问题,但今天我发现了一些更重要的问题,并决定找出确切的原因
通过测试,我已经尽可能地缩小了代码的范围,我发现这是在尝试获取shiboken2.wrapInstance
的父级时发生的。尝试创建窗口之后,出现一个错误,说“代码>运行时错误:已经删除了内部C++对象(PySID2.qtWistGo.QWIDGET)。< /Cord>.<
import maya.OpenMayaUI as omUI
import pymel.core as pm
import shiboken2
from PySide2 import QtWidgets
win_id = 'test'
#Delete existing window
if pm.workspaceControl(win_id, exists=True):
pm.deleteUI(win_id)
#Create window and setup wrapper
pm.workspaceControl(win_id)
c_pointer = omUI.MQtUtil.findControl(win_id)
parent_wrap = shiboken2.wrapInstance(int(c_pointer), QtWidgets.QWidget)
print parent_wrap.parent()
#Create actual window
#This will error if parent_wrap.parent() was called
win = QtWidgets.QMainWindow(parent_object)
如何在不引起问题的情况下获取wrap实例的父级?我认为这与过早地从内存中取消引用有关,但我不确定如何着手修复它。我找到了一个修复程序,虽然有点脏,但到目前为止似乎工作可靠 因此,首先我发现,如果您创建上述
父对象的两个实例,并在创建第二个实例之前获取父对象,则可以单独进入窗口而不会引起问题。它一直工作到窗口停靠/分离的点,但这会删除旧父级并提供新父级,因此旧指针不再有效
在初始化窗口之前提供此父级似乎允许我在不破坏代码的情况下使用self.parent().parent()…
对其进行重新计算
如果状态已更改(浮动/停靠),并且每当发生运行时错误
时,都需要更新它,但由于它不会对性能造成巨大影响,为简单起见,我只是在每次需要时重新生成它
要覆盖一个函数,例如move
,以下是如何使用它:
def move(self, x, y):
if self.dockable:
return self._parent_override().move(x, y)
return QtWidgets.QMainWindow.move(self, x, y)
这是解决问题的override类:
def _parent_override(self, create=True):
#Determine if it's a new window, we need to get the C++ pointer again
if not hasattr(self, '__temp_parent'):
base = qt_get_window(self.ID)
else:
base = self.parent()
#Get the correct parent level
if pm.workspaceControl(self.ID, query=True, floating=True):
parent = base.parent().parent().parent().parent()
else:
parent = base.parent().parent()
#Even though this attribute is never used,
#PySide2 is dumb and deletes the parent if it's not set
self.__temp_parent = parent
return parent