引自:https://doc.qt.io/qt-5/qtqml-syntax-directoryimports.html
模塊由模塊定義qmldir文件定義。每個模塊都有一個關聯的類型名稱空間,它是模塊的標識符。模塊可以提供QML對象類型(由QML文檔或通過C ++插件定義)和JavaScript資源,並且可以由客戶端導入。
要定義模塊,開發人員應將模塊中的各種QML文檔,JavaScript資源和C ++插件收集到一個目錄中,並編寫一個適當的模塊定義qmldir文件,該文件也應放置在該目錄中。然後可以將該目錄作爲模塊安裝到QML導入路徑中。
請注意,定義模塊不是共享項目中常見QML類型的唯一方法- 爲此,也可以使用簡單的QML文檔目錄導入。
引自:https://doc.qt.io/qt-5/qtqml-modules-qmldir.html
模塊定義qmldir文件
有兩種不同類型的qmldir
文件:
- QML文檔目錄
- QML模塊定義文件
QML模塊定義文件
一個qmldir
文件是一個包含以下命令的純文本文件:
/*聲明模塊的模塊標識符。<ModuleIdentifier>是模塊的(點分URI表示法)標識符
,必須與模塊的安裝路徑匹配。所述模塊標識符的指令必須是文件的第一行。*/
module <ModuleIdentifier>
例:module ExampleModule
/*聲明一個對象
[singleton]可選的。用於聲明單例類型。
<TypeName> 是可用的類型
<InitialVersion> 是要爲其提供類型的模塊版本
<File> 是定義類型的QML文件的(相對)文件名
*/
[singleton] <TypeName> <InitialVersion> <File>
/*
qmldir文件中可能存在零個或多個對象類型聲明,但是每種對象類型在模塊的任何特定版本中都必須具有唯一的類型名稱。
注意:要聲明singleton類型,定義該類型的QML文件必須包含該pragma Singleton語句。
*/
//singleton例子
//Style.qml with custom singleton type definition
pragma Singleton //單例
import QtQuick 2.0
QtObject {
property int textSize: 20
property color textColor: "green"
}
//--------------------qmldir------------------------------
// qmldir declaring the singleton type
module CustomStyles
singleton Style 1.0 Style.qml //聲明Style類型
//--------------------use------------------------------
// singleton type in use
import QtQuick 2.0
import CustomStyles 1.0
Text {
font.pixelSize: Style.textSize
color: Style.textColor
text: "Hello World"
}
/*
聲明模塊中的對象類型,但該對象類型不應提供給模塊用戶。
qmldir文件中可能存在零個或多個內部對象類型聲明
*/
internal <TypeName> <File>
//例:
internal MyPrivateType MyPrivateType.qml
/*
聲明模塊可以使用的JavaScript文件。該資源將通過具有指定版本號的指定標識符提供。
qmldir文件中可能存在零個或多個JavaScript資源聲明,但是每個JavaScript資源在模塊的任何特定版本中都必須具有唯一的標識符。
*/
<ResourceIdentifier> <InitialVersion> <File>
//例
MyScript 1.0 MyScript.js
/*
聲明該模塊可以使用的插件。
<Name>是插件庫名稱。這通常與插件二進制文件的文件名不同,後者取決於平臺。例如,該庫MyAppTypes將libMyAppTypes.so在Linux和MyAppTypes.dllWindows上生成。
<Path> (可選)指定以下任一項:
包含插件文件的目錄的絕對路徑,或者
從包含qmldir文件的目錄到包含插件文件的目錄的相對路徑。
默認情況下,引擎在包含qmldir文件的目錄中搜索插件庫。(可使用QQmlEngine :: pluginPathList()查詢插件搜索路徑,並使用QQmlEngine :: addPluginPath()修改插件搜索路徑。)
qmldir文件中可能存在零個或多個C ++插件聲明,但是由於插件加載是一項相對昂貴的操作,建議客戶最多指定一個插件。
*/
plugin <Name> [<Path>]
//例:
plugin MyPluginLibrary
/*
提供模塊使用的C ++插件的類名。
對於依賴於C ++插件的其他QML模塊,需要附加此功能的信息。沒有此信息,使用靜態鏈接構建的Qt Quick應用程序將無法解析模塊導入。
*/
classname <C++ plugin class>
/*
聲明模塊的類型描述文件,Qt Creator等QML工具可以讀取該模塊的類型描述文件,以訪問有關模塊插件定義的類型的信息。<File>是文件的(相對)包含.qmltypes後綴的文件名。一般由qmlplugindump工具生成
*/
typeinfo <File>
//例
typeinfo mymodule.qmltypes
/*
聲明此模塊依賴於另一個模塊
僅在隱藏依賴項的情況下才需要此聲明:例如,當一個模塊的C ++代碼用於(可能有條件地)加載QML時,QML則依賴於其他模塊。在這種情況下,必須depends聲明以將其他模塊包含在應用程序包中。
*/
depends <ModuleIdentifier> <InitialVersion>
/*
註釋
*/
# <Comment>
/*
如果插件受Qt Quick Designer支持,請設置此屬性。默認情況下,將不支持該插件。
Qt Quick Designer支持的插件必須經過正確測試。
*/
designersupported
qmldir
文件中的每個命令必須位於單獨的行上。
Example of a qmldir File
module ExampleModule #定義了一個名爲ExampleModule的模塊
#CustomButton在模塊的版本2.0和2.1中定義了QML對象類型,每種版本的實現方式不同
CustomButton 2.0 CustomButton20.qml
CustomButton 2.1 CustomButton21.qml
#指定了客戶端導入模塊時引擎必須加載的插件,並且該插件可以向QML類型系統註冊各種C ++定義的類型在類Unix系統上,QML引擎嘗試libexamplemodule.so作爲QQmlExtensionPlugin加載,而在Windows上,它examplemodule.dll作爲QQmlExtensionPlugin加載。
plugin examplemodule
#最後,該qmldir文件指定一個JavaScript資源,僅在導入模塊的版本2.0或更高版本(在相同的主版本下)時可用。
MathFunctions 2.0 mathfuncs.js
/*如果將模塊安裝到QML導入路徑中,則客戶端可以通過以下方式導入和使用該模塊:*/
import QtQuick 2.0
import ExampleModule 2.1
Rectangle {
width: 400
height: 400
color: "lightsteelblue"
CustomButton {
color: "gray"
text: "Click Me!"
onClicked: MathFunctions.generateRandom() > 10 ? color = "red" : color = "gray";
}
}
#CustomButton上面使用的類型將來自CustomButton21.qml文件中指定的定義,並且由MathFunctions標識符標識的JavaScript資源將在mathfuncs.js文件中定義。
編寫qmltypes文件
QML模塊可以在其qmldir
文件中引用一個或多個類型信息文件。這些通常具有.qmltypes
擴展名,並且可以由外部工具讀取以獲取有關插件中定義的類型的信息。
因此,qmltypes文件對QML模塊的功能沒有影響。它們的唯一用途是允許Qt Creator之類的工具爲模塊用戶提供代碼完成,錯誤檢查和其他功能。
任何使用插件的模塊都應附帶一個類型描述文件。
爲模塊創建qmltypes文件的最佳方法使用Qt隨附的工具qmlplugindump
生成該文件。
示例:如果模塊位於中/tmp/imports/My/Module
,則可以運行
qmlplugindump My.Module 1.0 /tmp/imports > /tmp/imports/My/Module/mymodule.qmltypes
生成完成後需要在qmldir中添加
typeinfo mymodule.qmltypes
qmltype文件例子
mport QtQuick.tooling 1.1
// There always is a single Module object that contains all
// Component objects.
Module {
// A Component object directly corresponds to a type exported
// in a plugin with a call to qmlRegisterType.
Component {
// The name is a unique identifier used to refer to this type.
// It is recommended you simply use the C++ type name.
name: "QQuickAbstractAnimation"
// The name of the prototype Component.
prototype: "QObject"
// The name of the default property.
defaultProperty: "animations"
// The name of the type containing attached properties
// and methods.
attachedType: "QQuickAnimationAttached"
// The list of exports determines how a type can be imported.
// Each string has the format "URI/Name version" and matches the
// arguments to qmlRegisterType. Usually types are only exported
// once, if at all.
// If the "URI/" part of the string is missing that means the
// type should be put into the package defined by the URI the
// module was imported with.
// For example if this module was imported with 'import Foo 4.8'
// the Animation object would be found in the package Foo and
// QtQuick.
exports: [
"Animation 4.7",
"QtQuick/Animation 1.0"
]
// The meta object revisions for the exports specified in 'exports'.
// Describes with revisioned properties will be visible in an export.
// The list must have exactly the same length as the 'exports' list.
// For example the 'animations' propery described below will only be
// available through the QtQuick/Animation 1.0 export.
exportMetaObjectRevisions: [0, 1]
Property {
name: "animations";
type: "QQuickAbstractAnimation"
// defaults to false, whether this property is read only
isReadonly: true
// defaults to false, whether the type of this property was a pointer in C++
isPointer: true
// defaults to false: whether the type actually is a QQmlListProperty<type>
isList: true
// defaults to 0: the meta object revision that introduced this property
revision: 1
}
Property { name: "loops"; type: "int" }
Property { name: "name"; type: "string" }
Property { name: "loopsEnum"; type: "Loops" }
Enum {
name: "Loops"
values: {
"Infinite": -2,
"OnceOnly": 1
}
}
// Signal and Method work the same way. The inner Parameter
// declarations also support the isReadonly, isPointer and isList
// attributes which mean the same as for Property
Method { name: "restart" }
Signal { name: "started"; revision: 2 }
Signal {
name: "runningChanged"
Parameter { type: "bool" }
Parameter { name: "foo"; type: "bool" }
}
}
}
導入QML文檔目錄
https://doc.qt.io/qt-5/qtqml-syntax-directoryimports.html
可以導入QML文件的本地目錄,而無需任何其他設置或配置。也可以導入QML文件的遠程目錄,但是需要目錄列表qmldir
文件存在。本地目錄可以選擇包含目錄列表qmldir
文件,並指定可使用的JavaScript資源。
本地目錄導入
如果本地目錄包含目錄列表qmldir
文件,則這些類型將與qmldir
文件中指定的類型名稱一起使用;否則,將不可用。它們將具有從QML文檔的文件名派生的類型名稱。如果qmldir
在目錄中未指定文件,則只有以大寫字母開頭和以“ .qml”結尾的文件名纔會顯示爲類型。
例:
文檔結構如下
myapp
|- mycomponents
|- CheckBox.qml
|- DialogBox.qml
|- Slider.qml
|- main
|- application.qml
下例可以直接使用類型
import "../mycomponents"
DialogBox {
CheckBox {
// ...
}
Slider {
// ...
}
}
也可以定義別名訪問
import "../mycomponents" as MyComponents
MyComponents.DialogBox {
// ...
}
遠程目錄
如果目錄包含目錄列表qmldir
文件,也可以從遠程位置導入QML文件的目錄。
例如,如果myapp
上一個示例中的目錄位於“ http://www.my-example-server.com”,並且該mycomponents
目錄包含的qmldir
文件定義如下:
//qmldir文件
CheckBox CheckBox.qml
DialogBox DialogBox.qml
Slider Slider.qml
//可以使用這種方式遠程加載文件
import "http://www.my-example-server.com/myapp/mycomponents"
DialogBox {
CheckBox {
// ...
}
Slider {
// ...
}
}
//請注意,文件通過網絡導入目錄時,只能訪問qmldir該目錄中文件中指定的QML和JavaScript文件。
//警告:從遠程服務器導入目錄時,開發人員應始終謹慎,僅從受信任的源加載目錄,以避免加載惡意代碼
目錄列表qmldir文件
目錄列表qmldir
文件與模塊定義qmldir文件明顯不同。目錄列表qmldir
文件允許快速方便地共享一組QML文檔,但是它沒有定義將文檔定義的QML對象類型註冊到的類型名稱空間,也不支持這些QML對象類型的版本控制。
目錄列表qmldir
文件的語法如下:
Command | Syntax | Description |
---|---|---|
Object Type Declaration | <TypeName> <FileName> | An object type declaration allows a QML document to be exposed with the given <TypeName> .
Example: RoundedButton RoundedBtn.qml |
Internal Object Type Declaration | internal <TypeName> <FileName> | An internal object type declaration allows a QML document to be registered as a type which becomes available only to the other QML documents contained in the directory import. The internal type will not be made available to clients who import the directory.
Example: internal HighlightedButton HighlightedBtn.qml |
JavaScript Resource Declaration | <Identifier> <FileName> | A JavaScript resource declaration allows a JavaScript file to be exposed via the given identifier.
Example: MathFunctions mathfuncs.js |
本地文件系統目錄可以選擇包含qmldir
文件。這允許引擎僅嚮導入目錄的客戶端公開某些QML類型。此外,除非在qmldir
文件中聲明它們,否則目錄中的JavaScript資源不會公開給客戶端。