Qt 我可以使用QCommandLineParser来确定GUI模式还是CLI模式?

Qt 我可以使用QCommandLineParser来确定GUI模式还是CLI模式?,qt,qt5,Qt,Qt5,我使用的其中一个程序有两种运行模式:GUI(图形用户界面)模式或CLI(命令行界面)模式。我们通过命令行参数确定要使用的模式(即,如果传递“-cli”,它将使用cli模式) 实例化的QApplication类型取决于使用的模式:QApplication应用于GUI模式,QCoreApplication应用于CLI模式,因为Qt的GUI部分不应实例化为CLI模式(因为CLI模式不使用或不需要它们) 我可以通过类似于以下的代码来实现这一点: std::unique_ptr<QCoreAppli

我使用的其中一个程序有两种运行模式:GUI(图形用户界面)模式或CLI(命令行界面)模式。我们通过命令行参数确定要使用的模式(即,如果传递“-cli”,它将使用cli模式)

实例化的QApplication类型取决于使用的模式:QApplication应用于GUI模式,QCoreApplication应用于CLI模式,因为Qt的GUI部分不应实例化为CLI模式(因为CLI模式不使用或不需要它们)

我可以通过类似于以下的代码来实现这一点:

std::unique_ptr<QCoreApplication> app = 
    (cliMode) ? std::make_unique<QCoreApplication>(argc, argv)
              : std::make_unique<QApplication>(argc, argv);

// Do some other stuff...

return app->exec();
好的:因此,在没有实例化QApplication对象的情况下,我不能再运行
--help
命令。我通过手动解析参数来查看
--help
是否为参数,暂时解决了这个问题。如果是,则继续实例化QCoreApplication,解析参数,然后退出

但后来我开始在MacOSX上发现一个神秘的错误。当我直接在OSX上运行可执行文件时,它会毫无问题地运行。但是,如果我试图双击
.app
文件或在终端中键入
$open myQtApplication.app
,我会得到这个神秘的错误:

LSOpenURLsWithRole() failed with error -10810 for the file ./myQtApplication.app
由于这是一个相当隐晦的错误,我花了很长时间才弄清楚这个错误是由QCommandLineParser在实例化QApplication对象之前被使用引起的

要解决此问题,我现在执行以下操作:

std::unique_ptr<QCoreApplication> app = 
    (cliMode) ? std::make_unique<QCoreApplication>(argc, argv)
              : std::make_unique<QApplication>(argc, argv);

// Do some other stuff...

