2017-03-21 29 views
0

是否可以使用編譯時安全從C++調用QML組件中的函數或更改屬性?使用編譯時安全從C++更改QML屬性

當前建議更改屬性是使用任何的以下功能:

QQmlProperty::write(object, "someNumber", 100); 
QMetaProperty::write(object, "someNumber", 100) 
object->setProperty("someNumber", 100); 

其中對象是QObject *到具有稱爲someNumber屬性QML組件。有關更多信息,請參閱http://doc.qt.io/qt-5/qtqml-cppintegration-interactqmlfromcpp.html

目前,我可以將"someNumber"更改爲"otherNumber",即使沒有任何編譯錯誤,即使沒有屬性otherNumber

甚至可以將數字100更改爲另一種類型,如"100"(字符串文本),而不會出現任何編譯錯誤,即無類型檢查。當您嘗試從C++調用QML組件中定義的函數時,會出現類似的問題。

我知道每個函數都會返回false,如果它們無法轉換類型或者屬性不存在,但我正在尋找編譯時錯誤檢查。

有沒有人有任何想法如何做到這一點?

+0

你需要一個額外的工具,AFAIK一個不存在。它不能成爲「普通」構建的一部分,因爲QML文件可以在運行時從磁盤加載,在這種情況下,沒有什麼能夠防止它們在編譯後被更改。但當然有* *可能是一個工具,它檢查C++代碼對當前的QML文件,並抱怨這樣的東西... – hyde

+0

@hyde QML文件不需要必須是JIT,因爲我們正在使用Qt Quick Compiler我認爲它可以設計成在鏈接器階段檢測到它。感謝評論。 –

+0

我認爲QML組件實例只使用動態屬性(即沒有具有非動態屬性的特定C++類,即使使用預編譯的QML,至少AFAIK也是如此)。 QML編譯器當然可以導出已知屬性的列表,然後可能有一個工具可以檢查列表中的C++代碼,但是AFAIK沒有人編寫過這樣的工具。 – hyde

回答

2

這完全依賴於C++類的object

如果你訪問它的聲明(頭),你可以投的具體類型和呼叫setter方法,而不是直接通過抽象屬性API會。

但是,從C++中設置QML對象屬性通常不是一個好主意,因爲您依賴於該對象來存在並且具有某種類型。

更好的方法是將數據作爲暴露給QML的對象的屬性提供,並處理QML端的分配。 在C++控制下,暴露對象的API是完整的,因此您可以始終使用各自的類型檢查調用setter。

0

這是不可能的,因爲Qt元對象系統依賴於QVariant,所以傳遞給它的所有數據都將首先轉換爲QVariant,然後才轉換回接收端。而對話是否失敗只會在運行時間內被發現。

但是,您可以創建一個C++類,在其中您將從C++修改數據並將其導出到QML。