Embedding a view to another (QT) application?

Have some feature requests, feedback, cool stuff to share, or want to know where FreeCAD is going? This is the place.
Forum rules
Be nice to others! Read the FreeCAD code of conduct!
jukkaaho
Posts: 14
Joined: Thu Dec 24, 2009 5:42 am

Embedding a view to another (QT) application?

Postby jukkaaho » Fri Dec 25, 2009 6:15 pm

Hello,

I've been playing with FreeCAD for a couple of days now when i finally got it working, and indeed it looks very promising and interesting project. Now i'm wondering what are the possibilities to embed a model view and other GUI features to another QT application. It would be a superior feature to create little specific applications with all the functionality FreeCAD is providing, and to enchance functionality even more with numpy/scipy/matplotlib/etc. I guess it's possible to use FreeCAD's non-gui features throught Pivy with Open Inventor scene syntax to create a canvas to QT app with model view and some little controllers, but that doesn't feel to be very practical solution. Is it possible to create QWidget with a canvas and embed a model view to it somehow..? Basicly it should be something like:

Code: Select all

class MyApp(QWidget):
    def __init__(self, parent=None):
        super(Form, self).__init__(parent)
        self.lineedit = QLineEdit("foo")
	self.myfreecadcanvas = FreeCADGui.ActiveDocument().View # Here the magic happens
        layout = QVBoxLayout()
        layout.addWidget(self.lineedit)
        layout.addWidget(self.myfreecadcanvas)
        self.setLayout(layout)
	...
If you have any ideas where to start looking (already looked the couple QT examples from wiki), I'd like to hear them.

Jukka Aho
User avatar
yorik
Site Admin
Posts: 12035
Joined: Tue Feb 17, 2009 9:16 pm
Location: Brussels, Belgium
Contact:

Re: Embedding a view to another (QT) application?

Postby yorik » Fri Dec 25, 2009 6:23 pm

I don't think that this is possible already, but I think Werner has been experimenting with importing the FreeCADGui from outside FreeCAD... I think you can already, but the whole interface at once, not only a part of it like the 3D view. But, maybe you might be able to import it all and then hide the pieces you don't need?
jukkaaho
Posts: 14
Joined: Thu Dec 24, 2009 5:42 am

Re: Embedding a view to another (QT) application?

Postby jukkaaho » Fri Dec 25, 2009 6:57 pm

I think that there must be some kind of layer to 3d view that inherits from QApplication so that Qt event handling etc. works. I'm not a Qt professional and just started experimenting it couple weeks ago, but I thought that because FreeCAD's GUI is already made with Qt, that kind of layer is already present or it's quite simple to develop.
User avatar
yorik
Site Admin
Posts: 12035
Joined: Tue Feb 17, 2009 9:16 pm
Location: Brussels, Belgium
Contact:

Re: Embedding a view to another (QT) application?

Postby yorik » Fri Dec 25, 2009 10:51 pm

No doubt Werner will give us more info about that soon...
jukkaaho
Posts: 14
Joined: Thu Dec 24, 2009 5:42 am

Re: Embedding a view to another (QT) application?

Postby jukkaaho » Sat Dec 26, 2009 12:40 am

Meanwhile i did do some studying. I succesfully got Coin scenegraph object in terminal with normal Python interpreter. It wasn't even hard. FreeCAD rocks!

Code: Select all

from FreeCAD import Part
import sys
import FreeCAD
import FreeCADGui
from PyQt4 import QtGui,QtCore

qApp = QtGui.QApplication(sys.argv) # QApplication object
FreeCADGui.showMainWindow() # Optional step? BTW, didn't work on iPython.
nd=FreeCAD.newDocument('title') # Document object
qad=FreeCADGui.activeDocument() # GUI Document object
aw=qad.activeView() # View3dInventor object

# Let's make something
box = nd.addObject("Part::Box","Box1") # Part object
box.Height=10
box.Width=10
box1.Length=10
aw.viewAxometrix() # We're already using View3dInventor object to change view.

sg = aw.getSceneGraph() # pivy.coin.SoSelection; proxy of <Swig Object of type 'SoSelection *'     \o/
Now i need some.. Hmm. Glue! I guess i need to represent that pivy.coin.SoSelection with some Qt layer now. I have no idea how that should be done.

