Using an external .json file for configuration
-
@Clone45 You should use https://doc.qt.io/qt-6/qstandardpaths.html#locate with QStandardPaths::AppConfigLocation to find the location for configuration of your application in a platform independent way. Then put your json file from res there if it is not yet done.
@jsulm I've run into some additional issues:
18:40:28: Starting C:\Users\clone\Documents\build-TinyBonsai-Desktop_Qt_6_5_0_MinGW_64_bit-Debug\TinyBonsai.exe...
Resource files:
":/qpdf"
":/qt-project.org"
Config file path: "C:/Users/clone/Documents/build-TinyBonsai-Desktop_Qt_6_5_0_MinGW_64_bit-Debug/module_types.json"
Could not copy file from ":/res/module_types.json" to "C:/Users/clone/AppData/Local/TinyBonsai\module_types.json"
Error: "Cannot open :/res/module_types.json for input"I'm having trouble with my source resource file not being found. I've spent some time trying to figure this out on my own, but a little bit of advice would go a long way!
-
@jsulm I've run into some additional issues:
18:40:28: Starting C:\Users\clone\Documents\build-TinyBonsai-Desktop_Qt_6_5_0_MinGW_64_bit-Debug\TinyBonsai.exe...
Resource files:
":/qpdf"
":/qt-project.org"
Config file path: "C:/Users/clone/Documents/build-TinyBonsai-Desktop_Qt_6_5_0_MinGW_64_bit-Debug/module_types.json"
Could not copy file from ":/res/module_types.json" to "C:/Users/clone/AppData/Local/TinyBonsai\module_types.json"
Error: "Cannot open :/res/module_types.json for input"I'm having trouble with my source resource file not being found. I've spent some time trying to figure this out on my own, but a little bit of advice would go a long way!
-
@jsulm Thanks so much for sticking with me.
Here is my resources.qrc file:
<RCC> <qresource prefix="/"> <file>res/module_types.json</file> </qresource> </RCC>
Here is my make CMakeLists.txt file:
cmake_minimum_required(VERSION 3.5) project(TinyBonsai VERSION 0.1 LANGUAGES CXX) find_package(Qt6 COMPONENTS Core Widgets REQUIRED) qt6_add_resources(RESOURCE_FILES resources.qrc) set(CMAKE_AUTOUIC ON) set(CMAKE_AUTOMOC ON) set(CMAKE_AUTORCC ON) set(CMAKE_CXX_STANDARD 17) set(CMAKE_CXX_STANDARD_REQUIRED ON) find_package(QT NAMES Qt6 Qt5 REQUIRED COMPONENTS Widgets) find_package(Qt${QT_VERSION_MAJOR} REQUIRED COMPONENTS Widgets) set(PROJECT_SOURCES main.cpp mainwindow.cpp mainwindow.h mainwindow.ui ModulesListModel.h module.h module.cpp moduletypes.h moduletypes.cpp moduletypesmanager.h moduletypesmanager.cpp nodecanvas.h nodecanvas.cpp port.h port.cpp defines.h connection.h connection.cpp ) if(${QT_VERSION_MAJOR} GREATER_EQUAL 6) qt_add_executable(TinyBonsai MANUAL_FINALIZATION ${PROJECT_SOURCES} ) # Define target properties for Android with Qt 6 as: # set_property(TARGET TinyBonsai APPEND PROPERTY QT_ANDROID_PACKAGE_SOURCE_DIR # ${CMAKE_CURRENT_SOURCE_DIR}/android) # For more information, see https://doc.qt.io/qt-6/qt-add-executable.html#target-creation else() if(ANDROID) add_library(TinyBonsai SHARED ${PROJECT_SOURCES} ) # Define properties for Android with Qt 5 after find_package() calls as: # set(ANDROID_PACKAGE_SOURCE_DIR "${CMAKE_CURRENT_SOURCE_DIR}/android") else() add_executable(TinyBonsai ${PROJECT_SOURCES} ) endif() endif() target_include_directories(TinyBonsai PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}) target_link_libraries(TinyBonsai PRIVATE Qt${QT_VERSION_MAJOR}::Widgets) set_target_properties(TinyBonsai PROPERTIES MACOSX_BUNDLE_GUI_IDENTIFIER my.example.com MACOSX_BUNDLE_BUNDLE_VERSION ${PROJECT_VERSION} MACOSX_BUNDLE_SHORT_VERSION_STRING ${PROJECT_VERSION_MAJOR}.${PROJECT_VERSION_MINOR} MACOSX_BUNDLE TRUE WIN32_EXECUTABLE TRUE ) install(TARGETS TinyBonsai BUNDLE DESTINATION . LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR}) if(QT_VERSION_MAJOR EQUAL 6) qt_finalize_executable(TinyBonsai) endif()
And here's the code that I'm working with:
int main(int argc, char *argv[]) { QApplication a(argc, argv); // This is not compiling: // Q_INIT_RESOURCE(resources); // List all resource files QDir resourceDir(":/"); QStringList resourceFiles = resourceDir.entryList(); qDebug() << "Resource files:"; for (const QString &fileName : resourceFiles) { QFileInfo fileInfo(":/"+fileName); qDebug() << fileInfo.absoluteFilePath(); } // Fist thing, copy the configuration file to the config location if it doesn't exist QString configFileName = "module_types.json"; QString configFilePath = QStandardPaths::locate(QStandardPaths::AppConfigLocation, configFileName); qDebug() << "Config file path: " << configFilePath; QString sourceFilePath = ":/res/" + configFileName; QString targetDirectory = QStandardPaths::writableLocation(QStandardPaths::AppConfigLocation); // Create the target directory if it doesn't exist QDir dir; if (!dir.exists(targetDirectory)) { dir.mkpath(targetDirectory); // Create the target directory if it does not exist }
Ah, and here's where the configuration file is that I wish to copy.
-
@jsulm Thanks so much for sticking with me.
Here is my resources.qrc file:
<RCC> <qresource prefix="/"> <file>res/module_types.json</file> </qresource> </RCC>
Here is my make CMakeLists.txt file:
cmake_minimum_required(VERSION 3.5) project(TinyBonsai VERSION 0.1 LANGUAGES CXX) find_package(Qt6 COMPONENTS Core Widgets REQUIRED) qt6_add_resources(RESOURCE_FILES resources.qrc) set(CMAKE_AUTOUIC ON) set(CMAKE_AUTOMOC ON) set(CMAKE_AUTORCC ON) set(CMAKE_CXX_STANDARD 17) set(CMAKE_CXX_STANDARD_REQUIRED ON) find_package(QT NAMES Qt6 Qt5 REQUIRED COMPONENTS Widgets) find_package(Qt${QT_VERSION_MAJOR} REQUIRED COMPONENTS Widgets) set(PROJECT_SOURCES main.cpp mainwindow.cpp mainwindow.h mainwindow.ui ModulesListModel.h module.h module.cpp moduletypes.h moduletypes.cpp moduletypesmanager.h moduletypesmanager.cpp nodecanvas.h nodecanvas.cpp port.h port.cpp defines.h connection.h connection.cpp ) if(${QT_VERSION_MAJOR} GREATER_EQUAL 6) qt_add_executable(TinyBonsai MANUAL_FINALIZATION ${PROJECT_SOURCES} ) # Define target properties for Android with Qt 6 as: # set_property(TARGET TinyBonsai APPEND PROPERTY QT_ANDROID_PACKAGE_SOURCE_DIR # ${CMAKE_CURRENT_SOURCE_DIR}/android) # For more information, see https://doc.qt.io/qt-6/qt-add-executable.html#target-creation else() if(ANDROID) add_library(TinyBonsai SHARED ${PROJECT_SOURCES} ) # Define properties for Android with Qt 5 after find_package() calls as: # set(ANDROID_PACKAGE_SOURCE_DIR "${CMAKE_CURRENT_SOURCE_DIR}/android") else() add_executable(TinyBonsai ${PROJECT_SOURCES} ) endif() endif() target_include_directories(TinyBonsai PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}) target_link_libraries(TinyBonsai PRIVATE Qt${QT_VERSION_MAJOR}::Widgets) set_target_properties(TinyBonsai PROPERTIES MACOSX_BUNDLE_GUI_IDENTIFIER my.example.com MACOSX_BUNDLE_BUNDLE_VERSION ${PROJECT_VERSION} MACOSX_BUNDLE_SHORT_VERSION_STRING ${PROJECT_VERSION_MAJOR}.${PROJECT_VERSION_MINOR} MACOSX_BUNDLE TRUE WIN32_EXECUTABLE TRUE ) install(TARGETS TinyBonsai BUNDLE DESTINATION . LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR}) if(QT_VERSION_MAJOR EQUAL 6) qt_finalize_executable(TinyBonsai) endif()
And here's the code that I'm working with:
int main(int argc, char *argv[]) { QApplication a(argc, argv); // This is not compiling: // Q_INIT_RESOURCE(resources); // List all resource files QDir resourceDir(":/"); QStringList resourceFiles = resourceDir.entryList(); qDebug() << "Resource files:"; for (const QString &fileName : resourceFiles) { QFileInfo fileInfo(":/"+fileName); qDebug() << fileInfo.absoluteFilePath(); } // Fist thing, copy the configuration file to the config location if it doesn't exist QString configFileName = "module_types.json"; QString configFilePath = QStandardPaths::locate(QStandardPaths::AppConfigLocation, configFileName); qDebug() << "Config file path: " << configFilePath; QString sourceFilePath = ":/res/" + configFileName; QString targetDirectory = QStandardPaths::writableLocation(QStandardPaths::AppConfigLocation); // Create the target directory if it doesn't exist QDir dir; if (!dir.exists(targetDirectory)) { dir.mkpath(targetDirectory); // Create the target directory if it does not exist }
Ah, and here's where the configuration file is that I wish to copy.
@Clone45 said in Using an external .json file for configuration:
qt6_add_resources(RESOURCE_FILES resources.qrc)
What should this do?
-
@Clone45 said in Using an external .json file for configuration:
qt6_add_resources(RESOURCE_FILES resources.qrc)
What should this do?
@Christian-Ehrlicher Sorry Christian, I'm not quite following you. What I'm trying to achieve is include an external .json file along with my application which will be loaded by the application when it runs. The json file should be editable by the users.
It's completely possible that I'm going down the wrong path? It looks like qt_add_resources adds an external data file to the executable, but that doesn't seem to match my needs.
Any advice will be much appreciated!
-
@Christian-Ehrlicher Sorry Christian, I'm not quite following you. What I'm trying to achieve is include an external .json file along with my application which will be loaded by the application when it runs. The json file should be editable by the users.
It's completely possible that I'm going down the wrong path? It looks like qt_add_resources adds an external data file to the executable, but that doesn't seem to match my needs.
Any advice will be much appreciated!
@Clone45 said in Using an external .json file for configuration:
? It looks like qt_add_resources adds an external data file to the executable, but that doesn't seem to match my needs.
It does exactly what you want but you're using it wrong. The link I gave you shows the correct usage. You should add RESOURCE_FILES somewhere as explained there.
-
@Clone45 said in Using an external .json file for configuration:
? It looks like qt_add_resources adds an external data file to the executable, but that doesn't seem to match my needs.
It does exactly what you want but you're using it wrong. The link I gave you shows the correct usage. You should add RESOURCE_FILES somewhere as explained there.
@Christian-Ehrlicher Apologies Christian. I appreciate the help.
I have the following in my CMakeLists.txt file:
cmake_minimum_required(VERSION 3.5) project(TinyBonsai VERSION 0.1 LANGUAGES CXX) find_package(Qt6 COMPONENTS Core Widgets REQUIRED) # # Here's where I have added the resource files: # ↓↓↓↓ qt6_add_resources(RESOURCE_FILES resources.qrc) set(CMAKE_AUTOUIC ON) set(CMAKE_AUTOMOC ON) set(CMAKE_AUTORCC ON)
Is that what you're referring to? Is so, that's already in place, but I'm still having issues.
-
@Clone45 said in Using an external .json file for configuration:
? It looks like qt_add_resources adds an external data file to the executable, but that doesn't seem to match my needs.
It does exactly what you want but you're using it wrong. The link I gave you shows the correct usage. You should add RESOURCE_FILES somewhere as explained there.
@Christian-Ehrlicher said in Using an external .json file for configuration:
You should add RESOURCE_FILES somewhere as explained there.
Why don't yiu just follow the documentation and add the output of qt_add_resources() to qt_add_executable() as written in the example?
qt_add_executable(TinyBonsai MANUAL_FINALIZATION ${PROJECT_SOURCES} ${RESOURCE_FILES } )
How should cmake know otherwise where to add the generated file to?
-
@Christian-Ehrlicher said in Using an external .json file for configuration:
You should add RESOURCE_FILES somewhere as explained there.
Why don't yiu just follow the documentation and add the output of qt_add_resources() to qt_add_executable() as written in the example?
qt_add_executable(TinyBonsai MANUAL_FINALIZATION ${PROJECT_SOURCES} ${RESOURCE_FILES } )
How should cmake know otherwise where to add the generated file to?
@Christian-Ehrlicher said in Using an external .json file for configuration:
@Christian-Ehrlicher said in Using an external .json file for configuration:
You should add RESOURCE_FILES somewhere as explained there.
Why don't yiu just follow the documentation and add the output of qt_add_resources() to qt_add_executable() as written in the example?
qt_add_executable(TinyBonsai MANUAL_FINALIZATION ${PROJECT_SOURCES} ${RESOURCE_FILES } )
How should cmake know otherwise where to add the generated file to?Thank you for all of your help. It's working now, after I added the resource files to qt_add_executable. I had a little bit of trouble with overwriting the configuration file because of permissions issues, but I was able to work around that by setting the permissions explicitly in the code.
Cheers,
Bret -
@Christian-Ehrlicher Apologies Christian. I appreciate the help.
I have the following in my CMakeLists.txt file:
cmake_minimum_required(VERSION 3.5) project(TinyBonsai VERSION 0.1 LANGUAGES CXX) find_package(Qt6 COMPONENTS Core Widgets REQUIRED) # # Here's where I have added the resource files: # ↓↓↓↓ qt6_add_resources(RESOURCE_FILES resources.qrc) set(CMAKE_AUTOUIC ON) set(CMAKE_AUTOMOC ON) set(CMAKE_AUTORCC ON)
Is that what you're referring to? Is so, that's already in place, but I'm still having issues.
@Clone45 said in Using an external .json file for configuration:
after I added the resource files to qt_add_executable
set(CMAKE_AUTORCC ON)
Yes, this is also possible because you enabled AUTORCC.