FreeCAD / FreeCAD_Conda

conda recipes for freecad and dependencies of freecad
GNU Lesser General Public License v2.1
42 stars 17 forks source link

FreeCAD python binding crashes #15

Closed gnthibault closed 6 years ago

gnthibault commented 6 years ago

Dear all,

I tried to port one of the code from this page: https://www.freecadweb.org/wiki/Embedding_FreeCADGui from PyQt4 to PyQt5 (result file attached).

Unfortunately, I got a segmentation fault whenever I try to use call a FreeCAD python binding.

Are you experiencing the same with this code on conda environment ?

#!/usr/bin/env python

import os
import sys

from PyQt5 import QtCore, QtGui
from PyQt5.QtWidgets import QMainWindow, QAction, QApplication, QMdiArea

from pivy.coin import SoInput, SoDB
from pivy.quarter import QuarterWidget

import os, sys
sys.path.append(os.path.join(os.environ["CONDA_PREFIX"], "lib"))
import FreeCADGui

class MdiQuarterWidget(QuarterWidget):
    def __init__(self, parent, sharewidget):
        QuarterWidget.__init__(self, parent=parent, sharewidget=sharewidget)

    def minimumSizeHint(self):
        return QtCore.QSize(640, 480)

class MdiMainWindow(QMainWindow):
    def __init__(self, qApp):
        QMainWindow.__init__(self)
        self._firstwidget = None
        self._mdiArea = QMdiArea()
        self.setCentralWidget(self._mdiArea)
        self.setAcceptDrops(True)
        self.setWindowTitle("Pivy Quarter MDI example")

        filemenu = self.menuBar().addMenu("&File")
        windowmenu = self.menuBar().addMenu("&Windows")

        fileopenaction = QAction("&Create Box", self)
        fileexitaction = QAction("E&xit", self)
        tileaction = QAction("Tile", self)
        cascadeaction = QAction("Cascade", self)

        filemenu.addAction(fileopenaction)
        filemenu.addAction(fileexitaction)
        windowmenu.addAction(tileaction)
        windowmenu.addAction(cascadeaction)

        fileopenaction.triggered.connect( self.createBoxInFreeCAD)
        fileexitaction.triggered.connect(QApplication.closeAllWindows)
        tileaction.triggered.connect(self._mdiArea.tileSubWindows)
        cascadeaction.triggered.connect(self._mdiArea.cascadeSubWindows)

        windowmapper = QtCore.QSignalMapper(self)
        windowmapper.mapped.connect(self._mdiArea.setActiveSubWindow)
        self.dirname = os.curdir       

    def closeEvent(self, event):
        self._mdiArea.closeAllWindows()

    def createBoxInFreeCAD(self):
        d=FreeCAD.newDocument()
        o=d.addObject("Part::Box")
        d.recompute()
        s=FreeCADGui.subgraphFromObject(o)
        child = self.createMdiChild()
        child.show()
        child.setSceneGraph(s)

    def createMdiChild(self):
        widget = MdiQuarterWidget(None, self._firstwidget)
        self._mdiArea.addWindow(widget)
        if not self._firstwidget:
            self._firstwidget = widget
        return widget

def main():
    app = QApplication(sys.argv)
    FreeCADGui.setupWithoutGUI()        
    mdi = MdiMainWindow(app)   
    mdi.show()
    sys.exit(app.exec_())

if __name__ == '__main__':
    main()

Thank you in advance for your help

looooo commented 6 years ago

please use PySide2 instead of PyQt5. Mixing PyQt5 and PySide2 is not a good idea.

looooo commented 6 years ago

I tried it and get:

AttributeError: 'PySide2.QtWidgets.QMdiArea' object has no attribute 'addWindow'
Traceback (most recent call last):
  File "test_fc_env.py", line 57, in closeEvent
    self._mdiArea.closeAllWindows()
AttributeError: 'PySide2.QtWidgets.QMdiArea' object has no attribute 'closeAllWindows'

this are some qt5 changes: QMdiArea.addWindow -> QMdiArea.addSubWindow QMdiArea.closeAllWindows -> QMdiArea.closeAllSubWindows

gnthibault commented 6 years ago

Now everything works like a charm, I can now really try to learn of this wonderful software really works. Many thanks for your help.