Jukka
User avatar
jriegel
Site Admin
Posts: 3369
Joined: Sun Feb 15, 2009 5:29 pm
Location: Ulm, Germany
Contact:

Re: Embedding a view to another (QT) application?

Postby jriegel » Sat Dec 26, 2009 9:02 am

Our layer between the Coin and Qt is SoQt. This makes all the event tuneling.
Stop whining - start coding!
User avatar
jriegel
Site Admin
Posts: 3369
Joined: Sun Feb 15, 2009 5:29 pm
Location: Ulm, Germany
Contact:

Re: Embedding a view to another (QT) application?

Postby jriegel » Sat Dec 26, 2009 9:21 am

Ahh,
now I read the whole thread...

There fore another comment.

Our 3D Viewer is a heavy improved/changed SoQtViewer.
Our Viewer is tidily coupled to a lot of services we have in the Gui portion of FreeCAD, as
the Selection framework, the ViewProvider framwork and many more. Its at least hard to get it out of
FreeCAD and working.

The design of FreeCad is the other way around. Your application can be a FreeCAd module and has
the ability to brand FreeCAD:

https://sourceforge.net/apps/mediawiki/ ... e=Branding

Thats much easier then ripping the needed parts out of FreeCAD. And you Application can look
completely different.

Cheers
Jürgen
Stop whining - start coding!
wmayer
Site Admin
Posts: 16465
Joined: Thu Feb 19, 2009 10:32 am

Re: Embedding a view to another (QT) application?

Postby wmayer » Sat Dec 26, 2009 11:27 am

Hi,

as Jürgen already said it's usually done this way that the other application, i.e. its user interface, ... is embedded into FreeCAD. Nevertheless, it's also possible to embed FreeCAD into your application. Basically, you can

* only use the FreeCAD App part, i.e. no GUI stuff and wire the signals which get emitted when a document is created or objects inside a document get created/deleted/modified to your own slot function. There you have to implement all the GUI stuff on your own, like creation of 3d views, creating the Inventor objects for the 3d scene, ...

* if your application has embedded Python you can use the FreeCADGui Python module. Just import FreeCADGui and call the showMainWindow() function. This approach, however, requires that the GUI toolkit can interact with Qt's event loop. Using Qt in the same version provides this of course but also all X11 toolkits that use Glib and on Windows all toolkits that is based somehow on the Win32 API, such as MFC, wxWidgets, ... Unfortunately, this loads the GUI of FreeCAD as a whole. I think using only the parts which you're interested in is possible but it's quite a bit of hack. For example when creating a 3d view you can search for the widget and reparent it to your own main widget. FreeCAD's actual main widget can be set hidden.

Werner
jukkaaho
Posts: 14
Joined: Thu Dec 24, 2009 5:42 am

Re: Embedding a view to another (QT) application?

Postby jukkaaho » Sat Dec 26, 2009 4:24 pm

Hi Werner

I did try to find that 3d view widget, but haven't found anything relevant yet that could be used in PyQt. And yes, my Qt app will be written in Python with PyQt. I'm not very interested about modifying FreeCADGui source code. Does the Python methods to get 3d view QWidget or relevant QObject even exist?

Maybe one solution is to use that View3dInventor object to construct my own QWidget. I guess in that case i would get a full access to every method needed to create QWidget? Actually, getting callbacks from FreeCADGui isn't needed at all, because i can and i will use controllers and events provided by PyQt for example to control camera positions etc.. Anyway, i need something to represent that that View3dInventor data with PyQt, so SoQtViewer is out of question. Any ideas? I found IVuPy ( http://ivupy.sourceforge.net/ ) that could be useful at base of project. But it looks it's not maintenanced anymore.
User avatar
jriegel
Site Admin
Posts: 3369
Joined: Sun Feb 15, 2009 5:29 pm
Location: Ulm, Germany
Contact:

Re: Embedding a view to another (QT) application?

Postby jriegel » Sat Dec 26, 2009 9:11 pm

That case is at least complicated! Its basically the difference between a event loop driven GUI and an interpreter which run a script!
Wenn the GUI is running the control is in the event loop.

May be whats better for you is to run a ExaminerViewer in Pivy and load the exported data form FreeCAD.
Stop whining - start coding!