Qt5.4开发文档翻译:QCommandLineParser类,QCommandLineParser Class
QCommandLineParser 类,提供了一种用于处理命令行选项的手段。 详细说明……
头文件: |
#include <QCommandLineParser> |
qmake指令: |
QT += core |
自此版本开始引入: |
Qt 5.2 |
QCommandLineParser 类,提供了一种用于处理命令行选项的手段。
QCoreApplication 以一个简单的字符串列表的形式 来 表示命令行参数。 QCommandLineParser 提供 了更强大的能力 :定义 一组选项;解析命令 行参数;记录 ,哪些选项已被实际使用;记录 ,选项的值。
任何 一个不被解析为选项 ( 即,不以符号 -开头 ) 的参数,都被存储为一个“位置参数”。
这个解析器,能够处理:短选项名字;长选项名字;同一个选项具有多个名字;以及,选项值。
命令 行中的选项, 其识别依据为 :以单个或两个 - 字符开头。选项 - (单个减号 ,不带字母 ) ,是一个特殊情况,通常表示 的是标准输入,因而 并不会被当作选项来处理。选项 -- ( 双减号 )之后 的任何东西,都会被解析器当成是位置参数。
短选项,也就是单个字母。对于选项 v ,在命令行中是通过传递 -v 来表示的。 在默认解析模式中, 短选项可使用一种紧凑格式来编写,例如, -abc 等价 于 -a -b -c 。对于 这种紧凑格式的选项,也可将解析模式设置为 ParseAsLongOptions ,那样 的话, -abc 会被解析为长选项 abc 。
长选项,也就是,其中包含着多于1个字母,并且不可以紧缩的方式来处理。对于 长选项 verbose ,可传递为 --verbose ,或者传递为 -verbose 。
要向选项传递值的话,可使用赋值操作符: -v=value 、 --verbose=value ;或者使用空格: -v value 、 --verbose value ,也就是说,下一个参数会被用作其值 (即使 它以 - 开头也是如此 ) 。
这个解析器,不接受可选值——如果已经指定某个选项需要一个值,那么,就必须为它传入一个值。如果该选项被放置在命令行末尾,并且未设置值,那么,会认为该选项根本就没有被指定。
这个解析器,并不支持利用 --disable-option 或 --no-option 这种格式来反转 或禁用长选项。然而 , 妳可以显式地处理这种情况,具体做法就是, 以 no-option 作为它的名字,然后显式地处理其意义。
示例:
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."));
// 一个逻辑值选项,它只有一个名字 (-p)
QCommandLineOption showProgressOption("p", QCoreApplication ::translate("main", "Show progress during copy"));
parser.addOption(showProgressOption);
// 一个逻辑值选项,它有多个名字 (-f, --force)
QCommandLineOption forceOption( QStringList () << "f" << "force",
QCoreApplication ::translate("main", "Overwrite existing files."));
parser.addOption(forceOption);
// 一个选项,它需要一个值
QCommandLineOption targetDirectoryOption( QStringList () << "t" << "target-directory",
QCoreApplication ::translate("main", "Copy all source files into <directory>."),
QCoreApplication ::translate("main", "directory"));
parser.addOption(targetDirectoryOption);
// 处理用户实际提供的命令行参数
parser.process(app);
const QStringList args = parser.positionalArguments();
// source 即为 args.at(0) , destination 即为 args.at(1)
bool showProgress = parser.isSet(showProgressOption);
bool force = parser.isSet(forceOption);
QString targetDir = parser.value(targetDirectoryOption);
// ...
}
如果妳的编译器支持 C++11标准 ,那么, 上面示例中的三个 addOption ()调用还可以简化:
parser.addOptions({
// 一个逻辑选项,只有一个名字 (-p)
{"p",
QCoreApplication ::translate("main", "Show progress during copy")},
// 一个逻辑选项,它具有多个名字 (-f, --force)
{{"f", "force"},
QCoreApplication ::translate("main", "Overwrite existing files.")},
// 一个选项,它需要一个值
{{"t", "target-directory"},
QCoreApplication ::translate("main", "Copy all source files into <directory>."),
QCoreApplication ::translate("main", "directory")},
});
已知 的 限制 :对于Qt 本身 的选项的解析,是在 QCoreApplication 及其子类中进行的,这个过程在 QCommandLineParser 存在之前就发生了,因此 , QCommandLineParser 对此无能为力 。 这就意味着,任何 一个看起来像是内置Qt 选项的选项, 都会被 QCoreApplication 当成Qt 内置选项来处理。例如: --profile -reverse ,将导致, QGuiApplication 检测 到 -reverse选项 的存在,并且 从 QCoreApplication::arguments ()中删去它,然后 ,才轮到 QCommandLineParser 检测 出 profile 选项并且解析命令 行参数。
在实际开发中,对于那些位置参数,以及选项的值,都应当进行额外的错误检查。例如,应当检查数字的范围。
然后 ,较好 的做法就是,编写 一个函数 ,用来进行命令 行参数解析, 它需要一个结构体或类作为参数来接收选项 值,并且返回 一个枚举,用来表示结果。 QtNetwork 模块 中的dnslookup 示例,展示了这一点:
struct DnsQuery
{
DnsQuery() : type( QDnsLookup ::A) {}
QDnsLookup ::Type type;
QHostAddress nameServer;
QString name;
};
enum CommandLineParseResult
{
CommandLineOk,
CommandLineError,
CommandLineVersionRequested,
CommandLineHelpRequested
};
CommandLineParseResult parseCommandLine( QCommandLineParser &parser, DnsQuery *query, QString *errorMessage)
{
parser.setSingleDashWordOptionMode( QCommandLineParser ::ParseAsLongOptions);
const QCommandLineOption nameServerOption("n", "The name server to use.", "nameserver");
parser.addOption(nameServerOption);
const QCommandLineOption typeOption("t", "The lookup type.", "type");
parser.addOption(typeOption);
parser.addPositionalArgument("name", "The name to look up.");
const QCommandLineOption helpOption = parser.addHelpOption();
const QCommandLineOption versionOption = parser.addVersionOption();
if (!parser.parse( QCoreApplication ::arguments())) {
*errorMessage = parser.errorText();
return CommandLineError;
}
if (parser.isSet(versionOption))
return CommandLineVersionRequested;
if (parser.isSet(helpOption))
return CommandLineHelpRequested;
if (parser.isSet(nameServerOption)) {
const QString nameserver = parser.value(nameServerOption);
query->nameServer = QHostAddress (nameserver);
if (query->nameServer.isNull() || query->nameServer.protocol() == QAbstractSocket ::UnknownNetworkLayerProtocol) {
*errorMessage = "Bad nameserver address: " + nameserver;
return CommandLineError;
}
}
if (parser.isSet(typeOption)) {
const QString typeParameter = parser.value(typeOption);
const int type = typeFromParameter(typeParameter.toLower());
if (type < 0) {
*errorMessage = "Bad record type: " + typeParameter;
return CommandLineError;
}
query->type = static_cast< QDnsLookup ::Type>(type);
}
const QStringList positionalArguments = parser.positionalArguments();
if (positionalArguments.isEmpty()) {
*errorMessage = "Argument 'name' missing.";
return CommandLineError;
}
if (positionalArguments.size() > 1) {
*errorMessage = "Several 'name' arguments specified.";
return CommandLineError;
}
query->name = positionalArguments.first();
return CommandLineOk;
}
在主函数中,如果发现通过命令行传递了帮助(help)选项,那么,应当向标准流出流输出帮助内容,并且,应用程序应当以代码0退出。
如果检测到了错误,那么,应当向标准错误流里输出错误消息,并且,应用程序应当返回一个不等于0的退出代码。
QCoreApplication ::setApplicationVersion(QT_VERSION_STR);
QCoreApplication ::setApplicationName( QCoreApplication ::translate("QDnsLookupExample", "DNS Lookup Example"));
QCommandLineParser parser;
parser.setApplicationDescription( QCoreApplication ::translate("QDnsLookupExample", "An example demonstrating the class QDnsLookup."));
DnsQuery query;
QString errorMessage;
switch (parseCommandLine(parser, &query, &errorMessage)) {
case CommandLineOk:
break;
case CommandLineError:
fputs( qPrintable (errorMessage), stderr);
fputs("\n\n", stderr);
fputs( qPrintable (parser.helpText()), stderr);
return 1;
case CommandLineVersionRequested:
printf("%s %s\n", qPrintable ( QCoreApplication ::applicationName()),
qPrintable ( QCoreApplication ::applicationVersion()));
return 0;
case CommandLineHelpRequested:
parser.showHelp();
Q_UNREACHABLE();
}
此处,有一点特殊情况需要考虑,那就是,在移动平台上的图形界面程序。这些程序,无法使用标准输出流和标准错误流,因为,它们会被系统忽略或者根本无法访问。
对于这种图形界面应用程序,我们建议使用 一个 QMessageBox 来显示帮助文字 和错误消息。 为了保留帮助文字 的格式,应当使用 带有 <pre> 元素的富文本形式:
switch (parseCommandLine(parser, &query, &errorMessage)) {
case CommandLineOk:
break;
case CommandLineError:
#ifdef Q_OS_WIN
QMessageBox ::warning(0, QGuiApplication ::applicationDisplayName(),
"<html><head/><body><h2>" + errorMessage + "</h2><pre>"
+ parser.helpText() + "</pre></body></html>");
#else
fputs( qPrintable (errorMessage), stderr);
fputs("\n\n", stderr);
fputs( qPrintable (parser.helpText()), stderr);
#endif
return 1;
case CommandLineVersionRequested:
#ifdef Q_OS_WIN
QMessageBox ::information(0, QGuiApplication ::applicationDisplayName(),
QGuiApplication ::applicationDisplayName() + ' '
+ QCoreApplication ::applicationVersion());
#else
printf("%s %s\n", QGuiApplication ::applicationDisplayName(),
qPrintable ( QCoreApplication ::applicationVersion()));
#endif
return 0;
case CommandLineHelpRequested:
#ifdef Q_OS_WIN
QMessageBox ::warning(0, QGuiApplication ::applicationDisplayName(),
"<html><head/><body><pre>"
+ parser.helpText() + "</pre></body></html>");
return 0;
#else
parser.showHelp();
Q_UNREACHABLE();
#endif
}
然而,这对于dnslookup 示例来说没有意义,因为它是一个终端界面应用程序。
参考 QCommandLineOption 和 QCoreApplication 。
这个枚举,描述的是,在遇到命令行中单个减号后面跟着多个字母(例如 -abc )时,解析器应当如何解释其中的选项。
常量 |
值 |
说明 |
QCommandLineParser::ParseAsCompactedShortOptions |
0 |
-abc 被解释为:如果这三个选项都不带参数值的话,则解释成 -a -b -c ,即,以紧缩形式表达的三个选项;如果 a需要一个参数值,则,会被解释为 -a bc ,即,短选项 a后面跟上参数值 bc ,这通常用于那些其行为与编译器类似的工具程序,用来处理像 -DDEFINE=VALUE 或是 -I/include/path 这样的选项。这是默认的解析模式。对于新开发的程序,我们建议使用这种模式。 |
QCommandLineParser::ParseAsLongOptions |
1 |
-abc 被解释 --abc ,也就是说,被解释成名为 abc 的长选项。这是Qt自带的那些工具(uic, rcc...)解析参数的方式。这种模式,只应当用来维持那些本来就以这种形式解析参数的程序的兼容性。 |
参考 setSingleDashWordOptionMode () 。
加入帮助选项( -h 、 --help ) 。这个选项由 QCommandLineParser 自动处理。
别忘记使用 setApplicationDescription 来设置程序的说明文字, 当用户触发这个选项时,那个说明文字会被自动输出。
示例:
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);
// ...
}
返回 该选项的实例,以便日后用来调用 isSet () 。
添加一个选项 option ,以在解析时处理。
如果添加成功, 则返回真( true );否则返回假( false )。
以下情况下,添加选项会失败:该选项中未附带任何名字;或者,该选项的名字,与之前添加的某个选项的名字冲突。
添加一系列要在解析时寻找的选项。那些选项,是使用参数 options 来指定的。
如果 这些选项都添加成功,则返回真( true );否则返回假( false )。
参考 addOption () 的文档,以了解,此函数在什么情况下会失败。
此函数是从Qt 5.4 开始引入的。
为该应用程序定义一个额外的参数,这主要是为了更好地构造帮助文字。
参数 name 和 description 会出现在帮助文字中的 Arguments: 小节中。如果 还指定了 syntax ,则, 它会出现在 Usage 中,否则,只会将 name 追加到说明文字末尾。
示例:
// Usage: image-editor file
//
// Arguments:
// file The file to open.
parser.addPositionalArgument("file", QCoreApplication ::translate("main", "The file to open."));
// Usage: web-browser [urls...]
//
// Arguments:
// urls URLs to open, optionally.
parser.addPositionalArgument("urls", QCoreApplication ::translate("main", "URLs to open, optionally."), "[urls...]");
// Usage: cp source destination
//
// Arguments:
// source Source file to copy.
// destination Destination directory.
parser.addPositionalArgument("source", QCoreApplication ::translate("main", "Source file to copy."));
parser.addPositionalArgument("destination", QCoreApplication ::translate("main", "Destination directory."));
参考 addHelpOption () 和 helpText () 。
添加 -v / --version 选项 ,它会显示出该应用程序的版本字符串。
这个选项由 QCommandLineParser 自动处理。
妳可使用 QCoreApplication::setApplicationVersion ()来设置实际的版本号字符串。
返回 该选项的实例,以便日后用来调用 isSet () 。
清除之前为帮助文本而设置的那些额外参数定义。
这个功能,只在特殊情况下有必要使用:某些工具,会支持多个命令,因而会有不同的选项集合。当妳识别出实际的命令之后,就可以定义出针对这个命令的选项集合,因而可以相应地调整该命令的帮助文字。
示例:
QCoreApplication app(argc, argv);
QCommandLineParser parser;
parser.addPositionalArgument("command", "The command to execute.");
// 调用parse()来找到那些位置参数。
parser.parse( QCoreApplication ::arguments());
const QStringList args = parser.positionalArguments();
const QString command = args.isEmpty() ? QString () : args.first();
if (command == "resize") {
parser.clearPositionalArguments();
parser.addPositionalArgument("resize", "Resize the object to a new size.", "resize [resize_options]");
parser.addOption( QCommandLineOption ("size", "New size.", "new_size"));
parser.process(app);
// ...
}
/*
这段代码,将导致,产生上下文相关的帮助文字:
$ tool --help
Usage: tool command
Arguments:
command The command to execute.
$ tool resize --help
Usage: tool resize [resize_options]
Options:
--size <size> New size.
Arguments:
resize Resize the object to a new size.
*/
返回一个字符串,其中包含着完整的帮助文字信息。
参考 showHelp () 。
检查,选项 name 是否已经被传递给应用程序。
如果选项 name 已被设置,则返回真( true ),否则返回假(false)。
此处提供 的名字(name),可以是之前使用 addOption() 添加的任何一个长选项名或短选项名。所有 的那些选项名字都被认为是等价的。如果无法识别 出该名字或者该选项未被设置,则返回假(false)。
示例:
bool verbose = parser.isSet("verbose");
这是一个重载函数。
检查,选项 option 是否被传递给了应用程序。
如果选项 option 已被设置,则返回真( true ),否则返回假(false)。
对于那些不带参数值的选项,建议使用这种方式来检查。
示例:
QCoreApplication app(argc, argv);
QCommandLineParser parser;
QCommandLineOption verboseOption("verbose");
parser.addOption(verboseOption);
parser.process(app);
bool verbose = parser.isSet(verboseOption);
返回位置参数的列表。
这,是那些未能被识别为某个选项的一部分的参数的集合。
这是一个重载函数。
命令 行参数是通过 QCoreApplication 实例 app 来获取的。
谭 雨
瑩 丁 角主 密秘的人女
贈敬司公業影光嶺
Your opinionsHxLauncher: Launch Android applications by voice commands