24

我正在寻找 Qt4 的命令行解析器。

我做了一个小的谷歌搜索,发现了这个:http ://www.froglogic.com/pg?id= PublicationsFreeware&category=getopt 但是它缺乏对“--enable-foo”和“--disable-foo”开关的支持。除此之外,它看起来像一个真正的赢家。

编辑:

Frologic 似乎删除了这个。所以我看到的最好的选择是使用 Boost(它不是 API 也不是 ABI 稳定的)或分叉对 kdelibs 的支持。耶...

4

11 回答 11

23

QCoreApplication的构造函数需要(int &argc, char **argv)(并QApplication继承自QCoreApplication)。如文档所述,强烈建议

由于 QApplication 还处理常见的命令行参数,因此在应用程序本身进行任何解释或修改之前创建它通常是一个好主意。argv

而且,如果您让 Qt 在处理参数方面获得第一次通过,那么使用QStringList QCoreApplication::arguments()而不是遍历也是一个好主意argvQApplication可能会删除它为自己使用的一些论点。

这并不适合与其他参数解析库非常兼容......

然而,kdelibs确实带有一个很好的参数解析器,KCmdLineArgs. KApplication它是 LGPL,如果您真的需要,可以不使用(调用KCmdLineArgs::init)。

KCmdLineOptions options;
options.add("enable-foo", ki18n("enables foo"));
options.add("nodisable-foo", ki18n("disables foo"));
// double negatives are confusing, but this makes disable-foo enabled by default

KCmdLineArgs::addCmdLineOptions(options);
KApplication app;
KCmdLineArgs *args = KCmdLineArgs::parsedArgs();

if (args->isSet("enable-foo") && !args->isSet("disable-foo"))
    cout << "foo enabled" << endl;
else
    cout << "foo disabled" << endl;

未经测试(谁曾经测试过他们在 SO 上发布的内容?)。

于 2009-05-15T20:02:24.680 回答
17

从 Qt 5.2 开始,您终于可以在 QtCore 本身中找到解决方案:我在那里贡献了QCommandLineParser

于 2013-10-04T16:36:12.177 回答
9

这或多或少与 ehemient 相同的答案,但使用简单的正则表达式来帮助解析 args。(如果您只需要少量 args,这种方式可能很有用)

运行这个:

./QArgTest --pid=45 --enable-foo

和代码:

int main(int argc, char *argv[]) {
    QApplication app(argc, argv, false);
    qDebug() << "QApp arg test app"; 

    QStringList args = app.arguments();

    int pid = 0;

    QRegExp rxArgPid("--pid=([0-9]{1,})");
    QRegExp rxArgFooEna("--enable-foo");
    QRegExp rxArgFooDis("--disable-foo");

    for (int i = 1; i < args.size(); ++i) {
        if (rxArgPid.indexIn(args.at(i)) != -1 ) {   
            pid =  rxArgPid.cap(1).toInt();
            qDebug() << i << ":" << args.at(i) << rxArgPid.cap(1) << pid;
        }
        else if (rxArgFooEna.indexIn(args.at(i)) != -1 ) {   
            qDebug() << i << ":" << args.at(i) << "Enable Foo";
        } 
        else if (rxArgFooDis.indexIn(args.at(i)) != -1 ) {   
            qDebug() << i << ":" << args.at(i) << "Disable Foo";
        } 
        else {
            qDebug() << "Uknown arg:" << args.at(i);
        }
    }
    return 0;
}
于 2010-09-21T08:58:13.920 回答
7

还有来自http://www.libqxt.org/的 QxtCommandOptions

于 2010-09-06T19:51:10.313 回答
3

该软件包通过opts.addSwitch("disable-foo", &foo_disabled);支持 --disable-foo 和 --enable-foo 和opts.addSwitch("enable-foo", &foo_enabled); . 您需要同时检查两者,并与指定两者的人打交道(哎呀)。

我不明白的是这与QT4有什么关系......

于 2009-05-15T18:59:44.347 回答
2

一个非常简单的方法是扫描“key=value”参数,
将它们放在一个表中,比如 zz.map: QString -> QVariant,
然后使用 zz.map.value(key, default) 获取它们的值。一个例子:

#include "ztest.h"
Ztest zz;  
int main( int argc, char* argv[] )
{
    zz.eqargs( ++ argv );  // scan  test=2 x=str ... to zz.map

    QString xx = zz.map.value( "xx", "" );
    if( Zint( Size, 10 ))  // a #def -> zz.map.value( "Size", 10 )
        ...

ztest.h< 1 页,以下;Python 相同 ~ 10 行。

(每个人都有他/她最喜欢的选项解析器;这是最简单的。
值得重复:无论您指定选项,将它们回显到输出文件——
“我认识的每个科学家都难以跟踪他们上次运行时使用的参数脚本”。)

为了使 QPoints 等工作,当然需要一个 QString -> QPoint 解析器。任何人都知道为什么这不起作用(在 Qt 4.4.3 中)?

QPoint pt(0,0);
QDataStream s( "QPoint(1,2)" );
s >> pt;
qDebug() << "pt:" << pt;  // QPoint(1364225897,1853106225) ??

新增 25nov --

// ztest.h: scan args x=2 s=str ... to a key -> string table
// usage:
// Ztest ztest;
// int main( int argc, char* argv[] )
// {
//     QApplication app( argc, argv );
//     ztest.eqargs( ++ argv );  // scan leading args name=value ...
//     int x = Zint( x, 10 );  // arg x= or default 10
//     qreal ff = Zreal( ff, 3.14 );
//     QString s = Zstr( s, "default" );
// care: int misspelled = Zint( misspellled ) -- you lose
//version: 2009-06-09 jun denis

#ifndef ztest_h
#define ztest_h

#include <QHash>
#include <QString>
#include <QVariant>
#include <QRegExp>

//------------------------------------------------------------------------------
class Ztest {
public:
  QHash< QString, QVariant > map;
  int test;  // arg test=num,  if( ztest.test )

  Ztest() : test( 0 ) {}

  QVariant val( const QString& key, const QVariant& default_ = 0 )
  {
    return map.value( key, default_ );
  }

  void setval( const QString& key, const QVariant& val )
  {
    map[key] = val;
    if( key == "test"  ||  key == "Test" )
        test = val.toInt();
  }

//------------------------------------------------------------------------------
    // ztest.eqargs( ++ argv )  scans test=2 x=3 ... -> ztest table
  void eqargs( char** argv )
  {
    char** argv0 = argv;
    char *arg;
    QRegExp re( "(\\w+)=(.*)" );  // name= anything, but not ./file=name
    for( ; (arg = *argv) && re.exactMatch( arg );  argv ++ ){
        setval( re.cap(1), re.cap(2) );
    }
        // change argv[0..] -> args after all name=values
    while(( *argv0++ = *argv++) != 0 ) {}
  }
};

extern Ztest ztest;

    // macros: int x = Zint( x, 10 ): x= arg or default 10
#define Zstr( key, default )    ztest.val( #key, default ).toString()
#define Zint( key, default )    ztest.val( #key, default ).toInt()
#define Zreal( key, default )   ztest.val( #key, default ).toDouble()

#endif
于 2009-06-09T13:07:49.557 回答
2

看看这个:http ://code.google.com/p/qtargparser/

于 2009-11-21T10:13:25.593 回答
2

现在是 2013 年,仍然没有“第一方”arg 解析器。无论如何..如果有人发现自己面临同样的问题并想避免 cmd 解析器库附带的学习曲线,这里有一个“快速而肮脏”的解决方案:-

QString QArgByKey(QString key, QChar sep = QChar('\0') ) //prototype usually in separate header

QString QArgByKey(QString key, QChar sep )
{
    bool sepd=sep!=QChar('\0');
    int pos=sepd?qApp->arguments().indexOf(QRegExp('^'+key+sep+"\\S*")):qApp->arguments().indexOf(QRegExp(key));
    return pos==-1?QString::null:
    (sepd?qApp->arguments().at(pos).split(sep).at(1):(++pos<qApp->arguments().size()?qApp->arguments().at(pos):QString::null));
}

例子:-

user@box:~$ ./myApp  firstKey=Value1 --secondKey Value2 thirdKey=val3.1,val3.2,val3.3 --enable-foo

用法:

QString param1   = QArgByKey("firstkey",'='); // Returns `Value1` from first pair
QString param2   = QArgByKey("--secondkey"); // Returns `Value2` from second pair
QString param3-1 = QArgByKey("thirdkey",'=').split(',').at(0); // Returns `val3.1`
bool fooEnabled  = qApp->arguments().contains("--enable-foo"); //To check for `--enable-foo` 

参数可以按任何顺序传递

编辑:此代码段的更新将在此处找到

于 2013-09-01T14:05:28.517 回答
1

它必须是Qt4特定的吗?如果不是,GNU Getopt真的很不错,尽管如果您不使用开源软件,许可可能会成为问题。

于 2009-05-15T18:55:14.310 回答
0

此外,对于一些花哨的选项解析,您可以尝试gperf

IBM 有一个很好的教程

于 2009-11-10T13:48:17.430 回答
0

我也在寻找这样做时遇到的另一个选择:

http://code.google.com/p/qgetopts/

不过我没用过。

于 2010-07-16T18:48:42.353 回答