2013-03-06 76 views
19

Tôi muốn khai báo thuộc tính chung trong tệp cấu hình và sử dụng nó trong các tệp khác. ví dụ tuyên bố mainbg trong:khai báo thuộc tính toàn cầu trong QML cho các tệp QML khác

Style.qml:

property color mainbg: 'red' 

và sử dụng nó trong các tập tin QML khác (như view.qmlmain.qml). Làm thế nào tôi có thể làm công việc này?

Trả lời

28

Sử dụng QML Singleton.

Vui lòng tham khảo "Cách tiếp cận 2" trên this page - Các ý kiến ​​xấu xí QTBUG-34418 là của tôi.

Đây là những mảnh bạn cần:

Style.QML

pragma Singleton 
import QtQuick 2.0 
QtObject { 
    property color mainbg: 'red' 
} 

qmldir

Tập tin này phải nằm trong cùng thư mục với singleton .qml nộp (Style.qml trong ví dụ của chúng tôi) hoặc bạn phải cung cấp một đường dẫn tương đối với nó. qmldir cũng có thể cần được bao gồm bởi tệp tài nguyên .qrc. Thông tin thêm về các tệp qmldir có thể được tìm thấy here.

# qmldir 
singleton Style Style.qml 

Làm thế nào để tham khảo

import QtQuick 2.0 
import "." // this is needed when referencing singleton object from same folder 
Rectangle { 
    color: Style.mainbg // <- there it is!!! 
    width: 240; height 160 
} 

Cách tiếp cận này có sẵn từ Qt5.0. Bạn cần một câu lệnh import thư mục ngay cả khi tham chiếu singlet QML trong cùng một thư mục. Nếu là cùng một thư mục, hãy sử dụng: import "." Đây là lỗi mà tôi đã ghi trên trang qt-project (xem QTBUG-34418, các trình đơn yêu cầu nhập khẩu rõ ràng để tải tệp qmldir).

+0

Tại sao không chỉ là một tập tin javascript '.pragma library' đơn giản? – Matteo

17

Bạn có thể tạo tệp js và nhập tệp đó vào tất cả các tệp phải sử dụng thuộc tính này.

js file:

//Note: you only need '.pragma library' if you are planning to 
//change this variable from multiple qml files 
.pragma library 
var globalVariable = 20; 

QML file:

import "test.js" as Global 

Rectangle { 
    id: main 
    width: 300; height: 400 

    Component.onCompleted: { 
    console.log(Global.globalVariable) 
    //you can also change it 
    Global.globalVariable = 5 
    } 
} 
+1

đừng quên đặt '#pragma library' vào đó. – user1095108

+5

Tôi phải lưu ý rằng tệp '.pragma library' _allowes_ JS sẽ được một số tệp QML sử dụng, nhưng _không bảo đảm rằng sẽ chỉ có một thể hiện của thư viện. Tôi vừa mới gặp phải lỗi nghiêm trọng trong ứng dụng của mình là do nỗ lực của tôi trong việc sử dụng thư viện JS như là thùng chứa trạng thái toàn cục. – tonytony

1

Bạn luôn có thể tạo ra một tập tin đối tượng QML mới có chứa các thuộc tính mà bạn muốn chia sẻ trên các file QML. Chỉ cần nhập nó giống như cách bạn làm với bất kỳ đối tượng QML nào và bạn có quyền truy cập vào các thuộc tính. Bây giờ, nếu bạn muốn có thể sửa đổi các thuộc tính này và có các thay đổi được chia sẻ trên các trường hợp, mọi thứ trở nên phức tạp hơn nhiều và bạn sẽ muốn sử dụng một số giải pháp bằng cách sử dụng tệp .pragma thư viện js. Trừ khi bạn muốn viết một số loại C++ thay thế.

20

Về cơ bản, nếu bạn không cần phải sở hữu ràng buộc (nếu bạn đánh giá là một hằng số và sẽ không cần phải khai báo về biến đổi), bạn có thể định nghĩa nó trong một thư viện chia sẻ Javascript, như thế này:

// MyConstants.js 
.pragma library 
var mainbg = "red"; 

Và sử dụng nó trong QML như thế này:

import "MyConstants.js" as Constants 

Rectangle { 
    color: Constants.mainbg; 
} 

Nhưng mặt xấu của việc này là: - không gõ mạnh (JS không thực sự biết về các loại), do đó bạn có thể đặt bất cứ điều gì ngay cả khi nó không phải là một màu. - và nếu bạn thay đổi mainbg, Mục sử dụng nó sẽ không được thông báo về thay đổi và sẽ giữ nguyên giá trị cũ

Vì vậy, nếu bạn cần kiểm tra loại và ràng buộc/thay đổi thông báo, chỉ cần khai báo tài sản của bạn với tư cách là thành viên đối tượng gốc trong bạn main.qml, và nó sẽ có thể truy cập từ mọi nơi trong ứng dụng QML, bởi vì thuộc tính trên thực tế sẽ được đăng ký trực tiếp vào đối tượng Ngữ cảnh Qml, là định nghĩa toàn cục theo định nghĩa.

Hy vọng điều đó sẽ hữu ích.

1

Thêm thuộc tính này vào chính và bạn có thể truy cập vào bất kỳ qml nào, đây có thể không chính xác nhưng cách này hoạt động.

hoặc nếu bạn muốn vào nhóm bất động sản thêm chúng vào một QML bao gồm mà QML trong chính và đưa ra một id, bây giờ bạn có thể truy cập vào thuộc tính này sử dụng id rằng

main.qml

Item{ 
width:10 
height:10 

Model{ 
id:globdldata 
} 



} 

Model.qml

Item { 

property color mainbg: 'red' 

} 

bạn có thể sử dụng bất cứ nơi nào globdldata.mainbg

3

Thêm một số đóng góp vào câu trả lời @pixelgrease, tôi đã tìm thấy một kỹ thuật khác không yêu cầu đường dẫn tương đối import ".", giải quyết lỗi QTBUG-34418. Điều này rất hữu ích, đặc biệt nếu một lớp có một lớp là qmldir và singleton ở một vị trí khác với tệp qml mà singleton được sử dụng. Kỹ thuật này yêu cầu xác định một mô-đun thích hợp bên trong cấu trúc cây: sau đó mô-đun được giải quyết bằng cách thêm đường dẫn cha của mô-đun vào công cụ QML với QmlEngine::addImportPath(moduleParentPath). Ví dụ:

qml/ 
├── <ModuleName>/ 
│ ├── <ClassName>.qml 
│ ├── qmldir 

Trong main.cpp bạn có rồi:

QQmlApplicationEngine engine; 
engine.addImportPath("qrc:/qml"); // Can be any directory 
engine.load("qrc:/qml/main.qml"); 

Nếu bạn sử dụng các nguồn lực, qml.qrc:

<RCC> 
<qresource prefix="/"> 
     (...) 
<file>qml/main.qml</file> 
<file>qml/MySingletons/MySingleton.qml</file> 
<file>qml/MySingletons/qmldir</file> 
</qresource> 
</RCC> 

Trong qmldir:

module MySingletons 
singleton MySingleton 1.0 MySingleton.qml 

Trong main.qml hoặc bất kỳ tệp qml nào khác trong một thư mục khác ectory:

import MySingletons 1.0 

Sau đó, bạn sử dụng lớp MySingleton như bình thường. Tôi đính kèm ví dụ MySingletonWithModule.7z vào lỗi QTBUG-34418 để tham khảo.