Using Draft.make_text in external script

Need help, or want to share a macro? Post here!
Forum rules
Be nice to others! Respect the FreeCAD code of conduct!
Post Reply
sdementen
Posts: 7
Joined: Wed Jun 09, 2021 4:12 am

Using Draft.make_text in external script

Post by sdementen »

Hello,

I am using FreeCAD from an external script (windows 10 + python 3.8) to create a document and some objects in it.
I can create without issues an object of type App::Annotation.
However, if I want to create some text with Draf.make_text, I get an issue either when importing Draft after calling FreeCADGui.showMainWindow()

Code: Select all

22:52:17  During initialization the error "Failed to wrap widget" occurred in ..\AppData\Local\Programs\FreeCAD 0.19\Mod\Tux\InitGui.py
22:52:17  Please look into the log file for further information
22:55:17  Traceback (most recent call last):
22:55:17    File "../myproject/designer/bug_draftgui.py", line 61, in drawtextmake
22:55:17      app.exec_()
22:55:17    File "..\PycharmProjects\fmh\env38\Lib\site-packages\shiboken2\files.dir\shibokensupport\__feature__.py", line 142, in _import
22:55:17      return original_import(name, *args, **kwargs)
22:55:17    File "..\AppData\Local\Programs\FreeCAD 0.19\Mod\Draft\Draft.py", line 332, in <module>
22:55:17      from draftmake.make_facebinder import (make_facebinder,
22:55:17    File "..\PycharmProjects\fmh\env38\Lib\site-packages\shiboken2\files.dir\shibokensupport\__feature__.py", line 142, in _import
22:55:17      return original_import(name, *args, **kwargs)
22:55:17    File "..\AppData\Local\Programs\FreeCAD 0.19\Mod\Draft\draftmake\make_facebinder.py", line 36, in <module>
22:55:17      from draftviewproviders.view_facebinder import ViewProviderFacebinder
22:55:17    File "..\PycharmProjects\fmh\env38\Lib\site-packages\shiboken2\files.dir\shibokensupport\__feature__.py", line 142, in _import
22:55:17      return original_import(name, *args, **kwargs)
22:55:17    File "..\AppData\Local\Programs\FreeCAD 0.19\Mod\Draft\draftviewproviders\view_facebinder.py", line 33, in <module>
22:55:17      import DraftGui
22:55:17    File "..\PycharmProjects\fmh\env38\Lib\site-packages\shiboken2\files.dir\shibokensupport\__feature__.py", line 142, in _import
22:55:17      return original_import(name, *args, **kwargs)
22:55:17    File "..\AppData\Local\Programs\FreeCAD 0.19\Mod\Draft\DraftGui.py", line 2231, in <module>
22:55:17      FreeCADGui.draftToolBar = DraftToolBar()
22:55:17    File "..\AppData\Local\Programs\FreeCAD 0.19\Mod\Draft\DraftGui.py", line 211, in __init__
22:55:17      mw = FreeCADGui.getMainWindow()
22:55:17  RuntimeError: Failed to wrap widget
or another error if I have imported Draft before calling FreeCADGui.showMainWindow()

Code: Select all

22:57:16  ----------------
22:57:16  Text
22:57:16  string: ['Hello', 'FreeCAD']
22:57:16  placement: Vector (0.0, 0.0, 0.0)
22:57:16  Traceback (most recent call last):
22:57:16    File "../PycharmProjects/fmh/designer/bug_draftgui.py", line 53, in drawtextmake
22:57:16      obj = Draft.make_text(self.text_list, self.position)
22:57:16    File "..\AppData\Local\Programs\FreeCAD 0.19\Mod\Draft\draftmake\make_text.py", line 131, in make_text
22:57:16      ViewProviderText(new_obj.ViewObject)
22:57:16  NameError: name 'ViewProviderText' is not defined
The code I am using to test make_text is the following

Code: Select all

import os
import sys

freecad_path = os.environ["HOMEDRIVE"] + os.environ["HOMEPATH"] + "\\AppData\\Local\\Programs\\FreeCAD 0.19"
sys.path.extend(
    [
        freecad_path + "\\bin",
        freecad_path + "\\lib",
        freecad_path + "\\bin\\lib\\site-packages",  # for pivy
    ]
)

from PySide2 import QtWidgets, QtCore

import FreeCAD
import FreeCADGui
import Draft


class MainWindow(QtWidgets.QMainWindow):
    def __init__(self):
        super().__init__()
        filemenu = self.menuBar().addMenu("&File")
        drawtextannot = QtWidgets.QAction("&Draw Text with Annotation", self)
        drawtextmake = QtWidgets.QAction("&Draw Text with make_text", self)
        filemenu.addAction(drawtextannot)
        filemenu.addAction(drawtextmake)
        self.connect(drawtextannot, QtCore.SIGNAL("triggered()"), self.drawtextannot)
        self.connect(drawtextmake, QtCore.SIGNAL("triggered()"), self.drawtextmake)

        self.position = FreeCAD.Vector(0., 0., 0.)
        self.text_list = ["Hello", "FreeCAD"]

    def showEvent(self, event):
        FreeCADGui.showMainWindow()
        self.doc = FreeCAD.newDocument("Unnamed")

    def drawtextannot(self):
        # this adds some text
        obj = self.doc.addObject("App::Annotation", "Annotation")
        obj.LabelText = self.text_list

        obj.Position = self.position

        if FreeCAD.GuiUp:
            obj.ViewObject.DisplayMode = "World"
            obj.ViewObject.FontSize = 75
            obj.ViewObject.TextColor = (0.0, 0.0, 0.0)

        view = FreeCADGui.activeDocument().activeView()
        view.fitAll()

    def drawtextmake(self):
        obj = Draft.make_text(self.text_list, self.position)
        obj.ViewObject.FontSize = "200 mm"


app = QtWidgets.QApplication(sys.argv)
mw = MainWindow()
mw.show()

app.exec_()
When I choose the menu option File -> Draw Text with Annotation, I get the Annotation appearing in FreeCAD.
If I run File -> Draw Text with make_text, I get the exceptions above (depending where I put the "import Draft" line.

Would you know a workaround to be able to use make_text from such external script ?
I am also interested by any tips&tricks for using efficiently FreeCAD from an external script.

thank you!
User avatar
onekk
Veteran
Posts: 6197
Joined: Sat Jan 17, 2015 7:48 am
Contact:

Re: Using Draft.make_text in external script

Post by onekk »

Simply the WB wants to have the Gui Up, it is not strange, as Draft is mainly a Gui wrapper to create Part objects.

I could guess that you wnat to use "FreeCAD as a library", i.e calling it from not an "external script" that could be simply a script loaded in the FreeCAD editor but importing FreeCAD as a Library.

The problem has been discussed in another thread if I remember well, there is a way to avoid this thing, maybe importing it in a different way.

Sorry to not be of more help, as I have no time now to do an extensive search on the forum, and send you the link to the relevant thread.


Regards

Carlo D.
GitHub page: https://github.com/onekk/freecad-doc.
- In deep articles on FreeCAD.
- Learning how to model with scripting.
- Various other stuffs.

Blog: https://okkmkblog.wordpress.com/
sdementen
Posts: 7
Joined: Wed Jun 09, 2021 4:12 am

Re: Using Draft.make_text in external script

Post by sdementen »

Indeed, it is about using FreeCAD as a library (when using the GUI, it is even close to a component model like UNO for OpenOffice or COM on windows).

I will look again in the forums if I find a reference to this issue. I already had a look but without much success. If you can find the posts you had in mind, I would be very grateful!
User avatar
onekk
Veteran
Posts: 6197
Joined: Sat Jan 17, 2015 7:48 am
Contact:

Re: Using Draft.make_text in external script

Post by onekk »

maybe you could try this advices,

https://wiki.freecadweb.org/Debugging

https://pythoncvc.net/?p=869

These are not strictly related, but show some tricks to use FreeCAD in advanced way, maybe some of them are useful.

Hope it helps

Carlo D.
GitHub page: https://github.com/onekk/freecad-doc.
- In deep articles on FreeCAD.
- Learning how to model with scripting.
- Various other stuffs.

Blog: https://okkmkblog.wordpress.com/
Post Reply