Skip to content
  • Categories
  • Recent
  • Tags
  • Popular
  • Users
  • Groups
  • Search
  • Get Qt Extensions
  • Unsolved
Collapse
Brand Logo
  1. Home
  2. Qt Development
  3. General and Desktop
  4. Have troubles with QCommandLineParser
Qt 6.11 is out! See what's new in the release blog

Have troubles with QCommandLineParser

Scheduled Pinned Locked Moved Solved General and Desktop
4 Posts 2 Posters 1.6k Views 1 Watching
  • Oldest to Newest
  • Newest to Oldest
  • Most Votes
Reply
  • Reply as topic
Log in to reply
This topic has been deleted. Only users with topic management privileges can see it.
  • T Offline
    T Offline
    tubbadu
    wrote on last edited by
    #1

    Hello! I'm having troubles trying to make QCommandLineParser work in my application:
    for some reasons I don't understand, some arguments are simply ignored by the parser, and it always returns false at isSet. Here's the code:

    QCommandLineParser parser;
    	parser.setApplicationDescription("KToggle, a tool to toggle any app");
    	parser.addHelpOption();
    	parser.addVersionOption();
    	QCommandLineOption classOption(QStringList() << "c" << "class",
    		QCoreApplication::translate("main", "Window class to toggle."),
    		QCoreApplication::translate("main", "class"));
    	parser.addOption(classOption);
    
    	QCommandLineOption nameOption(QStringList() << "n" << "name",
    		QCoreApplication::translate("main", "Window name to toggle. Substrings are also accepted."),
    		QCoreApplication::translate("main", "name"));
    	parser.addOption(nameOption);
    
    	QCommandLineOption programOption(QStringList() << "p" << "program",
    		QCoreApplication::translate("main", "Command to run program. May include optional flags."),
    		QCoreApplication::translate("main", "program"));
    	parser.addOption(programOption);
    
    	QCommandLineOption iconOption(QStringList() << "i" << "icon",
    		QCoreApplication::translate("main", "Tray icon to display. If unspecified, window's own icon will be displayed."),
    		QCoreApplication::translate("main", "icon"));
    	parser.addOption(iconOption);
    
    	QCommandLineOption xyOption(QStringList() << "xy",
    		QCoreApplication::translate("main", "x and y coordinates of the window."),
    		QCoreApplication::translate("main", "x,y"));
    	xyOption.setDefaultValue("0,0");
    	parser.addOption(xyOption);
    
    	QCommandLineOption sizeOption(QStringList() << "size",
    		QCoreApplication::translate("main", "Size of the window."),
    		QCoreApplication::translate("main", "height,width"));
    	sizeOption.setDefaultValue("500,700");
    	parser.addOption(sizeOption);
    
    	QCommandLineOption trayOption("no-tray",
    		QCoreApplication::translate("main", "Do not display tray icon."));
    	parser.addOption(trayOption);
    
    	QCommandLineOption cmdToRaiseOption("cmd-to-raise",
    		QCoreApplication::translate("main", "Raise window running the command each time. Use this for apps like Telegram that hide the window when minimized."));
    	parser.addOption(cmdToRaiseOption);
    
    	parser.process(app);
    

    then I'm trying to parse a json object to then send to QML:

    QByteArray parserToJs(const QCommandLineParser &parser){
    	QMap<QString, QString> map;
    
    	map["class"] = "windowClass";
    	map["name"] = "windowName";
    	map["program"] = "program";
    	map["icon"] = "icon";
    	map["no-tray"] = "noTray";
    	map["xy"] = "xy";
    	map["size"] = "size";
    	map["cmd-to-raise"] = "cmdToRaise";
    	
    	map["p"] = map["program"];
    	map["n"] = map["name"];
    	map["c"] = map["class"];
    	map["i"] = map["icon"];
    
    
    	QJsonObject parserJS;
    
    	qWarning() << parser.isSet("icon");
    
    	const QStringList options = map.keys(); //parser.optionNames();
    	for (const QString& option : options) {
    		if(parser.isSet(option)){
    			parserJS[map[option]] = parser.value(option);
    		} else {
    			qWarning() << option << "not set";
    		}
    	}
    
    	QJsonDocument docJS(parserJS);
    	return docJS.toJson();
    }
    

    this is the help page, correctly showing all my arguments:

    
    Options:
    -h, --help               Displays help on commandline options.
    --help-all               Displays help including Qt specific options.
    -v, --version            Displays version information.
    -c, --class <class>      Window class to toggle.
    -n, --name <name>        Window name to toggle. Substrings are also accepted.
    -p, --program <program>  Command to run program. May include optional flags.
    -i, --icon <icon>        Tray icon to display. If unspecified, window's own
    icon will be displayed.
    --xy <x,y>               x and y coordinates of the window.
    --size <height,width>    Size of the window.
    --no-tray                Do not display tray icon.
    --cmd-to-raise           Raise window running the command each time. Use this
    for apps like Telegram that hide the window when
    minimized.
    

    but somehow, icon and name are not recognized:

    $ ./build/bin/helloworld --class kate -p kate --icon plasma --xy 1,3 --size 800,500 --no-tray --name pippo
    
    "cmd-to-raise" not set
    "i" not set
    "icon" not set
    "n" not set
    "name" not set
    

    am I doing something wrong? Or is this a bug?
    thanks in advance!

    JonBJ 1 Reply Last reply
    0
    • T tubbadu

      Hello! I'm having troubles trying to make QCommandLineParser work in my application:
      for some reasons I don't understand, some arguments are simply ignored by the parser, and it always returns false at isSet. Here's the code:

      QCommandLineParser parser;
      	parser.setApplicationDescription("KToggle, a tool to toggle any app");
      	parser.addHelpOption();
      	parser.addVersionOption();
      	QCommandLineOption classOption(QStringList() << "c" << "class",
      		QCoreApplication::translate("main", "Window class to toggle."),
      		QCoreApplication::translate("main", "class"));
      	parser.addOption(classOption);
      
      	QCommandLineOption nameOption(QStringList() << "n" << "name",
      		QCoreApplication::translate("main", "Window name to toggle. Substrings are also accepted."),
      		QCoreApplication::translate("main", "name"));
      	parser.addOption(nameOption);
      
      	QCommandLineOption programOption(QStringList() << "p" << "program",
      		QCoreApplication::translate("main", "Command to run program. May include optional flags."),
      		QCoreApplication::translate("main", "program"));
      	parser.addOption(programOption);
      
      	QCommandLineOption iconOption(QStringList() << "i" << "icon",
      		QCoreApplication::translate("main", "Tray icon to display. If unspecified, window's own icon will be displayed."),
      		QCoreApplication::translate("main", "icon"));
      	parser.addOption(iconOption);
      
      	QCommandLineOption xyOption(QStringList() << "xy",
      		QCoreApplication::translate("main", "x and y coordinates of the window."),
      		QCoreApplication::translate("main", "x,y"));
      	xyOption.setDefaultValue("0,0");
      	parser.addOption(xyOption);
      
      	QCommandLineOption sizeOption(QStringList() << "size",
      		QCoreApplication::translate("main", "Size of the window."),
      		QCoreApplication::translate("main", "height,width"));
      	sizeOption.setDefaultValue("500,700");
      	parser.addOption(sizeOption);
      
      	QCommandLineOption trayOption("no-tray",
      		QCoreApplication::translate("main", "Do not display tray icon."));
      	parser.addOption(trayOption);
      
      	QCommandLineOption cmdToRaiseOption("cmd-to-raise",
      		QCoreApplication::translate("main", "Raise window running the command each time. Use this for apps like Telegram that hide the window when minimized."));
      	parser.addOption(cmdToRaiseOption);
      
      	parser.process(app);
      

      then I'm trying to parse a json object to then send to QML:

      QByteArray parserToJs(const QCommandLineParser &parser){
      	QMap<QString, QString> map;
      
      	map["class"] = "windowClass";
      	map["name"] = "windowName";
      	map["program"] = "program";
      	map["icon"] = "icon";
      	map["no-tray"] = "noTray";
      	map["xy"] = "xy";
      	map["size"] = "size";
      	map["cmd-to-raise"] = "cmdToRaise";
      	
      	map["p"] = map["program"];
      	map["n"] = map["name"];
      	map["c"] = map["class"];
      	map["i"] = map["icon"];
      
      
      	QJsonObject parserJS;
      
      	qWarning() << parser.isSet("icon");
      
      	const QStringList options = map.keys(); //parser.optionNames();
      	for (const QString& option : options) {
      		if(parser.isSet(option)){
      			parserJS[map[option]] = parser.value(option);
      		} else {
      			qWarning() << option << "not set";
      		}
      	}
      
      	QJsonDocument docJS(parserJS);
      	return docJS.toJson();
      }
      

      this is the help page, correctly showing all my arguments:

      
      Options:
      -h, --help               Displays help on commandline options.
      --help-all               Displays help including Qt specific options.
      -v, --version            Displays version information.
      -c, --class <class>      Window class to toggle.
      -n, --name <name>        Window name to toggle. Substrings are also accepted.
      -p, --program <program>  Command to run program. May include optional flags.
      -i, --icon <icon>        Tray icon to display. If unspecified, window's own
      icon will be displayed.
      --xy <x,y>               x and y coordinates of the window.
      --size <height,width>    Size of the window.
      --no-tray                Do not display tray icon.
      --cmd-to-raise           Raise window running the command each time. Use this
      for apps like Telegram that hide the window when
      minimized.
      

      but somehow, icon and name are not recognized:

      $ ./build/bin/helloworld --class kate -p kate --icon plasma --xy 1,3 --size 800,500 --no-tray --name pippo
      
      "cmd-to-raise" not set
      "i" not set
      "icon" not set
      "n" not set
      "name" not set
      

      am I doing something wrong? Or is this a bug?
      thanks in advance!

      JonBJ Offline
      JonBJ Offline
      JonB
      wrote on last edited by JonB
      #2

      @tubbadu
      I cannot spot what is wrong in your code. Do I dimly recall that Qt applications automatically/by default recognise a couple of command-line switches themselves and remove from command-line for future parsing? --name & --icon look a bit like UI options. Why don't you test your code against bool QCommandLineParser::parse(const QStringList &arguments) or void QCommandLineParser::process(const QStringList &arguments) instead? If that is different, then check out what the command-line arguments are actually being passed to QCommandLineParser::process(const QCoreApplication &app).

      Otherwise start by stripping your code down to a minimum, e.g. only accepting --icon, and pass only --icon on command-line, get that working, build up from there.

      T 1 Reply Last reply
      2
      • JonBJ JonB

        @tubbadu
        I cannot spot what is wrong in your code. Do I dimly recall that Qt applications automatically/by default recognise a couple of command-line switches themselves and remove from command-line for future parsing? --name & --icon look a bit like UI options. Why don't you test your code against bool QCommandLineParser::parse(const QStringList &arguments) or void QCommandLineParser::process(const QStringList &arguments) instead? If that is different, then check out what the command-line arguments are actually being passed to QCommandLineParser::process(const QCoreApplication &app).

        Otherwise start by stripping your code down to a minimum, e.g. only accepting --icon, and pass only --icon on command-line, get that working, build up from there.

        T Offline
        T Offline
        tubbadu
        wrote on last edited by
        #3

        @JonB you are right! running the app with --help-all lists all available Qt arguments, and icon and name are between them. Using different names fixed the problem, thank you very much!
        I think however that QCommandLineParser should raise an error instead of displaying it in the available arguments and then ignoring it...

        JonBJ 1 Reply Last reply
        0
        • T tubbadu has marked this topic as solved on
        • T tubbadu

          @JonB you are right! running the app with --help-all lists all available Qt arguments, and icon and name are between them. Using different names fixed the problem, thank you very much!
          I think however that QCommandLineParser should raise an error instead of displaying it in the available arguments and then ignoring it...

          JonBJ Offline
          JonBJ Offline
          JonB
          wrote on last edited by
          #4

          @tubbadu
          There must/ought to be a way (putenv(SOME_ENV_VAR)?) of switching off Qt grabbing its own arguments? Which you might want here? Else Qt apps could never see generic arguments, maybe this is a QGuiApplication thing not QCoreApplication?

          1 Reply Last reply
          0

          • Login

          • Login or register to search.
          • First post
            Last post
          0
          • Categories
          • Recent
          • Tags
          • Popular
          • Users
          • Groups
          • Search
          • Get Qt Extensions
          • Unsolved