return app->exec();
  • 手动分析
    main()
    函数开头的参数,以确定是否传递了
    --cli
  • 基于#1的结果实例化QApplication对象
  • 运行QCommandLineParser处理其余参数
  • 这不是一种非常干净的方法,因为我现在有两个参数解析器:一个用于确定是否传递了
    --cli
    ,其余用于其他参数

    有没有更好的或“适当的”方法来做到这一点


    我想主要的问题是:我可以使用QCommandLineParser来确定是实例化QCoreApplication对象还是QApplication对象吗?

    当然可以使用解析器,只要已经存在
    QCoreApplication
    。如果缺少
    --cli
    选项,您将切换到
    QApplication
    。回想一下,您可以完全控制应用程序对象的生命周期

    这适用于Windows和OS X上的Qt 4.8和5.11:

    // https://github.com/KubaO/stackoverflown/tree/master/questions/app-cli-gui-switch-52649458
    #include <QtGui>
    #if QT_VERSION >= QT_VERSION_CHECK(5, 0, 0)
    #include <QtWidgets>
    #endif
    
    struct Options {
       bool cli;
    };
    
    static Options parseOptionsQt4() {
       Options opts = {};
       for (auto arg : QCoreApplication::arguments().mid(1)) {
          if (arg == "--cli")
             opts.cli = true;
          else
             qFatal("Unknown option %s", arg.toLocal8Bit().constData());
       }
       return opts;
    }
    
    static Options parseOptions() {
       if (QT_VERSION < QT_VERSION_CHECK(5, 0, 0)) return parseOptionsQt4();
    #if QT_VERSION >= QT_VERSION_CHECK(5, 0, 0)
       Options opts = {};
       QCommandLineParser parser;
       QCommandLineOption cliOption("cli", "Start in command line mode.");
       parser.addOption(cliOption);
       parser.process(*qApp);
       opts.cli = parser.isSet(cliOption);
       return opts;
    #endif
    }
    
    int main(int argc, char *argv[]) {
       QScopedPointer<QCoreApplication> app(new QCoreApplication(argc, argv));
       auto options = parseOptions();
       if (options.cli) {
          qDebug() << "cli";
       } else {
          qDebug() << "gui";
          app.reset();
          app.reset(new QApplication(argc, argv));
       }
    
       if (qobject_cast<QApplication *>(qApp))
          QMessageBox::information(nullptr, "Hello", "Hello, World!");
       QMetaObject::invokeMethod(qApp, "quit", Qt::QueuedConnection);
       return app->exec();
    }
    
    //https://github.com/KubaO/stackoverflown/tree/master/questions/app-cli-gui-switch-52649458
    #包括
    #如果QT\u版本>=QT\u版本检查(5,0,0)
    #包括
    #恩迪夫
    结构选项{
    布尔克利;
    };
    静态选项parseOptionsQt4(){
    选项opts={};
    for(自动参数:QCoreApplication::arguments().mid(1)){
    如果(arg==“--cli”)
    opts.cli=true;
    其他的
    qFatal(“未知选项%s”,参数toLocal8Bit().constData());
    }
    返回选项;
    }
    静态选项parseOptions(){
    if(QT_VERSION=QT\u版本检查(5,0,0)
    选项opts={};
    QCommandLineParser;
    QCommandLineOption cliOption(“cli”,“在命令行模式下启动”);
    addOption(cliOption);
    进程(*qApp);
    opts.cli=parser.isSet(cliOption);
    返回选项;
    #恩迪夫
    }
    int main(int argc,char*argv[]){
    QScopedPointer应用程序(新的qcore应用程序(argc,argv));
    自动选项=解析选项();
    if(options.cli){
    
    qDebug()当然,您可以使用解析器-只要
    QCoreApplication
    已经存在。如果缺少
    --cli
    选项,您将切换到
    QApplication
    。记住,您可以完全控制应用程序对象的生存期

    这适用于Windows和OS X上的Qt 4.8和5.11:

    // https://github.com/KubaO/stackoverflown/tree/master/questions/app-cli-gui-switch-52649458
    #include <QtGui>
    #if QT_VERSION >= QT_VERSION_CHECK(5, 0, 0)
    #include <QtWidgets>
    #endif
    
    struct Options {
       bool cli;
    };
    
    static Options parseOptionsQt4() {
       Options opts = {};
       for (auto arg : QCoreApplication::arguments().mid(1)) {
          if (arg == "--cli")
             opts.cli = true;
          else
             qFatal("Unknown option %s", arg.toLocal8Bit().constData());
       }
       return opts;
    }
    
    static Options parseOptions() {
       if (QT_VERSION < QT_VERSION_CHECK(5, 0, 0)) return parseOptionsQt4();
    #if QT_VERSION >= QT_VERSION_CHECK(5, 0, 0)
       Options opts = {};
       QCommandLineParser parser;
       QCommandLineOption cliOption("cli", "Start in command line mode.");
       parser.addOption(cliOption);
       parser.process(*qApp);
       opts.cli = parser.isSet(cliOption);
       return opts;
    #endif
    }
    
    int main(int argc, char *argv[]) {
       QScopedPointer<QCoreApplication> app(new QCoreApplication(argc, argv));
       auto options = parseOptions();
       if (options.cli) {
          qDebug() << "cli";
       } else {
          qDebug() << "gui";
          app.reset();
          app.reset(new QApplication(argc, argv));
       }
    
       if (qobject_cast<QApplication *>(qApp))
          QMessageBox::information(nullptr, "Hello", "Hello, World!");
       QMetaObject::invokeMethod(qApp, "quit", Qt::QueuedConnection);
       return app->exec();
    }
    
    //https://github.com/KubaO/stackoverflown/tree/master/questions/app-cli-gui-switch-52649458
    #包括
    #如果QT\u版本>=QT\u版本检查(5,0,0)
    #包括
    #恩迪夫
    结构选项{
    布尔克利;
    };
    静态选项parseOptionsQt4(){
    选项opts={};
    for(自动参数:QCoreApplication::arguments().mid(1)){
    如果(arg==“--cli”)
    opts.cli=true;
    其他的
    qFatal(“未知选项%s”,参数toLocal8Bit().constData());
    }
    返回选项;
    }
    静态选项parseOptions(){
    if(QT_VERSION=QT\u版本检查(5,0,0)
    选项opts={};
    QCommandLineParser;
    QCommandLineOption cliOption(“cli”,“在命令行模式下启动”);
    addOption(cliOption);
    进程(*qApp);
    opts.cli=parser.isSet(cliOption);
    返回选项;
    #恩迪夫
    }
    int main(int argc,char*argv[]){
    QScopedPointer应用程序(新的qcore应用程序(argc,argv));
    自动选项=解析选项();
    if(options.cli){
    
    qDebug()Qt doc中有一个示例:。它看起来与您的非常相似。可能是,最好不使用任何语法以独占方式解析
    --cli
    ,因为后者可能依赖于前者。(第一个链接中的Qt doc.sample代码就是这样做的。)如果有疑问,您甚至可以删除此
    --cli
    参数。因此,
    QApplication
    可能永远看不到它。这可以通过
    --argc;
    和一个简单的循环
    argv[i]=argv[i+1]来完成
    从找到
    --cli
    i
    开始。Qt doc中有一个示例。它看起来与您的非常相似。可能是,最好不使用任何语法,而只解析
    --cli
    ,因为后者可能依赖于前者。(第一个链接中的Qt doc.sample代码就是这样做的。)如果有疑问,您甚至可以删除这个
    --cli
    参数。因此,
    QApplication
    可能永远看不到它。这可以通过
    --argc;
    和一个简单的循环
    argv[i]=argv[i+1]
    来完成,从您所选择的
    i
    开始