Results 1 to 13 of 13

Thread: Question on proper use of QCommandLineOption?

  1. #1
    Join Date
    Nov 2009
    Location
    US, Midwest
    Posts
    215
    Thanks
    62
    Thanked 4 Times in 4 Posts
    Qt products
    Qt4
    Platforms
    Unix/X11 Windows

    Default Question on proper use of QCommandLineOption?

    Qt Code:
    1. #include <QCoreApplication>
    2. #include <QCommandLineOption>
    3. #include <QCommandLineParser>
    4. #include <QDebug>
    5.  
    6. /*
    7. How should I use CommandLineOption/Parser to process command line arguments
    8. when the arguments are defined in the string?
    9. For example, if the argument is "p ttt" I want to do one thing, if it is "p mmmm"
    10. I need to do something else. My little test show nothing in debug.
    11. Am I misunderstanding the usage of these classes?
    12.  
    13. Help/advise is appreciated. Thansk.
    14.  */
    15. int main(int argc, char *argv[])
    16. {
    17. QCoreApplication a(argc, argv);
    18. QCommandLineParser parser;
    19.  
    20. QCommandLineOption co({{"p","pp","t"}, "test option", "v1"});
    21. parser.addOption(co);
    22.  
    23. parser.process ( (QStringList() << "p --v1"));
    24. QString vv = parser.value("p");
    25. qDebug() << vv;
    26.  
    27. return a.exec();
    28. }
    To copy to clipboard, switch view to plain text mode 

  2. #2
    Join Date
    Dec 2009
    Location
    New Orleans, Louisiana
    Posts
    791
    Thanks
    13
    Thanked 153 Times in 150 Posts
    Qt products
    Qt5
    Platforms
    MacOS X

    Default Re: Question on proper use of QCommandLineOption?

    I've only used QCommandLineParser once, so not sure if this is an optimal solution, but it works for me and I believe covers all scenarios:
    Qt Code:
    1. QCommandLineOption c_opt({"c","csvfile"}, "The CSV file with desired fields.", "csvfile");
    2. QCommandLineOption i_opt({"i","import"}, "Import the CSV file into tablename");
    3. QCommandLineOption s_opt({"s","sync"}, "Sync tablename with the CSV file fields.");
    4. QCommandLineOption t_opt({"t","table"}, "The target table name.", "tablename");
    5. QCommandLineParser parser;
    6.  
    7. parser.addHelpOption();
    8. parser.addVersionOption();
    9. parser.addOption(c_opt);
    10. parser.addOption(i_opt);
    11. parser.addOption(s_opt);
    12. parser.addOption(t_opt);
    13. parser.addPositionalArgument("db", "The database file to process.");
    14. parser.process(QCoreApplication::arguments());
    15.  
    16. QStringList args = parser.positionalArguments();
    17.  
    18. QString csv_filename = parser.value("csvfile");
    19. QString table_name = parser.value("table");
    20.  
    21. if (!parser.isSet(i_opt) && !parser.isSet(s_opt))
    22. {
    23. qDebug("\nOne of import or sync options is required.\n");
    24. parser.showHelp();
    25. }
    26.  
    27. if (parser.isSet(i_opt) && parser.isSet(s_opt))
    28. {
    29. qDebug("\nOnly one of import or sync options is allowed.\n");
    30. parser.showHelp();
    31. }
    32.  
    33. if (!parser.isSet(c_opt) || csv_filename.isEmpty())
    34. {
    35. qDebug("\nThe CSV file to import is a required option.\n");
    36. parser.showHelp();
    37. }
    38.  
    39. if (!parser.isSet(t_opt) || table_name.isEmpty())
    40. {
    41. qDebug("\nThe table name is a required option.\n");
    42. parser.showHelp(1);
    43. }
    44.  
    45. QString db_filename;
    46.  
    47. if (args.count() == 1)
    48. {
    49. db_filename = args.at(0);
    50. }
    51.  
    52. if (csv_filename.isEmpty() || db_filename.isEmpty())
    53. {
    54. qDebug("\nThe CSV file name and database name are required.\n");
    55. parser.showHelp(1);
    56. }
    To copy to clipboard, switch view to plain text mode 
    I write the best type of code possible, code that I want to write, not code that someone tells me to write!

  3. The following 2 users say thank you to jefftee for this useful post:

    embeddedmz (5th July 2019), TorAn (11th November 2016)

  4. #3
    Join Date
    Nov 2009
    Location
    US, Midwest
    Posts
    215
    Thanks
    62
    Thanked 4 Times in 4 Posts
    Qt products
    Qt4
    Platforms
    Unix/X11 Windows

    Default Re: Question on proper use of QCommandLineOption?

    Thank you so much! Using your code I figured out what was the main problem that I was dealing with. It turns out that the call

    Qt Code:
    1. parser.process(QCoreApplication::arguments());
    To copy to clipboard, switch view to plain text mode 
    or
    Qt Code:
    1. parser.process (QStringList&);
    To copy to clipboard, switch view to plain text mode 

    works by assuming that the the first element in QStringList must be the path to the process (argv[0]). Qt documentation does not mention it at all, and I was passing list that had two arguments (option and option value).
    It also works if the first element in the list is just an empty string.

  5. #4
    Join Date
    Nov 2009
    Location
    US, Midwest
    Posts
    215
    Thanks
    62
    Thanked 4 Times in 4 Posts
    Qt products
    Qt4
    Platforms
    Unix/X11 Windows

    Default Re: Question on proper use of QCommandLineOption?

    jefftee: Would you be so kind to also publish a command of how you actually invoke your application with the options, specifically with "positionalArgument" db? I can't find out (in the docs) how it should be specified. db=smth? db "smth"?

  6. #5
    Join Date
    Dec 2009
    Location
    New Orleans, Louisiana
    Posts
    791
    Thanks
    13
    Thanked 153 Times in 150 Posts
    Qt products
    Qt5
    Platforms
    MacOS X

    Default Re: Question on proper use of QCommandLineOption?

    Sure, a typical usage would be:
    Qt Code:
    1. tablesync -i -c test.csv -t incident_data ~/db/sqlite.db
    To copy to clipboard, switch view to plain text mode 
    Here's also the "tablesync -h" output that is automatically built:
    Qt Code:
    1. mbp02:~/develop/tablesync[develop]$ tablesync -h
    2. Usage: tablesync [options] db
    3.  
    4. Options:
    5. -h, --help Displays this help.
    6. -v, --version Displays version information.
    7. -c, --csvfile <csvfile> The CSV file with desired fields.
    8. -i, --import Import the CSV file into tablename
    9. -s, --sync Sync tablename with the CSV file fields.
    10. -t, --table <tablename> The target table name.
    11.  
    12. Arguments:
    13. db The database file to process.
    To copy to clipboard, switch view to plain text mode 

    As shown above, the only positional argument is the last, so that requires that all cmd line options that start with a "-" must precede any positional arguments. The Qt behavior with QCommandLineParser seems pretty sane/normal to me, so I'm quite happy to use it rather than have to deal with the differences between getopt(s) on different OS platforms, etc.
    I write the best type of code possible, code that I want to write, not code that someone tells me to write!

  7. The following user says thank you to jefftee for this useful post:

    TorAn (11th November 2016)

  8. #6
    Join Date
    Nov 2009
    Location
    US, Midwest
    Posts
    215
    Thanks
    62
    Thanked 4 Times in 4 Posts
    Qt products
    Qt4
    Platforms
    Unix/X11 Windows

    Default Re: Question on proper use of QCommandLineOption?

    Thanks! What is still unclear to me is the case where there are more then one "positionalArgument". In your case it is "db" and you expect only one argument there. But what if there are more then one positionalArguments? Like, "db" and "openReadOnly" or something similar? How to distinguish between two or more positionalArguments?

  9. #7
    Join Date
    Dec 2009
    Location
    New Orleans, Louisiana
    Posts
    791
    Thanks
    13
    Thanked 153 Times in 150 Posts
    Qt products
    Qt5
    Platforms
    MacOS X

    Default Re: Question on proper use of QCommandLineOption?

    See line 16 in the code I posted. Positional args are stored in a QStringList named args, so args.size() will tell you how many positional args were present, and args[0] is the first, args[1] is the 2nd, etc. You can have as many positional args as you want, but they must follow any other options that start with "-" or "--" and you can't have a missing (default) positional argument unless it's the last one (and perhaps only).

    Hope that helps.
    I write the best type of code possible, code that I want to write, not code that someone tells me to write!

  10. The following user says thank you to jefftee for this useful post:

    TorAn (11th November 2016)

  11. #8
    Join Date
    Nov 2009
    Location
    US, Midwest
    Posts
    215
    Thanks
    62
    Thanked 4 Times in 4 Posts
    Qt products
    Qt4
    Platforms
    Unix/X11 Windows

    Default Re: Question on proper use of QCommandLineOption?

    Right, I understood that from the code you posted. Let's say your command line has two positional args, "db1" and "db2" with values ~/db/sqlite1.db and ~/dbsqlite2.db. So, the command line will look like this, right?

    tablesync -i -c test.csv -t incident_data ~/db/sqlite1.db ~/dbsqlite2.db.

    How do you know which one is db1 and which one is db2?

  12. #9
    Join Date
    Dec 2009
    Location
    New Orleans, Louisiana
    Posts
    791
    Thanks
    13
    Thanked 153 Times in 150 Posts
    Qt products
    Qt5
    Platforms
    MacOS X

    Default Re: Question on proper use of QCommandLineOption?

    Yes, for the example you posted above, db1 would be ~/db/sqlite1.db and db2 would be ~/db/sqlite2.db. You would define the two positional arguments like so:
    Qt Code:
    1. parser.addPositionalArgument("db1", "The source database file to process."); // first positional argument
    2. parser.addPositionalArgument("db2", "The destination database file to process."); // second positional argument
    To copy to clipboard, switch view to plain text mode 

    Remember, positional args are just that, their usage is based solely in the order in which they appear, not based on their values or naming, etc.

    In the example above, where you had two positional arguments: ~/db/sqlite1.db ~/dbsqlite2.db, if you screwed up and entered them in reverse order: ~/db/sqlite2.db ~/db/sqlite1.db, then your program will use ~/db/sqlite2.db as db1 and ~/db/sqlite1.db as db2. Think of it like the DOS copy command or Unix cp command where both take a source and target positional argument, i.e. cp source.txt target.txt, which would copy the source.txt file to a new file called target.txt, etc.
    I write the best type of code possible, code that I want to write, not code that someone tells me to write!

  13. The following user says thank you to jefftee for this useful post:

    TorAn (11th November 2016)

  14. #10
    Join Date
    Nov 2009
    Location
    US, Midwest
    Posts
    215
    Thanks
    62
    Thanked 4 Times in 4 Posts
    Qt products
    Qt4
    Platforms
    Unix/X11 Windows

    Default Re: Question on proper use of QCommandLineOption?

    Thank you so much for your help and patience. I could not believe my eyes and your explanations up until the very end. I still find it strange that the designer(s) of positional arguments would use argument order to determine the input value, even though the argument names are available. I kind of ignored the name "PositionalArgument", shame on me.
    Thanks again.

  15. #11
    Join Date
    Jan 2006
    Location
    Graz, Austria
    Posts
    8,416
    Thanks
    37
    Thanked 1,544 Times in 1,494 Posts
    Qt products
    Qt3 Qt4 Qt5
    Platforms
    Unix/X11 Windows

    Default Re: Question on proper use of QCommandLineOption?

    Quote Originally Posted by TorAn View Post
    Thank you so much for your help and patience. I could not believe my eyes and your explanations up until the very end. I still find it strange that the designer(s) of positional arguments would use argument order to determine the input value, even though the argument names are available.
    Positional means that the argument is identified by its position.
    I.e. you can't have the second without having the first.

    Btw, your original problem sounded more like passing a value to a specific commandline switch, i.e. from your description I would have assumed you have a "p" option that has a parameter that can either be "ttt" or "mmmm".

    Cheers,
    _

  16. #12
    Join Date
    Nov 2009
    Location
    US, Midwest
    Posts
    215
    Thanks
    62
    Thanked 4 Times in 4 Posts
    Qt products
    Qt4
    Platforms
    Unix/X11 Windows

    Default Re: Question on proper use of QCommandLineOption?

    Turned out I cannot even use these classes. As I discovered (3 days too late. Clearly spelled out in the documentation, though):
    when an error happens (for instance an unknown option was passed), the current process will then stop, using the exit() function.
    What a strange design...Hopefully this thread will be a warning to others who want to try using these two classes for something other then parsing command-line arguments.

  17. #13
    Join Date
    Dec 2009
    Location
    New Orleans, Louisiana
    Posts
    791
    Thanks
    13
    Thanked 153 Times in 150 Posts
    Qt products
    Qt5
    Platforms
    MacOS X

    Default Re: Question on proper use of QCommandLineOption?

    If you want control over error handling for invalid options, use QCommandLineParser::parse() instead of QCommandLineParser::process().
    I write the best type of code possible, code that I want to write, not code that someone tells me to write!

  18. The following user says thank you to jefftee for this useful post:

    TorAn (13th November 2016)

Similar Threads

  1. Proper file downloading?
    By matt4682 in forum Newbie
    Replies: 4
    Last Post: 2nd May 2014, 10:45
  2. Proper way to use qmake and moc?
    By mossen in forum Newbie
    Replies: 1
    Last Post: 6th May 2011, 02:52
  3. proper use of QList?
    By jhowland in forum Qt Programming
    Replies: 3
    Last Post: 13th September 2010, 14:57
  4. Need help determining proper Qt distribution
    By bizmopeen in forum Newbie
    Replies: 2
    Last Post: 22nd December 2009, 20:47
  5. Proper way to #include Qt?
    By pherthyl in forum Qt Programming
    Replies: 1
    Last Post: 11th August 2006, 02:15

Tags for this Thread

Bookmarks

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •  
Digia, Qt and their respective logos are trademarks of Digia Plc in Finland and/or other countries worldwide.