Qt6.5的QML项目中,我发现QML引用资源文件并不像QtWidgets项目那样直接。
在QtWidgets的项目中,我们一般是创建.qrc资源文件,然后创建前缀/new/prefix,再往该前缀中添加一个图片文件,比如:test.png。
最终,我们就可以使用qrc:/new/prefix/test.png这样的方式来引用这个图片文件。
但在QML中,情况发生了改变。
当我们创建一个.qrc文件时,该文件会在CMakeLists.txt被引用:
...
qt_add_qml_module(appuntitled
URI untitled
VERSION 1.0
QML_FILES Main.qml
RESOURCES res.qrc
)
...
而QtWidgets项目中,res.qrc将会被添加到:
qt_add_executable(appuntitled
main.cpp
${PROJECT_SOURCES}
res.qrc
)
添加到qt_add_qml_module()的res.qrc能够被QtWidgets的代码引用,不能够被QML引用。反过来也是同样的道理。经过我们实验,QtWidgets和QML应该分别工作在两个不同的资源下,二者是无法通过修改CMakeLists.txt来达成资源文件互通的效果。
假设我们在QML项目中创建了一个res.qrc并往其中添加了以下内容:
<RCC>
<qresource prefix="/">
<file>images/background.jpg</file>
</qresource>
</RCC>
在QML代码中使用"qrc:/images/background.jpg",你会发现QML无法打开这个图片。
为什么呢?因为二者不在同一个资源文件中:
appVideoPlatform_raw_qml_0.qrc是QML的运行环境,而res.qrc并不在其中。即使我们将res.qrc的前缀改成/qt/qml/VideoPlatform也不能改变二者不在同一资源文件的事实。
有的时候,QML项目中的:
engine.loadFromModule("项目名", "Main");
会报错,它说你的"项目名"模块它找不到,这时你可将该语句替换成:
engine.load(QUrl(u"qrc:/qt/qml/项目名/Main.qml"_qs);
直接定位最终的Main.qml。但请注意,不同的Qt版本,资源文件的前缀可能是不一样的,因此这需要根据版本进行相应的修改(直接看它怎样生成的)。
既然添加res.qrc无法引用图片文件,那该怎样才能够引用图片文件呢?
直接将图片添加到qml中,例如:
qt_add_qml_module(appVideoPlatform
URI VideoPlatform
VERSION 1.0
QML_FILES Main.qml
RESOURCES images/login_background.jpg
)
然后,使用/qt/qml/你的项目名/images/login_background.jpg来引用,这会导致引用图片的代码和Qt版本强相关(因为不同的Qt版本QML所在的资源文件前缀不同)。