在编写一个包含 gui qt
的程序时,我偶然发现了一个问题,可以用下面的最少代码重现:
#include <iostream>
#include <QApplication>
#include <QSettings>
using namespace std;
int main(int argc, char ** argv) {
QApplication *app;
{
int tmp_argc = argc;
app = new QApplication(tmp_argc, argv);
}
QSettings settings("testvendor");
cout<<"Num of arguments: "<<app->arguments().count()<<std::endl;
return 0;
}
运行会导致核心转储(在对 QApplication::参数的调用中)或Num of arguments: 0
这显然是错误的。
如果我使用 app = new QApplication(argc, argv)
实例化app
(使用带有参数计数的无作用域变量)或删除settings
的声明/定义 - 程序输出按预期Num of arguments: 1
(这些更改中的任何一个就足够了)。
我在Ubuntu
上使用Qt 5.5
,该项目是基于cmake
的,内容CMakeLists.txt
:
cmake_minimum_required(VERSION 3.3)
project(qtest)
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++11")
set(CMAKE_PREFIX_PATH /opt/Qt/6.5.1/gcc_64/)
find_package(Qt5Widgets REQUIRED)
set(SOURCE_FILES main.cpp)
add_executable(qtest ${SOURCE_FILES})
target_link_libraries(qtest Qt5::Widgets)
警告:argc 和 argv 引用的数据必须在 QApplication 对象的整个生存期内保持有效。此外,argc 必须大于零,并且 argv 必须至少包含一个有效字符串。
来自 QT 5 文档。强调我的。
tmp_argc
超出了范围。
QApplication *app;
{
int tmp_argc = argc;
app = new QApplication(tmp_argc, argv);
} <-- BOOM!
以下是修复它的方法,符合构造函数文档中给出的要求QCoreApplication
:
// https://github.com/KubaO/stackoverflown/tree/master/questions/app-args-35566459
#include <QtCore>
#include <memory>
std::unique_ptr<QCoreApplication> newApp(int & argc, char ** argv) {
return std::unique_ptr<QCoreApplication>(new QCoreApplication{argc, argv});
}
int main(int argc, char ** argv) {
std::unique_ptr<QCoreApplication> app(newApp(argc, argv));
QSettings settings{"testvendor"};
qDebug() << "Num of arguments: " << app->arguments().count();
}