Console application on the side
Hello there,
I developed a Qt application with gui and everything for the running and visualization of physics-related experiments. Sometimes I have to start a long running process that can take several days to try out many things in the background and in the end reports with the found results. I am looking for a way to launch this background process without a gui just by invoking a command in the shell. The process is in an Object that derives from QThread and can run on its own. As far as I see it, it is really just a question of building the project right. Does it makes sense to have two project configurations, where one would build a gui application and the other just a console application? If this is the right way, would I have two different .pro files then? Would I need two .cpp classes that have a main() function tailored to my needs?
Thanks,
Cruz
Re: Console application on the side
Maybe a command line parameter that will say whether to run the GUI or not?
Re: Console application on the side
Yes, true, much easier that way. Thanks.
Re: Console application on the side
It's about as simple as not calling show() on the main window instance when the "run in the background" command line parameter is present. You could also simply make a copy of your executable, rename it, and examine the name of the executable at run time to decide how to run it up. QCoreApplication::applicationName()
Re: Console application on the side
I gave this a go, but it does not work as expected yet. It does when I start my program locally, but when I try to start it remotely over ssh, I receive the error message:
Quote:
qt.qpa.screen: QXcbConnection: Could not connect to display
Could not connect to any X display.
I was able to find hints that I should forward my X session, but this does not come easy to me, because I have to first ssh into a proxy server and then from there I can ssh into a protected machine. I would like to avoid any X and windows and widgets altogether. My main function looks like this:
Code:
#include "GuiSimulation.h"
#include "Experimenter.h"
#include <QApplication>
int main(int argc, char *argv[])
{
GuiSimulation w; // The gui.
Experimenter e; // The background thread.
if (argc > 1)
{
e.start();
}
else
{
w.show();
}
return a.exec();
}
Even if I minimize this to
Code:
#include <QApplication>
int main(int argc, char *argv[])
{
return a.exec();
}
I receive the error message above. Any help is much appreciated.
Re: Console application on the side
You should use QCoreApplication in command line mode.
Re: Console application on the side
Indeed! The final result:
Code:
int main(int argc, char *argv[])
{
if (argc > 1) // Command line mode.
{
Experimenter e;
e.start();
return a.exec();
}
else // GUI mode
{
GuiSimulation w;
w.show();
return a.exec();
}
}
Re: Console application on the side
One more question though. The event loop I started with a.exec() keeps running forever and eventually I have to kill it by hand. Normally, I would connect the finished() signal of QThread to a closed() or exit() slot or something, but here in the main function I can't use connect() right? How do I go about this?
Re: Console application on the side
Quote:
but here in the main function I can't use connect() right?
Why not? There is a static version of QObject::connect(), and QCoreApplication is derived from QObject, so you could also use a.connect().
Re: Console application on the side
Yes! This works like a charm. Thanks.
Code:
int main(int argc, char *argv[])
{
if (argc > 1) // Command line mode.
{
Experimenter e;
e.start();
a.connect(&e, SIGNAL(finished()), &a, SLOT(quit()));
return a.exec();
}
else // GUI mode
{
GuiSimulation w;
w.show();
return a.exec();
}
}
Re: Console application on the side
I think I would call connect() before starting the Experimenter thread. If the thread finishes before the connection is made, you'll get a hung executable.
Re: Console application on the side
Yes, you are right. This thing here takes several days to run so it shouldn't be an issue, but why would we stop short of perfection...
Code:
int main(int argc, char *argv[])
{
if (argc > 1) // Command line mode.
{
Experimenter e;
a.connect(&e, SIGNAL(finished()), &a, SLOT(quit()));
e.start();
return a.exec();
}
else // GUI mode
{
GuiSimulation w;
w.show();
return a.exec();
}
}
Re: Console application on the side
Quote:
but why would we stop short of perfection...
Exactly. Someone else might read this thread and copy your next to last version, then wonder why it didn't work because their process is very quick.