Design Principle: App/Gui Split

Here's the place for discussion related to coding in FreeCAD, C++ or Python. Design, interfaces and structures.
Forum rules
Be nice to others! Respect the FreeCAD code of conduct!
User avatar
wandererfan
Veteran
Posts: 6326
Joined: Tue Nov 06, 2012 5:42 pm
Contact:

Design Principle: App/Gui Split

Post by wandererfan »

Is there any documentation on our App/Gui split design principle? I've only found 1 relevant statement so far:

http://www.freecadweb.org/wiki/index.ph ... ature_list
FreeCAD also runs as a command line application, with low memory footprint. In command line mode, FreeCAD runs without its interface, but with all its geometry tools. It can be, for example, used as server to produce content for other applications.
Note that it says "with all its geometry tools", not all its FUNCTIONALITY.

Is this a reasonable summation of the App/Gui split principle?
1) App portion of module must run without Gui portion
2) App portion of module must not link against QtGui
3) App portion must load/save any Document containing module's Objects
4) All object create/modify/delete logic must be in App. (same as #3?)
5) It is permissible for an App to be of limited use without its Gui

For context, TechDraw relies heavily on QtGui to produce its drawings and our efforts to produce drawing on the App side without QtGui are moving slowly. So point 5 is a big deal for us!

Thanks,
wf
wmayer
Founder
Posts: 20324
Joined: Thu Feb 19, 2009 10:32 am
Contact:

Re: Design Principle: App/Gui Split

Post by wmayer »

Is this a reasonable summation of the App/Gui split principle?
Yes.
1) App portion of module must run without Gui portion
Yes. It's functionality might be limited but it must basically work.
2) App portion of module must not link against QtGui
In general yes. For more information see below.
3) App portion must load/save any Document containing module's Objects
It depends. Objects part of the Gui (e.g. view providers) of course cannot be loaded. They will be just ignored when reading a project.
But this isn't something you have to manage, the FreeCAD core system handles this already.
NOTE: if you have a project with Gui objects but load it with the command line interface and then re-save the document the view objects are lost.
4) All object create/modify/delete logic must be in App. (same as #3?)
Not necessarily. In FreeCAD it's everywhere this way that on App a boost signal is emitted (e.g. object creation, change, deletion, ...). The Gui part must then implement the slot functions and connect to these signals.

But again, this is already done in the core system and you have to do this only if you have special purposes.
NOTE: you have to use boost signals/slots. Qt signals/slots cannot be used because in the command line interface (i.e. only App is loaded) there is no running event loop.
5) It is permissible for an App to be of limited use without its Gui
Sure. Isn't it the same as in 1) ?
For context, TechDraw relies heavily on QtGui to produce its drawings and our efforts to produce drawing on the App side without QtGui are moving slowly. So point 5 is a big deal for us!
Ian Rees talked to me about this a few months ago and it's OK for me to link against QtGui in this case to use its capabilities. But you have to consider two points:

1) Make sure that App doesn't offer a GUI (dialogs or the like)
2) You have to be aware of that FreeCAD can be built on a pure server system. You can then either just skip your whole App module from being built or you can structure the code this way that the parts using QtGui are not built.
In this case it's OK to have App with limited functionality.
User avatar
wandererfan
Veteran
Posts: 6326
Joined: Tue Nov 06, 2012 5:42 pm
Contact:

Re: Design Principle: App/Gui Split

Post by wandererfan »

Ok, thanks, this helps a lot.
there is no running event loop.
Ian would have to tell you why, but this seems to be the latest hurdle.

wf
ian.rees
Posts: 696
Joined: Sun Jun 15, 2014 3:28 am
Contact:

Re: Design Principle: App/Gui Split

Post by ian.rees »

Sorry about the slow response - somehow didn't notice this thread until now (other relevant thread here).

The failing in my recent attempt was that I was trying to move all code required for making Drawings (including via the Python interface) in to the "App" of TechDraw, which created problems due to a hierarchy of QGraphicsItem children being spread across Gui and App (messy).

