QCommandLineParser to select gui or non-gui mode



  • If I want to use QCommandLineParser, I must first create an application object. But supposing I don't want to run in GUI mode, it's best for me to make a QCoreApplication object. E.g.:

    int main(int argc, char* argv[]){
      QCoreApplication app(argc, argv);
    
      QCommandLineParser parser;
      QCommandLineOption noGuiMode( "z", "run without gui");
      parser.addOption(noGuiMode);
      parser.process(app);
      ...
    }
    

    But if I continue with

      ...
      if(!parser.isSet(noGuiMode)){
        QApplication guiApp(argc, argv);
        ... // initialization stuff or whatever, mainWindow->show();
        return guiApp.exec();
      }
      return app.exec();
    }
    

    Then the program will complain that I must have a QApplication started before I can create widgets.

    The example I find in the documentation isn't helpful either. That example uses a separate "create application" function that parses the command line options on its own. While this would work, it seems to be a duplicate effort, considering that a QCommandLineParser exists separately.

    I've also tried just using the parse(QStringList) option, but even this requires an application object is already created.

    I've tried using scoped pointers and swapping in a QApplication, and other approaches, but I just can't seem to resolve this without duplicating the function of QCommandLineParser to first parse if non-gui mode is requested, and then create an application to then pass to QCommandLineParser to parse the remaining options.



  • Hi,

    in my project we use this techinque

    QSharedPointer<QCoreApplication> app;
    if(commandLine) {
        app.reset(new QCoreApplication(argc, argv));
    } else {
        app.reset(new QApplication(argc, argv));
    }
    

    where commandLine is initialized parsing the command line arguments



  • You could also copy the contents of argv[] into a QStringList and then use QCommandLineParser before you create any Q*Application with:
    void QCommandLineParser::​process(const QStringList & arguments)



  • @Wieland said:

    You could also copy the contents of argv[] into a QStringList and then use QCommandLineParser before you create any Q*Application with:
    void QCommandLineParser::​process(const QStringList & arguments)

    We use QCommandLineParser to parse the arguments



  • @Wieland
    This works... to a degree. 1, it still feels kludgey to construct a stringlist of arguments to parse.
    Second, I can't add in help or version options in this way. I have to instantiate the application to get these, I think?



  • @mcosta
    I think @shavera's biggest concern is, like she said:

    If I want to use QCommandLineParser, I must first create an application object.

    Her assumption is wrong as there isn't only void QCommandLineParser::​process(const QCoreApplication & app) but also void QCommandLineParser::​process(const QStringList & arguments).

    @shavera said

    This works... to a degree. 1, it still feels kludgey to construct a stringlist of arguments to parse.
    Second, I can't add in help or version options in this way. I have to instantiate the application to get these, I think?

    This is all true. Maybe you should file a bug and request some improvement of QCommandLineParser. But honestly I don't think this would be implemented in the near future.



  • @mcosta I don't precisely understand what you mean in either comment. Using QCommandLineParser seems to either require a Q*Application already created, or to pass in a self-generated list of arguments to the parser, which one could then use to decide which type of application to generate. (but at the loss of some other functionality of QCommandLineParser, it seems to me)



  • @Wieland

    Yeah I was initially thinking along the lines of a bug report/suggested feature, but I wanted to make sure I wasn't overlooking some obvious solution. For instance, my initial attempt, I just used QCoreApplication::arguments() to generate the stringlist, forgetting that isn't a static function, which generated an error.



  • @shavera Looks like there is no nice solution by now. I've actually seen multiple people complaining about this. :-(



  • Hi,

    the complete code is this

        CommandFactory factory;
        bool foundParams = factory.commandLineParamsArePresent(argc, argv, error);
        
        QSharedPointer<QCoreApplication> app;
        if(foundParams) {
            if(!error.isEmpty()) {
                qDebug() << error;
                return 1;
            }
            app = QSharedPointer<QCoreApplication>(new QCoreApplication(argc, argv));
        } else {
            app = QSharedPointer<QCoreApplication>(new CWinAdminApp(argc, argv));
        }
    

    The CommandLineFactory::commandLineParamsArePresent() use a QCommandLineParser to parse the argv[] contents before creating any Q*Application instance.



  • @mcosta I can see how that could work, but it runs into the initial kludge problem, that you have to parse for whether a command line option is present (or more specifically, that a specific command line option is present in the case of multiple options), which you then use to construct the application (and potentially pass this application object through the CommandLineOption stuff itself)



  • @shavera I understand what do you mean but honestly I don't think such kind of feature could be useful; you need anyway to do something manually to run in GUI or non-GUI mode.



Looks like your connection to Qt Forum was lost, please wait while we try to reconnect.