TechDraw and v0.21

Discussions about the development of the TechDraw workbench
Forum rules
Be nice to others! Respect the FreeCAD code of conduct!
edi
Posts: 481
Joined: Fri Jan 17, 2020 1:32 pm

Re: TechDraw and v0.21

Post by edi »

wandererfan wrote: Sat Apr 30, 2022 12:55 pm In Python, TechDrawGui.addQGIToView(myFeature, myQGSvgItem) should do it. If not, we can add some functionality.
I tried to adopt your python script published in https://forum.freecadweb.org/viewtopic. ... 5&p=379153.

Code: Select all

import FreeCAD, FreeCADGui
import TechDraw, TechDrawGui
from PySide import QtGui, QtCore
from PySide import QtSvg # new inserted line
TDG = TechDrawGui

#class SimpleItem(QtGui.QGraphicsItem): # original line
class SimpleItem(QtSvg.QGraphicsSvgItem): # new inserted line
    def __init__(self, parent = None):
        super().__init__(parent)
        self.Type = QtGui.QGraphicsItem.UserType + 501
        self.setZValue(500)

    def boundingRect(self):
        penWidth = 10.0
        return QtCore.QRectF(-100 - penWidth / 2, -100 - penWidth / 2,
                      200 + penWidth, 200 + penWidth)

    def paint(self, painter, option, widget):
        painter.drawRoundedRect(-100, -100, 200, 200, 50, 50)

view = App.ActiveDocument.View

qgSI = SimpleItem()
obj = TDG.addQGIToView(view, qgSI); # FreeCAD crash in this line
qgSI.setPos(0.0, 0.0)
When replacing QGraphicsItem by QGraphicsSvgItem FreeCAD crashes.

As far as I could analyse, the following happenes (but I can be wrong):

In file AppTechDrawGuiPy.cpp, line 349 ff:

Code: Select all

QGraphicsItem* item = wrap.toQGraphicsItem(qgiPy);
if (item != nullptr) {
  qgiv->addArbitraryItem(item);

the function toQGraphicsItem returns a pointer having an improper type.
Subsequently in file QGIView.cpp, line 678 ff:

Code: Select all

void QGIView::addArbitraryItem(QGraphicsItem* qgi)
{
    if (qgi != nullptr) {
        addToGroup(qgi);
        qgi->show();
    }
}
addToGroup (and subseqent called Qt functions) are running out of memory.
User avatar
wandererfan
Veteran
Posts: 6309
Joined: Tue Nov 06, 2012 5:42 pm
Contact:

Re: TechDraw and v0.21

Post by wandererfan »

edi wrote: Fri May 06, 2022 3:52 pm the function toQGraphicsItem returns a pointer having an improper type.
Some derived graphics items (like QGraphicsSvgItem and QGraphicsTextItem) don't inherit directly for QGraphicsItem, but from QGraphicsObject. This confuses Shiboken in toQGraphicsItem.

git commit ccad0fac90 adds a toGraphicsObject method to the PythonWrapper and a addQGObjToView method to TechDrawGui. You will need to use addQGObjToView for items that are derived from QGraphicsObject. I would prefer one method to handle both types of item, but this will have to do.

Code: Select all

import FreeCAD, FreeCADGui
import TechDraw, TechDrawGui
from PySide import QtGui, QtCore
from PySide import QtSvg
TDG = TechDrawGui

#class SimpleItem(QtGui.QGraphicsItem):
#class SimpleItem(QtGui.QGraphicsPathItem):
#class SimpleItem(QtGui.QGraphicsTextItem): # QGraphicsObject
#class SimpleItem(QtGui.QGraphicsLineItem):
#class SimpleItem(QtGui.QGraphicsPixmapItem):
class SimpleItem(QtSvg.QGraphicsSvgItem): # QGraphicsObject
    def __init__(self, parent = None):
        super().__init__(parent)
        self.Type = QtGui.QGraphicsItem.UserType + 501
        self.setZValue(500)

    def boundingRect(self):
        penWidth = 10.0
        return QtCore.QRectF(-100 - penWidth / 2, -100 - penWidth / 2,
                      200 + penWidth, 200 + penWidth)

    def paint(self, painter, option, widget):
        painter.drawRoundedRect(-100, -100, 200, 200, 50, 50)

view = App.ActiveDocument.View

qgSI = SimpleItem()
#obj = TDG.addQGIToView(view, qgSI); # for items derived directly from QGraphicsItem
obj = TDG.addQGObjToView(view, qgSI); # for items derived from QGraphicsObject
qgSI.setPos(0.0, 0.0)
edi
Posts: 481
Joined: Fri Jan 17, 2020 1:32 pm

Re: TechDraw and v0.21

Post by edi »

Thank you for creating addQGObjToView. It is working well.

The script

Code: Select all

import FreeCAD, FreeCADGui
import TechDraw, TechDrawGui
from PySide import QtGui, QtCore, QtSvg
TDG = TechDrawGui

class SvgItem(QtSvg.QGraphicsSvgItem): 
    def __init__(self,filename,parent = None):
        super().__init__(filename,parent)
        self.Type = QtGui.QGraphicsItem.UserType + 501
        self.setZValue(500)
        self.setFlag(self.ItemIsMovable)
        self.setFlag(self.ItemIsSelectable)

view = App.ActiveDocument.View

svgFileName =  os.path.dirname(__file__) + "/Testfile.svg"

qgSvg = SvgItem(svgFileName)

TDG.addQGObjToView(view, qgSvg) 
adds an item represented by a svg-file to a view.
- The item can be selected and moved inside the view.
- If the view is moved, the item keeps its position inside the view.

The script

Code: Select all

import FreeCAD, FreeCADGui
import TechDraw, TechDrawGui
from PySide import QtGui, QtCore, QtSvg
TDG = TechDrawGui

#class Dummy(QtGui.QGraphicsItem): # ... also possible
class Dummy(QtSvg.QGraphicsSvgItem): 
    def dummy(self):
        pass

view = App.ActiveDocument.View

svgFileName =  os.path.dirname(__file__) + "/Testfile.svg"

svgItem = QtSvg.QGraphicsSvgItem(svgFileName)
svgItem.setFlag(svgItem.ItemIsMovable)
svgItem.setFlag(svgItem.ItemIsSelectable)

TDG.addQGObjToView(view, svgItem) 
has the same functionality.
But a never used dummy class, which inherits QGraphicsItem or QGraphicsSvgItem must be declared. If not, nothing happenes. Either no item is created, or the created item is invisible.
Do you have any explanation ?
User avatar
wandererfan
Veteran
Posts: 6309
Joined: Tue Nov 06, 2012 5:42 pm
Contact:

Re: TechDraw and v0.21

Post by wandererfan »

edi wrote: Tue May 10, 2022 12:23 pm Do you have any explanation ?
No, it is a mystery to me. The svg item gets added to the scene, and it is added to the view as a child, but I can not make it display.
Post Reply