[英]QML singletone style nested files
我已經為 QML 應用程序定義了樣式作為單獨的文件MyStyle.qml :
pragma Singleton
import QtQuick 2.15
import QtQml 2.15
QtObject {
property color color1: "#ffffff"
...
}
我想用另一個超分辨率文件修改它 >2k MyStyle_2k.qml 。
MyStyle{
color1: "#000000"
...
}
樣式在main.cpp中注冊:
QScreen* screen = QGuiApplication::primaryScreen();
auto screenHeight = screen->geometry().height();
QUrl styleUrl;
if(screenHeight > 1440){
styleUrl = QUrl("qrc:/gui/style/MyStyle_2k.qml");
}else{
styleUrl = QUrl("qrc:/gui/style/MyStyle.qml");
}
qmlRegisterSingletonType(styleUrl, "MyStyle", 1, 0, "MyStyle");
不幸的是,由於錯誤,它不起作用:
QQmlApplicationEngine 無法加載組件 qrc:/path/other_file.qml: Type MyStyle/MyStyle unavailable:9:1: Composite Singleton Type MyStyle 不可創建。
是否可以通過另一個文件修改 qml singleton?
您正在嘗試創建 singleton 類型的實例,這是不可能的,因此會出現錯誤消息。 如果你想創建樣式的實例並在 QML 中修改它,你需要使用 qmlRegisterType()。
或者你需要寫MyStyle.color1: "#000000"
來修改 singleton 的值。
編輯:您可以創建一個可實例化的樣式,如InternalMyStyle.qml
,在那里設置所有默認值,然后在MyStyle.qml
和MyStyle_2k.qml
中重新使用它,如下所示。 MyStyle.qml
和MyStyle_2k.qml
仍然是單例。
InternalMyStyle.qml
import QtQuick
QtObject {
property color color1: "#ff00ff"
}
我的風格.qml
pragma Singleton
import QtQuick
InternalMyStyle {}
我的風格_2k.qml
pragma Singleton
import QtQuick
InternalMyStyle {
color1: "#ff0000"
}
主.cpp
#include <QGuiApplication>
#include <QQmlApplicationEngine>
#include <QScreen>
int main(int argc, char *argv[])
{
QGuiApplication app(argc, argv);
QScreen *screen = QGuiApplication::primaryScreen();
auto screenHeight = screen->geometry().height();
QUrl styleUrl;
if (screenHeight > 1440)
styleUrl = QUrl(u"qrc:/untitledMyStyle/MyStyle_2k.qml"_qs);
else
styleUrl = QUrl(u"qrc:/untitledMyStyle/MyStyle.qml"_qs);
qmlRegisterSingletonType(styleUrl, "MyStyle", 1, 0, "MyStyle");
QQmlApplicationEngine engine;
const QUrl url(u"qrc:/untitledMyStyle/main.qml"_qs);
QObject::connect(
&engine,
&QQmlApplicationEngine::objectCreated,
&app,
[url](QObject *obj, const QUrl &objUrl) {
if (!obj && url == objUrl)
QCoreApplication::exit(-1);
},
Qt::QueuedConnection);
engine.load(url);
return app.exec();
}
CMakeLists.txt
...
qt_add_qml_module(appuntitledMyStyle
URI untitledMyStyle
VERSION 1.0
QML_FILES
main.qml
MyStyle.qml
MyStyle_2k.qml
InternalMyStyle.qml
)
...
您應該將這兩個文件命名為MyStyle.qml
,但按以下方式組織它們:
qrc:/gui/style/MyStyle.qml
qrc:/gui/style/+highres/MyStyle.qml
然后,您可以通過使用文件選擇器讓 Qt 知道要加載哪個版本的MyStyle.qml
。 請注意加號+
作為highres
前綴的用法。 這就是 Qt 基於默認或自定義文件選擇器組織文件覆蓋的方式。 將QT_FILE_SELECTOR
highres
變量,例如
QScreen* screen = QGuiApplication::primaryScreen();
auto screenHeight = screen->geometry().height();
if (screenHeight > 1440) {
qputenv("QT_FILE_SELECTOR", QString("highres").toUtf8());
}
此代碼需要在您的main.cpp
中盡早發生,因為QT_FILE_SELECTOR
將被檢查一次並且以后不會被重新檢查。
來自https://doc.qt.io/qt-6/qfileselector.html :
將從 QT_FILE_SELECTORS 環境變量中添加更多選擇器,設置后應該是一組逗號分隔的選擇器。 注意這個變量只會被讀取一次; 如果變量在應用程序運行時發生變化,選擇器可能不會更新。 初始選擇器集僅在首次使用時評估一次。
如果您不想使用QT_FILE_SELECTOR
環境變量,那么,為 QML 使用定義文件選擇器的正確方法是通過 QQmlFileSelector:
QScreen* screen = QGuiApplication::primaryScreen();
auto screenHeight = screen->geometry().height();
QQmlFileSelector* selector = null;
if (screenHeight > 1440) {
selector = new QQmlFileSelector(&engine);
selector->setExtraSelectors(QStringList() << QString("highres"));
}
使用QQmlFileSelector
的優點是您可以控制在運行時處於活動狀態的文件選擇器。 即您可以添加/刪除文件選擇器。 然而,這也意味着每次更改文件選擇器時,都必須強制重新加載已經加載的組件。 但是,它是以額外的編碼要求為代價的,因為您需要實例化 QQmlFileSelector 配置它,強制重新加載組件(這對於單例來說更難),並在程序退出時清理代碼(注意我沒有提供任何這些,因為如何實例化和發布 QQmlFileSelector 與您在應用程序中管理 memory 的方式一致,這取決於您。
有關更多詳細信息,您應該直接查閱文檔。
我找到的唯一可行的解決方案是使用單個文件作為 singleton Style.qml 和 state 組。
主.cpp
...
QScreen* screen = QGuiApplication::primaryScreen();
auto screenHeight = screen->geometry().height();
if(screenHeight > 1440){
engine.rootContext()->setContextProperty("StyleState", "2k");
}else{
engine.rootContext()->setContextProperty("StyleState", "");
}
...
State.qml
pragma Singleton
import QtQuick 2.15
import QtQml 2.15
QtObject {
id: root
property var widthA: 50
property var widthB: 100
property alias customStyle: customState.state // alias for call dircectly from qml
property var states: StateGroup{
id: customState
state: StyleState
states: [
State{
name: "2k"
PropertyChanges{
target: root
widthA: 100
widthB: 200
}
}
]
}
}
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.