【问题标题】:Obtaining command line arguments in a Qt application在 Qt 应用程序中获取命令行参数
【发布时间】:2011-02-24 11:46:48
【问题描述】:

以下 sn-p 来自我使用 Qt 框架编写的一个小应用程序。这个想法是应用程序可以以批处理模式运行(即由脚本调用)或可以交互运行。

因此,重要的是,我能够解析命令行参数以了解在哪种模式下运行等。

[编辑]

我在 Ubuntu Karmic 上使用 Qt Creator 1.3.1 进行调试。参数以正常方式传递(即通过 Qt Creator IDE 中的“项目”设置添加它们)。

当我运行应用程序时,似乎没有将参数传递给应用程序。下面的代码是我的 main() 函数的 sn-p。

int main(int argc, char *argv[])
{
    //Q_INIT_RESOURCE(application);

    try {
        QApplication the_app(argc, argv);

        //trying to get the arguments into a list    
        QStringList cmdline_args = QCoreApplication::arguments();

        // Code continues ...
    }
    catch (const MyCustomException &e) { return 1; }

    return 0;
}

[更新]

我已经确定了问题 - 出于某种原因,虽然 argc 是正确的,但 argv 的元素是空字符串。

我用这个小代码 sn-p 打印出 argv 项目 - 看到它们都是空的,我感到很震惊。

for (int i=0; i< argc; i++){
    std::string s(argv[i]); //required so I can see the damn variable in the debugger
    std::cout << s << std::endl;
}

有人知道如何在我的应用程序中检索命令行参数吗?

【问题讨论】:

  • 你的 try/catch 上有一个额外的大括号。你没有给我们实用程序::option_values 的代码......你不能把这个例子简化为说 if cmdline_args.isEmpty() print "oh no!" 吗?如果你这样做了,你还会遇到问题吗?
  • 顺便问一下,utility::options_values 是什么?我在 Qt 文档中也没有看到类似的东西。此外,即使您不传递参数,第一个参数也将始终是程序名称。所以我认为问题可能出在实用程序::option_values 中。你也试过检查 argv[0],argv[1] 等...也试试那个..

标签: c++ qt qt-creator


【解决方案1】:

如果您的 argc 和 argv 都很好,我很惊讶这会成为可能,因为 QApplication::arguments() 非常简单。注意the source code。过滤 Linux 的 #ifdefs,它只是:

QStringList QCoreApplication::arguments()
{
    QStringList list;
    if (!self) {
        qWarning("QCoreApplication::arguments: Please instantiate the QApplication object first");
        return list;
    }
    const int ac = self->d_func()->argc;
    char ** const av = self->d_func()->argv;
    for (int a = 0; a < ac; ++a) {
        list << QString::fromLocal8Bit(av[a]);
    }
    return list;
}

这就是你所拥有的。有一个 Unicode 警告,我认为它不适用于 Karmic:

"在 Unix 上,这个列表是由传递给 main() 函数中的构造函数的 argc 和 argv 参数构建的。argv 中的字符串数据是使用 QString::fromLocal8Bit() 解释的;因此它是例如,无法在以 Latin1 语言环境运行的系统上传递日语命令行参数。大多数现代 Unix 系统没有此限制,因为它们是基于 Unicode 的。"

您可以直接针对您的 argc 和 argv 尝试复制该代码,看看会发生什么。

【讨论】:

  • +1 为我指明了正确的方向。我被 argc 是正确的值误导了,并且没有费心去取消引用 argv 来检查它的内容。我放了一个小语句来将参数打印到标准输出,我很震惊地看到 argv 的元素是空字符串 - 这是什么疯狂?!
  • 我会接受这个作为正确答案,因为它让我走上了正确的道路——而且,我不能删除原来的问题,因为我投票赞成这个答案。原始代码是错误的,因为我应该在应用程序的实例(而不是类)上调用参数 - 我不知道为什么我没有早点发现这一点(也没有人这样做)。在文档参数中还有一个静态方法(当调用 staticall 时它会正确编译 [奇怪地]),实际上我应该将它作为实例方法调用(看图!)。
  • @morpheous:没有必要在 QCoreApplication 的实例上调用 arguments(),因为它是一个静态函数。但是,我发现 qApp->arguemtns() 比 QCoreApplication::arguments() 更好。
  • 正如 iconiK 所说,它不应该对静态或实例产生影响。 (注意它使用“self”而不是“this”...self 是用于处理单实例类的 Qt 宏。)至于 argc 非零时的空 argv...呃,wtf? argv[argc] 为空吗?