I'm now thinking it would be best to use an App/QGraphics/GUI split, so that in a sense we can still build a CLI only version that works (by building App and QGraphics) or a version without linking to Qt GUI (by only building App) that would still allow for nondestructively opening/saving files with Drawings. The QGraphics part would include code for GUI interaction (eg mouse event handlers), but not require user interaction as such.

Regarding the event loop - the rendering QGraphics scenes requires having a Qt event loop running, AFAICT this is an undocumented dependency (except in the Qt bug tracker). There's a possible fix at https://github.com/ianrrees/FreeCAD_tin ... 1bdd79a5a1 ; I was considering proposing a similar event loop in the CLI version of FreeCAD, if it's built with Qt available. -Ian-
wmayer
Founder
Posts: 20324
Joined: Thu Feb 19, 2009 10:32 am
Contact:

Re: Design Principle: App/Gui Split

Post by wmayer »

Two things you have to be aware of in

Code: Select all

void GIPageRenderer::renderToSvg(DrawPage *page, QString filename)
In this function you simply create an instance of QApplication without any checks if there is already one. It Qt application it's only allowed to have one Q(Core)Application to run. On any attempt to create a second one an assert is triggered and the application will crash.

1. The FreeCAD GUI is up, so there is already a QApplication instance running and you can use that.
2. FreeCAD might be loaded into another application without a GUI and have only an instance of QCoreApplication running. Also you are not allowed to create a QApplication in this case.

The easiest thing to test if a Q(Core)Application is running is to use QCoreApplication::instance(). Btw, as far as I understand this part of your code you don't even have to create a QApplication. All what you need there is an event loop and this you can directly do with QEventLoop. And the nice thing with it is that it's part of QtCore.
ian.rees
Posts: 696
Joined: Sun Jun 15, 2014 3:28 am
Contact:

Re: Design Principle: App/Gui Split

Post by ian.rees »

Can definitely do more checking to see whether there's a QApplication going - this was mainly just a prototype to see if the approach will work. It actually has to be a QApplication - even QCoreApplication is not enough. -Ian-
wmayer
Founder
Posts: 20324
Joined: Thu Feb 19, 2009 10:32 am
Contact:

Re: Design Principle: App/Gui Split

Post by wmayer »

actually has to be a QApplication - even QCoreApplication is not enough
But then as said you are in deep water because in command line version the TechDrawApp module could be loaded by an application with only QCoreApplication running. In this case you cannot also instantiate QApplication.

I would just avoid all these troubles by moving everything that needs QtGui to TechDrawGui and leave the rest at TechDrawApp.
ian.rees
Posts: 696
Joined: Sun Jun 15, 2014 3:28 am
Contact:

Re: Design Principle: App/Gui Split

Post by ian.rees »

Just to clarify - the situation you're imagining is a program starting a QCoreApplication, then importing the TechDraw module via Python? If so, I think it should be fairly easy to catch that, and an uncommon case.

Can certainly just leave all the QGraphics in Gui, but that means that TechDraw won't do anything useful without the FreeCAD GUI running. I think it would be nice to be able to render SVGs (or PDFs eventually) - there are already examples where people are scripting Drawing. -Ian-
wmayer
Founder
Posts: 20324
Joined: Thu Feb 19, 2009 10:32 am
Contact:

Re: Design Principle: App/Gui Split

Post by wmayer »

Just to clarify - the situation you're imagining is a program starting a QCoreApplication, then importing the TechDraw module via Python?
Yes, that's what I meant.
I think it would be nice to be able to render SVGs (or PDFs eventually) - there are already examples where people are scripting Drawing.
Unless the people don't run it on a pure server system then you can also script by loading the FreeCADGui module and then immediately hide the main window. In some cases (like off-screen rendering) that's the only feasible way to go.
uuykay
Posts: 13
Joined: Mon May 14, 2018 5:51 am

Re: Design Principle: App/Gui Split

Post by uuykay »

Would love to have a pure server side implementation to get the SVG exporting from TechDraw
Post Reply