PDA

View Full Version : Launching Multiple QApplication within a DLL



CodeSlapper
15th October 2017, 23:57
I am trying to create an object which creates its GUI internally, and cleans itself up.

I have a call to quit() as well within lets me close the gui out if I want to force a close or I can just sit on .exec call until the main window is closed.

FooObj.h


class FooObj
{
public:
FooObj(FooObj *obj);
~FooObj();
private:
GUIApp *guiApp;
FooObj *m_fooObj;
}
FooObj.c


FooObj::FooObj()
{
guiApp = new GUIApp(this);
}

FooObj::~FooObj()
{
delete guiApp;
}
GUIApp.h


class GUIApp
{
public:
GUIApp(FooObj *obj);
~GUIApp();

private:
std::thread m_appThread;
void m_RunApp();
}
GUIApp.c


GUIApp::GUIApp(obj)
{
m_fooObj = obj;
m_appThread = std::thread ([this] {m_RunApp();});
}

GUIApp::~GUIApp()
{
if(m_appThread.joinable())
m_appThread.join();
}

void GUIApp::m_RunApp()
{
int argc = 1;
auto a = new QApplication(argc, NULL);
auto win = new FooObjGUI(m_fooObj);
win->show();
a->exec();
return;
}
In GUIApp, there is a call to FooObjGUI which uses FooObj to a gui setup to handle all the data I want to display and what actions I expose to the user.

My intention is to have the user of this code not have to worry about qt and to have it clean itself up.

This code works fine in a dll or exe when I create a single FooObj. I cannot create a second FooObj because I cannot create a second QApplication. I have tried several ideas starting the a->exec() in a separate thread, but the events are not handled and the gui sits idle.

Is there a way to call QApplication across multiple threads within a single dll? Is there a workaround to have both FooObj use the same QApplication and not block the execution of the dll? The only workaround I have for myself at the moment is use 2 copies of the dll, but that is not a good longterm solution.

high_flyer
16th October 2017, 00:42
s there a way to call QApplication across multiple threads within a single dll?
No, and it has to do with the event loop, QApplication is designed as a singleton.

What you can do is spawn separate processes using QProcess.
You wont have a direct access to their events (as you mentioned you need) but you can overcome it the usual way for this kind of a scenario by using an IPC mechanism of your choice.
This will involve code that inspects the events and dispatches them (or rather, data about them) over the IPC.

Or, you could go about implementing your own "application" object building it around a QEventLoop - not something for beginners.

However, reading your post I am not sure you actually need multiple QApplications, what you seem to need is merely "multiple UI's."
I am putting quotes because you only really have one UI per QApplication - which can be made of many views and windows etc.
You could have threads each doing his thing, and talking to a different window or UI - and all these threads can share the even processing of your QApplication, each thread can be killed or spawned.
When the last thread exists, you can close your QApplication too.
To be clear:
your threads will drive the business logic, but they will be talking to a UI living the in the QApplication gui thread.

None of the above options are trivial, but the last one with threads seems to me the most sensible, and probably the most practical to implement.

CodeSlapper
16th October 2017, 20:52
Thanks for the input high_flyer.

I get what you are saying, and I have tried to implement it to some extent, but ran into issues.

Options I see.
1. Can I use a Qthread.exec() to run the guis instead of QApplication?
2. Can I use a common thread to create the windows and qapplication for all the classes?
3. Can I make my own processevents() loop?
4. Can I use QEventLoop?

Are there any examples of doing this out there?

high_flyer
17th October 2017, 11:52
1. Can I use a Qthread.exec() to run the guis instead of QApplication?
No, the UI has to live in the QApplication UI main thread (the usual case, as I said, you could implement your own QApplication but do you really want/need to?)
You could have your thread instruct creation of UI's in the main thread however.


2. Can I use a common thread to create the windows and qapplication for all the classes?
You already have that - the main UI thread.



3. Can I make my own processevents() loop?
4. Can I use QEventLoop?
Yes, by using QEventLoop.


Are there any examples of doing this out there?
I don't know (maybe someone else here does).
I would look in QDialog for example, (there are some other classes which have their own event loop as well) and try to get the right way of using it from there.
A short google search provided this which I think might be interesting as well:
https://www.qtdeveloperdays.com/2013/sites/default/files/presentation_pdf/Qt_Event_Loop.pdf