Seite 1 von 1
Programm für Console und X11
Verfasst: 7. Februar 2010 11:24
von fthieme
Hallo!
Ich hab ein kleines Programm geschrieben, welches entweder im Batch Mode oder aber mit graphischem Interface bedienbar ist. Basis ist QCoreApplication und in einem Zweig gibt es dann ein Widget, im anderen nicht.
Wenn ich das Programm nun auf der Console im Batch Mode starten will, will es sich trotzdem zum X Server verbinden. Ich vermute wegen linken gegen -lQtGui.
Wie kann ich es dazu bringen einfach zu laufen, wenn es kein X braucht?
Verfasst: 7. Februar 2010 12:09
von Christian81
Wie unterscheidest du zwischen console und x11? Wie sieht deine main.cpp aus?
Verfasst: 7. Februar 2010 12:17
von fthieme
Ich gebe einen Kommandozeilenschalter mit, den ich "-ni" getauft habe. Ausschnitsweise sieht die so aus:
Code: Alles auswählen
int main(int argc, char *argv[])
{
QApplication app(argc, argv);
QStringList arguments = QCoreApplication::arguments();
programName = arguments.at(0);
if (arguments.contains("-ni")) {
// non interactive
interactive = false;
arguments.removeAll("-ni");
} else {
interactive = true;
}
if (interactive) {
BumbleBeeMain bbmain(world);
bbmain.show();
returnValue = app.exec();
} else {
std::cout << "Running non-interactive mode on '" << problemFileName.toStdString() << "', "
<< iterations << " iterations." << std::endl;
world->doGenerations(iterations);
}
delete world;
return returnValue;
}
BumbleBeeMain ist dabei von QMainWindow abgeleitet.
Verfasst: 7. Februar 2010 12:31
von Christian81
QApplication braucht nun aber eine X11-Verbindung. Im Konsolen-Modus sollte man deshalb wohl eine QCoreApplication verwenden.
Verfasst: 7. Februar 2010 12:34
von fthieme
Argh - ich hab die zweite Zeile gelesen und gesehen QCoreApplicaton - alles klar...
Wie mache ich das nun also mit den Argumenten? Oder anders gefragt, wie komme ich von der QCoreApplication zu der QApplication?
Verfasst: 7. Februar 2010 12:39
von Christian81
Du musst die Argumente eben 'von Hand' auswerten und je nachdem QApplication oder QCoreApplication erzeugen.
Verfasst: 7. Februar 2010 12:40
von fthieme
mmh, doof, aber wenns nicht anders geht...
Danke
Edith: Geht doch anders. Ich erstelle jetzt ein QCoreApplication Objekt und ersetze das bei Bedarf durch ein QApplication Objekt.
Code: Alles auswählen
int main(int argc, char *argv[])
{
QCoreApplication *app;
app = new QCoreApplication(argc, argv);
QStringList arguments = QCoreApplication::arguments();
programName = arguments.at(0);
if (arguments.contains("-i")) {
// non interactive
interactive = true;
delete app;
app = new QApplication(argc, argv); // XXX Achtung unsauber, siehe Kommentar von franzf
arguments = QCoreApplication::arguments();
arguments.removeAll("-i");
} else {
interactive = false;
}
if (interactive) {
BumbleBeeMain bbmain(world);
bbmain.show();
returnValue = app->exec();
} else {
std::cout << "Running non-interactive mode on '" << problemFileName.toStdString() << "', "
<< iterations << " iterations." << std::endl;
world->doGenerations(iterations);
}
delete world;
delete app;
return returnValue;
}
Falls es mal jemand braucht

Verfasst: 7. Februar 2010 14:53
von Christian81
Bitte Q(Core)Application nicht mit new erstellen bzw delete löschen.
Probiere bitte einfach mal
Code: Alles auswählen
nt main(int argc, char *argv[])
{
QCoreApplication app_core(argc, argv);
QStringList arguments = QCoreApplication::arguments();
programName = arguments.at(0);
if (arguments.contains("-i")) {
QApplication app(argc, argv);
aus.
ich weiß nämlich nicht ob Qt das gut findet wenn du das QCoreApplication-Singleton erstens mit new erzugst und dann auch noch wieder löschst.
Aber gut zu wissen dass man nach einer QCoreApplication auch QApplication einfach instanziieren kann wenn man X braucht.
Verfasst: 7. Februar 2010 15:01
von franzf
Aber ne schöne Lösung ist es nicht...
Doku zu QCoreApplication::arguments():
Calling this function is slow - you should store the result in a variable when parsing the command line.
Du parst 2x arguments!
Ansonsten: was spricht dagegen, den Nutzer zu zwingen als ersten Parameter ein "-i" zu übergeben?
Dann wird aus deinem ganzen Hokuspokus ein:
Code: Alles auswählen
bool interactive = strcmp(argv[1], "-i") ? false : true;
Verfasst: 7. Februar 2010 15:35
von fthieme
Christian81 hat geschrieben:Bitte Q(Core)Application nicht mit new erstellen bzw delete löschen.
Probiere bitte einfach mal
Code: Alles auswählen
nt main(int argc, char *argv[])
{
QCoreApplication app_core(argc, argv);
QStringList arguments = QCoreApplication::arguments();
programName = arguments.at(0);
if (arguments.contains("-i")) {
QApplication app(argc, argv);
Wo steht, dass man diese Objekte nicht auch mit new und delete behandeln darf? Verzeih meine Unkenntnis was tiefere Programmabläufe anbelangt, aber bisher dachte ich, dass ein
dasselbe tut wie ein
. Nur dass das eine beim Beginn der Funktion passiert und das andere erst bei new.
ich weiß nämlich nicht ob Qt das gut findet wenn du das QCoreApplication-Singleton erstens mit new erzugst und dann auch noch wieder löschst.
Ob sie es gut finden weiß ich nicht, aber es geht
Zumindest hier und bei mir...
franzf hat geschrieben:Ansonsten: was spricht dagegen, den Nutzer zu zwingen als ersten Parameter ein "-i" zu übergeben?
Enfach, dass ich das nicht leiden kann. Ich meine nichts gegen Reihenfolgen von Parametern, aber "-" oder "--" Parameter sollten IMHO überall erlaubt sein...[/code]
Verfasst: 7. Februar 2010 15:58
von franzf
fthieme hat geschrieben:Ich weiß nämlich nicht ob Qt das gut findet wenn du das QCoreApplication-Singleton erstens mit new erzugst und dann auch noch wieder löschst.
Ob sie es gut finden weiß ich nicht, aber es geht

Allein der nicht virtuelle Destruktor von QCoreApplication sollte Argument genug sein, ein QApplication-Objekt nicht über einen QCoreApplication-Basiszeiger zu verwalten! Das kann am Ende richtig Aua geben...
Wenn du beide Anforderungen
1) CmdLineArg-Parsing
2) aus 1) abgeleitet mit oder ohne Gui
unter einen Hut bringen willst, musst du app Erstellen und CmdLineArg-Parsing trennen.
Nimm
Boost.Program_options, ist deutlich umfangreicher als QCoreApplication::arguments() und für deinen Anwebdungsfall fehlerunanfälliger.
Außerdem gibt es gleich ein umfangreich dokumentierendes "myapp --help" mit.
Verfasst: 7. Februar 2010 16:17
von fthieme
Danke für den Hinweis. Ich schaus mir mal an. Hab bisher noch nicht mit boost gearbeitet...