72 lines
2.4 KiB
Python
72 lines
2.4 KiB
Python
from PySide import QtGui
|
|
|
|
class SafeViewer(QtGui.QWidget):
|
|
"""FreeCAD uses a modified version of QuarterWidget, so the import pivy.quarter one will cause segfaults.
|
|
FreeCAD's FreeCADGui.createViewer() puts the viewer widget inside an MDI window, and detaching it without causing segfaults on exit is tricky.
|
|
This class contains some kludges to extract the viewer as a standalone widget and destroy it safely."""
|
|
def __init__(self, parent = None):
|
|
super(SafeViewer, self).__init__()
|
|
import FreeCADGui
|
|
self.viewer = FreeCADGui.createViewer()
|
|
self.graphicsView = self.viewer.graphicsView()
|
|
self.oldGraphicsViewParent = self.graphicsView.parent()
|
|
self.oldGraphicsViewParentParent = self.oldGraphicsViewParent.parent()
|
|
self.oldGraphicsViewParentParentParent = self.oldGraphicsViewParentParent.parent()
|
|
|
|
# Avoid segfault but still hide the undesired window by moving it to a new hidden MDI area.
|
|
self.hiddenQMDIArea = QtGui.QMdiArea()
|
|
self.hiddenQMDIArea.addSubWindow(self.oldGraphicsViewParentParentParent)
|
|
|
|
self.private_widget = self.oldGraphicsViewParent
|
|
self.private_widget.setParent(parent)
|
|
|
|
self.setLayout(QtGui.QVBoxLayout())
|
|
self.layout().addWidget(self.private_widget)
|
|
self.layout().setContentsMargins(0,0,0,0)
|
|
|
|
def fin(slf):
|
|
slf.finalizer()
|
|
|
|
import weakref
|
|
weakref.finalize(self, fin, self)
|
|
|
|
self.destroyed.connect(self.finalizer)
|
|
|
|
def finalizer(self):
|
|
# Cleanup in an order that doesn't cause a segfault:
|
|
self.private_widget.setParent(self.oldGraphicsViewParentParent)
|
|
self.oldGraphicsViewParentParentParent.close()
|
|
self.oldGraphicsViewParentParentParent = None
|
|
self.oldGraphicsViewParentParent = None
|
|
self.oldGraphicsViewParent = None
|
|
self.graphicsView = None
|
|
self.viewer = None
|
|
#self.parent = None
|
|
self.hiddenQMDIArea = None
|
|
|
|
"""
|
|
# Example use:
|
|
from PySide import QtGui
|
|
import pivy
|
|
def mk(v):
|
|
w = QtGui.QMainWindow()
|
|
oldFocus = QtGui.QApplication.focusWidget()
|
|
sv.widget.setParent(w)
|
|
oldFocus.setFocus()
|
|
w.show()
|
|
col = pivy.coin.SoBaseColor()
|
|
col.rgb = (1, 0, 0)
|
|
trans = pivy.coin.SoTranslation()
|
|
trans.translation.setValue([0, 0, 0])
|
|
cub = pivy.coin.SoCube()
|
|
myCustomNode = pivy.coin.SoSeparator()
|
|
myCustomNode.addChild(col)
|
|
myCustomNode.addChild(trans)
|
|
myCustomNode.addChild(cub)
|
|
sv.viewer.getViewer().setSceneGraph(myCustomNode)
|
|
sv.viewer.fitAll()
|
|
return w
|
|
sv = SafeViewer()
|
|
ww=mk(sv)
|
|
"""
|