代码之家  ›  专栏  ›  技术社区  ›  elcuco

Qt4的命令行解析器

  •  24
  • elcuco  · 技术社区  · 16 年前

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

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

    编辑:

    似乎Frologic删除了这个。因此,我看到的最佳选择是使用Boost(它既不是API也不是ABI稳定的)或分叉对KDELIB的支持。耶。。。

    11 回复  |  直到 14 年前
        1
  •  23
  •   feedc0de RushPL    8 年前

    QCoreApplication 's constructors 要求 (int &argc, char **argv) (及 QApplication 继承自 QCore应用 ).作为 documentation states ,强烈建议

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

    如果您让Qt在处理参数方面获得了第一个通行证,那么使用Qt也是一个好主意 QStringList QCoreApplication::arguments() 而不是走过去 argv ; QApplication 可能会删除它自己使用的一些参数。

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

    然而 kdelibs 有一个很好的参数解析器, KCmdLineArgs . 它是LGPL,可以在没有 KApplication 如果你真的想(打电话) 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;
    

    未经测试(谁测试过他们在S.O.上发布的内容?)。

        2
  •  17
  •   David Faure    8 年前

    从Qt5.2开始,您最终可以在QtCore本身中找到一个解决方案:我参与了 QCommandLineParser 那里

        3
  •  9
  •   Johan    13 年前

    这与ephemient的答案大致相同,但有一个简单的regexp来帮助解析args。(如果您只需要少量arg,这种方法可能很有用)

    使用以下命令运行:

    ./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;
    }
    
        4
  •  7
  •   KillerWabbit    14 年前

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

        5
  •  3
  •   jesup    16 年前

    这个包确实支持——禁用foo和——通过 opts.addSwitch(“禁用foo”和&foo_disabled); . 您需要处理检查这两者,以及处理指定这两者的人(OOP)。

    我不明白的是这和QT4有什么关系。。。

        6
  •  2
  •   Igor    15 年前
        7
  •  2
  •   denis    15 年前

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

    #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行也一样。

    (每个人都有他/她最喜欢的选择; 这是最简单的。
    值得重复:无论您如何指定选项, 将它们回显到输出文件中 --
    上次运行脚本时使用了哪些参数。“)

    有人知道为什么这不起作用吗(在Qt4.4.3中)?

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

    11月25日增补--

    // 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
    
        8
  •  2
  •   mrmoje    11 年前

    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` 
    

    参数可以按任何顺序传递

    编辑:将更新此代码段 found here

        9
  •  1
  •   Zifre    16 年前

    它必须是Qt4特定的吗?如果没有,, GNU Getopt 这真的很好,不过如果您不使用开源软件,许可可能会有问题。

        10
  •  0
  •   Marius Or.    15 年前

    gperf .

    IBM有一个很好的解决方案 tutorial

        11
  •  0
  •   dwj    14 年前

    另一个我在尝试这样做时遇到的选项:

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

    不过我还没用过。