ماژول های Qml بخش هایی مستقل در برنامه اند که وظایف مشخصی را در ارتباط با دیگر ماژول ها و برنامه انجام می دهند. در این نوشته نگاهی می اندازیم به ماژول های Qml، ایجاد آن ها و ارتباط با دیگر ماژول ها.
ماژول Qml
یک ماژول کیو ام ال (Qml) معمولا شامل فایل های کیو ام ال (Qml) و جاوا اسکریپت (JavaScript) است. همچنین می تواند دارای فایل های منبع (Resources) – مانند تصویر و صدا – و حتی کد های ++C باشد. این ماژول ها بصورت واحد های مستقل تعریف می شوند و می توان آن ها را در پروژه های دیگر باز استفاده کرد.
کیوت (Qt) برای ایجاد ماژول ها در cmake تابع qt_add_qml_module را ایجاد کرده است. این تابع ایجاد کتابخانه (Library)، ثبت انواع (Types) و ارتباط با موتور کیو ام ال را انجام می دهد.
ساخت ماژول Qml
ساخت یک ماژول کیو ام ال روندی بسیار ساده دارد. که با یک مثال آن را بررسی می کنیم. در این مثال ماژول ClockPlus را تعریف می کنیم و به پروژه می افزاییم. ساختار این ماژول بصورت زیر است.
clockplus ├── images │ └── back.jpg ├── js │ └── methods.js ├── backtype.cpp ├── backtype.h ├── ClockPlus.qml └── CMakeLists.txt
این ماژول شامل یک نوع به نام ClockPlus که در برنامه اصلی استفاده می کنیم. ماژول همچنین شامل فایل های جاوا اسکریپت، سی پلاس پلاس (++C) و یک تصویر است. محتوای فایل مانند هر پروژه دیگر کیو ام ال است و من وارد جزئیات آن ها نمی شوم. فایلی که در این ماژول برای ما مهم است فایل CMakeLists.txt است که ماژول را برای استفاده در پروژه آماده می کند. محتوای این فایل بصورت زیر است.
#CMakeLists.txt of ClockPlus module
qt_add_library(ClockPlus STATIC)
qt_add_qml_module(ClockPlus
URI modules.clockplus
VERSION 1.0
QML_FILES ClockPlus.qml
RESOURCES images/back.jpg js/methods.js
SOURCES backtype.h backtype.cpp
DEPENDENCIES QtQuick
)
در این فایل qt_add_library ماژول را بصورت یک کتابخانه استاتیک ایجاد می کند. و qt_add_qml_module ماژول را تعریف می کند. مقادیر اصلی این تابع بصورت زیر است:
- URI: بصورت مسیر ماژول با جایگذاری / با . ایجاد می شود. مثلا ماژول ClockPlus در مسیر modules/clockplus در پوشه ریشه پروژه قرار دارد. پس URI آن modules.clockplus می شود.
- VERSION: ویرایش ماژول
- QML_FILES: لیست فایل های qml
- RESOURCES: منابع مانند فایل های جاوا اسکریپت، تصاویر و …
- SOURCES: فایل های ++C
- DEPENDENCIES: اگر فایل های qml کتابخانه ای را import می کنند آن ها را اینجا اضافه می کنیم.
ساختار یک پروژه ساده که شامل ماژول ClockPlus و احتمالا ماژول های دیگری است به شکل زیر است:
ClockApp ├── modules │ ├── clockplus │ └── CMakeLists.txt ├── CMakeLists.txt ├── main.cpp └── Main.qml
افزودن ماژول به برنامه
در برنامه مثال ClockApp من ماژول ها را در مسیر دلخواه modules گذاشته ام. یک فایل CMakeLists.txt در پوشه modules ایجاد می کنم که شامل خط add_subdirectory(clockplus) است. تا مسیر ماژول ها را به فایل CMake بالاتر معرفی کند. حال در فایل CMakeLists.txt اصلی پروژه خط add_subdirectory(modules) را برای معرفی ماژول ها به CMake اضافه می کنم. در پایان ClockPlusplugin را به target_link_libraries می افزایم. ClokcPlusplugin نام کتابخانه ای است که qt_add_qml_module بصورت خودکار ایجاد کرده است. و بصورت پیش فرض نام آن را با افزودن plugin به انتهای نام ماژول تعیین می کند. فایل CMakeLists.txt نمونه را در زیر مشاهده می کنید.
cmake_minimum_required(VERSION 3.16)
project(ClockApp VERSION 0.1 LANGUAGES CXX)
find_package(Qt6 6.4 REQUIRED COMPONENTS Quick)
qt_standard_project_setup()
qt_add_executable(appClock main.cpp)
qt_add_qml_module(appClock
URI ClockApp
VERSION 1.0
RESOURCE_PREFIX /
QML_FILES
Main.qml
)
# add modules subdirectory here
add_subdirectory(modules/)
# link module to the project here
target_link_libraries(appClock PRIVATE Qt6::Quick ClockPlusplugin)
برای اطمینان از اینکه ماژول در برنامه اصلی در دسترس است دو خط زیر را به فایل main.cpp پروژه اضافه می کنیم:
#include <QtQml/QQmlExtensionPlugin>
Q_IMPORT_QML_PLUGIN(modules_clockplusPlugin)
در کد بالا modules_clockplusPlugin از جایگذاری . با _ در URI ماژول و افزودن Plugin به آخر آن بدست می آید.
اکنون که ماژول را به پروژه افزودیم، می توانیم آن را در هر فایل کیو ام ال در پروژه وارد (import) کرده و استفاده کنیم. در تکه کد زیر ماژول ClockPlus را افزوده و استفاده می کنیم.
import QtQuick
import modules.clockplus 1.0 // import module with version
Window {
width: 300; height: width * 16/9
visible: true
ClockPlus { // using ClockPlus type from module
id: clockPlus
anchors.centerIn: parent
}
}
تا اینجا با ماژول های Qml آشنا شدیم. این ماژول ها می توانند تنها شامل فایل های Qml باشند، یا فقط شامل کلاس های ++C و یا ترکیبی از هر دو.
ارتباط با ++C
در نوشته «ارتباط Qml با ++C» گفتم که یکی از راه های ارتباط بین رابط کاربری و منطق برنامه ماژول های Qml اند. بدین صورت که می توانیم کلاس های مختلفی را در ماژول تعریف کنیم. سپس در فایل های Qml برنامه آن ها را نمونه سازی (Instantiate) کنیم.
نکته مهم اینکه کلاس های ایجاد شده باید از QObject مشتق شده باشند و شامل ماکرو QML_ELEMENT باشند. برای آشنایی بیشتر با این کلاس ها به نوشته «ارتباط Qml با ++C» مراجعه کنید.