1. 程式人生 > >使用 Qt 解析命令列引數

使用 Qt 解析命令列引數

Qt解析命令列

我們使用 Python 寫個簡單的指令碼很方便,直接 import argparse 就能很容易的實現命令列引數解析的功能,還可以通過 --help 來輸出幫助功能,而 Qt5 頁提供了這方面的支援。

Qt 從 Qt5.2之後提供了 QCommandLineParserQCommandLineOption 兩個類來負責這個功能。

QCoreApplication 提供了方法用一個簡單的 String 佇列來獲取引數;QCommandLineParser 提供了定義一些選項、複製命令列引數、儲存實際有必要的引數的能力。如果一個引數不是一個選項,那麼它會被認為是positional argument

. QCommandLineParser 可以處理短名稱-a、長名稱--all、多個名稱、選項值等。

命令列的選型是由 ‘-’ 或 “–” 開頭的字串。短選項是’-a’,只有一個字母,通常表示標準輸入。有的時候也會寫成緊湊樣式,比如-a -b -c表示三個選項,-abc也表示三個短選項,只有當你設定 QCommandLineParser 的模式為 ParseAsLongOptions 時,-abc 才表示維長選項。

長選項多餘兩個字母長,並且不可以寫成緊湊樣式,例如 verbose 寫為-verbose 或 --verbose而且寫錯了並不會自動糾正。

在選項後面賦值有兩種方式,一種是空格符間隔將值跟在選項後面,另一種是選項緊跟’=’號和值。例如:-v=value --verbose=value

或者是 -v value --verbose value

而且經過我的測試,Qt 的這個工具獲得的值只能是 QString 型別,也就是說,如果你需要的是 int double float 之類的引數,你需要通過其他的函式自己進行轉換。

樣例程式碼

int main(int argc, char *argv[])
  {
      // 設定程式資訊
      QCoreApplication app(argc, argv);
      QCoreApplication::setApplicationName("my-copy-program");
      QCoreApplication::setApplicationVersion("1.0"
); // 解析工具 QCommandLineParser parser; parser.setApplicationDescription("Test helper"); parser.addHelpOption(); parser.addVersionOption(); parser.addPositionalArgument( "source", QCoreApplication::translate("main", "Source file to copy.")); parser.addPositionalArgument( "destination", QCoreApplication::translate("main", "Destination directory.")); // A boolean option with a single name (-p) QCommandLineOption showProgressOption( "p", QCoreApplication::translate("main", "Show progress during copy")); parser.addOption(showProgressOption); // A boolean option with multiple names (-f, --force) QCommandLineOption forceOption( QStringList() << "f" << "force", QCoreApplication::translate("main", "Overwrite existing files.")); parser.addOption(forceOption); // An option with a value QCommandLineOption targetDirectoryOption( QStringList() << "t" << "target-directory", QCoreApplication::translate("main", "Copy all source files into <directory>."), QCoreApplication::translate("main", "directory")); parser.addOption(targetDirectoryOption); // Process the actual command line arguments given by the user parser.process(app); const QStringList args = parser.positionalArguments(); // source is args.at(0), destination is args.at(1) bool showProgress = parser.isSet(showProgressOption); bool force = parser.isSet(forceOption); QString targetDir = parser.value(targetDirectoryOption); // ... }

如果你使用了C++ 11 標準的編譯器,那麼你還可以用下面的寫法來做。

      parser.addOptions(  {
          // A boolean option with a single name (-p)
          {"p",
              QCoreApplication::translate("main", "Show progress during copy")  },
          // A boolean option with multiple names (-f, --force)
          {  {"f", "force"},
              QCoreApplication::translate("main", "Overwrite existing files.")  },
          // An option with a value
          {  {"t", "target-directory"},
              QCoreApplication::translate("main", "Copy all source files into <directory>."),
              QCoreApplication::translate("main", "directory")  },
      }  );

設定為bool型別的

功能是判斷是否有出現過某個選項,操作如下:

QCoreApplication a(argc, argv);
// A boolean option with a single name (-p)
QCommandLineOption showProgressOption(
            "p",
            QCoreApplication::translate("main", "Show progress during copy"));
parser.addOption(showProgressOption);

// ......
parser.process(a);

bool showProgress = parser.isSet(showProgressOption);   // 檢視選項是否出現在命令列引數中。

設定可獲得值的引數

QCoreApplication a(argc, argv);
// An option with a value
QCommandLineOption targetDirectoryOption(
            QStringList() << "t" << "target-directory",
        QCoreApplication::translate("main", "Copy all source files into <directory>."),
        QCoreApplication::translate("main", "directory"));
parser.addOption(targetDirectoryOption);

// .......
parser.process(a);
QString targetDir = parser.value(targetDirectoryOption);

Reference