Qt 我可以使用QCommandLineParser来确定GUI模式还是CLI模式?
我使用的其中一个程序有两种运行模式:GUI(图形用户界面)模式或CLI(命令行界面)模式。我们通过命令行参数确定要使用的模式(即,如果传递“-cli”,它将使用cli模式) 实例化的QApplication类型取决于使用的模式:QApplication应用于GUI模式,QCoreApplication应用于CLI模式,因为Qt的GUI部分不应实例化为CLI模式(因为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
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
--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
开始