【解决方案2】:

如果您正在编写仅控制台应用程序,那么您可能需要考虑使用 QCoreApplication 而不是 QAppliction。 QCoreApplication 是 QtCore 的一部分,而 QApplication 是在 QtGui 中定义的,因此您会获得额外且不必要的依赖。

【讨论】:

    【解决方案3】:

    只是为了保持响应的最新,Qt 现在提供了一个专门用于解析命令行的类:

    http://doc.qt.io/qt-5/qcommandlineparser.html

    附: : 只能作为回复发布,不能作为评论发布;很抱歉,问题不是如何解析,而是如何访问。

    【讨论】:

    • 这当然是公认的答案。任何人都可以解析自己的参数,我实际上写了这样一个库:advgetopt。但是如果你正在编写一个 Qt 应用程序,你应该真正使用 Qt 类。它使它变得容易得多。
    【解决方案4】:

    这是一个在 QStringList 中包含参数的简单示例。假设您使用参数 -q -t

    启动应用程序
    int main(int argc, char *argv[])
    {
    QApplication a(argc, argv);
    MainWindow w;
    w.show();
    
    QString x;
    
    for (int i=1; i<argc; i++)
    {
        x.append(argv[i]);
    }
    qDebug() << x;
    QStringList args = x.split("-");
    args.removeFirst();
    qDebug() << "args="<< args;
    return a.exec();
    }
    

    输出如下

    x= "-q-t"
    
    args= ("q", "t")
    

    现在您将参数作为 QStringList ..

    这是我在一个小应用程序中编写和使用的完整代码

    #include "mainwindow.h"
    
    #include <QApplication>
    #include <QDebug>
    static  QStringList arguments;
    
    int main(int argc, char *argv[])
    {
        QApplication a(argc, argv);
        MainWindow w;
        w.show();
    //analyze the arguments
    //-b: use buidin player and if it does not exist use mpg123 shell to play files
    //
    //-t: test the player upon startup and exit
    //-s: use the following speaker ID for the test
    //-f: use the following file name and path
    //syntax: example:
    //                  -b : to use build in player
    //                  -t -s xx:xx:xx:xx:xx -f azanfile.mp3: to test upon startup playing a file
    
    
        bool useBuildInPlayer;
    
        QString x;
        for (int i=1; i<argc; i++)
        {
            x.append(argv[i]);
        }
        arguments << x.split("-");    arguments.removeFirst();
        qDebug() << arguments;
    
        if (arguments.indexOf("b")>=0) 
            useBuildInPlayer=true;
        else                            
            useBuildInPlayer=false;
    
        bool TestSpeaker = false;
        bool spkr=false; QString speaker;
        bool playfile=false;  QStringList testfiles;
        QString filestring;
        foreach (QString x, arguments)
        {
            if (x.left(1)=="s")
            {
                speaker = x.mid(1,-1); //remove the s from the beginning
                spkr=true;
            }
            if (x.left(1)=="f")
            {
                filestring=x.mid(1,-1);
                playfile=true;
                testfiles<<filestring;
            }
            if (x=="t")
                TestSpeaker = true;
        }
    
        if (TestSpeaker)
        {
            if (spkr)
            {
                qDebug() << "testing speaker "<< speaker;
            }
            else
            {
                qDebug() << "test argument needs speaker -s xx:xx:xx:xx:xx";
            }
            if (playfile)
            {
                qDebug() << "testing file "<< filestring;
            }
            else
            {
                qDebug() << "test file is missing";
            }
        }
        if (TestSpeaker && spkr && playfile)
        {
    
            if (useBuildInPlayer) //use build in player
            {
                qDebug() << "testing using buildin player";
    
            }
            else // use mpg123 shell
            {
                qDebug() << "testing using mpg123 shell";
    
            }
        }
    
    
        return a.exec();
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2021-07-16
      • 1970-01-01
      • 1970-01-01
      • 2015-03-04
      • 1970-01-01
      • 2019-12-06
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多