
برای آموزش Qt Quick بهتر از ابتدا با مفاهیم زیر آشنا شویم:
QML چیست ؟
QML یک زبان اعلامی است که به رابط های کاربر اجازه می دهد تا از نظر اجزای بصری آنها و نحوه تعامل و ارتباط آنها با یکدیگر توصیف شوند. این یک زبان بسیار خوانا است که به گونه ای طراحی شده است که مؤلفه ها را به صورت پویا به هم متصل می کند و اجازه می دهد تا مؤلفه ها به راحتی در یک رابط کاربری مجدداً مورد استفاده قرار گیرند و سفارشی شوند.
Qt Quick چیست ؟
QtQuick یک کتابخانه استاندارد از انواع و توابع برای QML است. که شامل انواع بصری، انواع تعاملی، انیمیشنها، مدلها و نماها، جلوههای ذرات و افکتهای سایه زن است. توسعه دهندگان QML میتوانند با یک ایمپورت به همه اینها دسترسی داشته باشند.
شروع سریع آموزش Qt Quick
این فصل یک مرور کلی بر QML است، زبان رابط کاربری اعلامی مورد استفاده در Qt 5. ما در مورد سینتکس QML که درختی از عناصر است بحث خواهیم کرد و به دنبال آن مروری بر مهمترین عناصر اساسی آن خواهیم داشت. بعداً به طور خلاصه به نحوه ایجاد عناصر خود به که به آنها کامپوننت میگویند خواهیم پرداخت و نحوه تبدیل عناصر با استفاده از دستکاری ویژگی ها خواهیم پرداخت. در پایان، به نحوه چیدمان عناصر با هم در یک لایه و در نهایت نگاهی به عناصری خواهیم پرداخت که کاربر می تواند ورودی ارائه دهد.
سینتکس QML
QML یک زبان اعلامی است که برای توصیف رابط کاربری برنامه شما استفاده می شود. این رابط کاربری را به عناصر کوچکتر تقسیم می کند، که می توانند در کامپوننتها ترکیب شوند. QML ظاهر و رفتار این عناصر رابط کاربری را توصیف می کند. این توضیحات رابط کاربری را می توان با کد جاوا اسکریپت تکمیل کرد تا کدهای ساده اما با منطق پیچیده تری ارائه دهد. در این دیدگاه، از الگوی HTML-JavaScript پیروی میشود، اما بر خلاف HTML زبان QML از ابتدا برای توصیف رابطهای کاربر طراحی شده است، نه اسناد متنی.
QML در ساده ترین روش خود سلسله مراتبی از عناصر است. عناصر کودک سیستم مختصات را از والدین به ارث می برند. مختصات x,y همیشه نسبت به والد است.

بیایید با یک مثال ساده از یک فایل QML برای توضیح سینتکس مختلف شروع کنیم.
- عبارت import یک ماژول را در یک نسخه خاص وارد می کند.
- نظرات را میتوان با استفاده از // برای نظرات تک خطی یا /* */ برای نظرات چند خطی ایجاد کرد. درست مانند C/C++ و جاوا اسکریپت
- هر فایل QML باید دقیقاً یک عنصر ریشه داشته باشد، مانند HTML
- یک عنصر با نوع خود و به دنبال آن { } اعلام می شود
- عناصر می توانند ویژگی داشته باشند، آنها به شکل "نام: مقدار" هستند
- عناصر دلخواه داخل یک سند QML را می توان با استفاده از شناسه آنها (یک غیر رشتهای) دسترسی داشت.
- عناصر می توانند تودرتو باشند، به این معنی که یک عنصر والد می تواند دارای عناصر فرزند باشد. عنصر والد با استفاده از کلمه کلیدی parent قابل دسترسی است.
عبارت import که شما یک نسخه خاص از یک ماژول را وارد می کنید. برای ماژولهای QML که با Qt ارائه میشوند، نسخه به نسخه Qt که قصد استفاده از آن را دارید پیوند داده شده است. هرچه شماره نسخه کمتر باشد، می توان از نسخه Qt قبلتر استفاده کرد. نسخه فرعی بیانیه import با نسخه فرعی نسخه Qt مطابقت دارد، بنابراین Qt 5.11 با QtQuick 2.11 و Qt 5.12 به QtQuick 2.12 و غیره مطابقت دارد. قبل از Qt 5.11، ماژولهای QML ارسال شده با Qt دارای توالی نسخهسازی خاص خود بودند، به این معنی که QtQuick از نسخههای Qt پیروی میکرد، در حالی که QtQuick.Controls با نسخه 2.0 در Qt 5.7 شروع شد و نسخه 2.4 در Qt 5.11 بود.
اغلب می خواهید با استفاده از کلمه کلیدی parent به یک عنصر خاص با شناسه یا یک عنصر والد دسترسی پیدا کنید. بنابراین تمرین خوبی است که عنصر ریشه خود را "root" با استفاده از id: root نامگذاری کنید. سپس لازم نیست به نحوه نامگذاری عنصر ریشه در سند QML خود فکر کنید.
اشاره
می توانید مثال را با استفاده از Qt Quick Runtime از خط فرمان سیستم عامل خود اجرا کنید:
$QTDIR/bin/qmlscene RectangleExample.qml
مسیر نصب Qt خود را بجای $QTDIR جایگزین کنید. فایل اجرایی qmlscene زمان اجرای Qt Quick را مقداردهی اولیه می کند و فایل QML ارائه شده را تفسیر می کند.
در Qt Creator می توانید فایل پروژه مربوطه را باز کرده و سند RectangleExample.qml را اجرا کنید.
پراپرتیها
عناصر با استفاده از نام عنصر خود اعلان می شوند اما با استفاده از ویژگی های آنها یا با ایجاد ویژگیهای سفارشی تعریف می شوند. یک ویژگی یک جفت کلید-مقدار ساده است، به عنوان مثال.
یک ویژگی دارای یک نوع کاملاً مشخص است و می تواند یک مقدار اولیه داشته باشد.
بیایید ویژگی های مختلف propertyها را مرور کنیم:
- id یک مقدار ویژگی خاص است که برای ارجاع به عناصر داخل یک فایل QML (که در QML "سند" نامیده می شود) استفاده می شود. شناسه یک نوع رشته نیست، بلکه یک شناسه و بخشی از سینتکس QML است. یک شناسه باید در داخل یک سند منحصربهفرد باشد و نمیتوان دو id یکسان در یک سند داشت و نمیتوان آن را پرس و جو(query) کرد. (در دنیای ++C مانند یک مرجع عمل می کند.)
- یک ویژگی بسته به نوع آن می تواند روی یک مقدار تنظیم شود. اگر مقداری برای یک ویژگی داده نشود، مقدار اولیه انتخاب می شود. برای اطلاعات بیشتر در مورد ارزش اولیه یک property، باید به مستندات آن مراجعه کنید.
- یک ویژگی می تواند به یک یا چند ویژگی دیگر وابستگی داشته باشد. به این binding میگویند. یک ویژگی bound زمانی به روز می شود که حداقل یکی از ویژگیهای وابسته آن تغییر کند. مانند قرارداد عمل می کند، در این صورت ارتفاع باید همیشه دو برابر عرض باشد. (height: 2 * width)
- تعریف پراپرتیها به صورت (<مقدار اولیه> : <نام> <نوع> property) تعریف میشود که مقدار اولیه اختیاریست و اگر مقدار اولیه داده نشود، مقدار اولیه سیستم انتخاب می شود.
توجه
همچنین میتوانید یک ویژگی را بهعنوان ویژگی پیشفرض با اضافه کردن اعلان ویژگی با کلمه کلیدی default اعلام کنید، اگر نام property داده نشده باشد. برای مثال وقتی عناصر فرزند را اضافه میکنید، عناصر فرزند به طور خودکار به ویژگیهای پیشفرض فرزندان لیست نوع اضافه میشوند، اگر عناصر قابل مشاهده باشند.
یا به عنوان مثالی دیگرمقدار someText میتواند در تعریف MyLabel به صورت زیر مقدار دهی شود
این دقیقا معادل کد زیر است
- یکی دیگر از راه های مهم برای اعلام ویژگی ها، استفاده از کلمه کلیدی alias است
( <مرجع>: <نام> property alias). کلمه کلیدی alias به ما این امکان را می دهد که یک ویژگی یک شی یا خود یک شی را از درون نوع به یک محدوده بیرونی ارسال کنیم. ما بعداً هنگام تعریف مؤلفهها برای صادر کردن ویژگیهای داخلی یا شناسه عناصر به سطح ریشه از این تکنیک استفاده خواهیم کرد. نام property alias نیازی به نوع ندارد، از نوع خاصیت یا شیء مرجع استفاده می کند. - پراپرتی text به پراپرتی times که از نوع int است بستگی دارد مقدار مبتنی بر int به طور خودکار به یک نوع رشته تبدیل می شود. این عبارت مثال دیگری از binding است و هر بار که ویژگی times تغییر میکند، متن به روز می شود.
- برخی از propertyها گروه بندی شده هستند. این ویژگی زمانی استفاده می شود که یک ویژگی ساختارمندتر است و ویژگی های مرتبط باید با هم گروه بندی شوند. یکی دیگر از روش های نوشتن ویژگی های گروه بندی شده
font { family: "Ubuntu"; pixelSize: 24 }. - برخی از ویژگی ها به خود عنصر متصل می شوند. این کار برای عناصر مرتبط جهانی که فقط یک بار در برنامه ظاهر می شوند (به عنوان مثال ورودی صفحه کلید) انجام می شود.
<Element>.<property>: <value>. - برای هر پراپرتی، می توانید یک سیگنال کنترل کننده ارائه دهید. این کنترل کننده پس از تغییر ویژگی فراخوانی می شود. به عنوان مثال، در اینجا ما می خواهیم هر زمان که ارتفاع تغییر می کند مطلع شویم و از کنسول داخلی برای ثبت پیام به سیستم استفاده کنیم.
هشدار
یک id فقط باید به عنوان مرجع در یک مستند استفاده شود (فایل فعلی). QML یک مکانیزم به نام محدوده بندی پویا فراهم کرده است که مستندات لود شده جدید مقادیر id قبلی را بازنویسی میکنند. این مکانیزم امکان استفاده از idهای قبلی را به ظرط بازنویسی نشدن فراهم میکند. این مانند ساخت متغیرهای جهانیست. متاسفانه این مکانیزم در عمل باعث به وجود آمدن کد بد میشود که باعث میشود برنامه به ترتیب اجرا وابسته باشد و امکان ایجاد مشکل پس از تغییرات در کد به شدت بالا میرود. متاسفانه امکان غیرفعال کردن این مکانیزم وجود ندارد. لطفا فقط با دقت از این مکانیزم استفاده کنید یا بهتر است اصلا از آن استفاده نکنید. بهتر است از بجای این روند از ایجاد کردن پراپرتی در المنت root استفاده کنید.
اسکریپت نویسی
QML و جاوا اسکریپت (همچنین به عنوان ECMAScript شناخته می شود) بهترین دوستان هستند. در فصل جاوا اسکریپت به جزئیات بیشتری در مورد این همزیستی خواهیم پرداخت. در حال حاضر در آموزش Qt Quick، ما فقط می خواهیم شما را از این رابطه آگاه کنیم.
- کنترلکننده تغییر متن onTextChanged هر بار که متن به دلیل فشار دادن کلید فاصله تغییر میکند، متن فعلی را چاپ میکند.
- هنگامی که عنصر متن کلید فاصله را دریافت می کند (به دلیل اینکه کاربر کلید فاصله را روی صفحه کلید فشار داده است) یک تابع جاوا اسکریپت increment() را فراخوانی می کنیم.
- تعریف تابع جاوا اسکریپت به شکل تابع <name>(<parameters>) { ... } که شمارنده spacePressed ما را افزایش می دهد. هر بار که spacePressed افزایش می یابد، پراپرتیهای وابسته نیز به روز می شوند.
توجه
تفاوت بین QML binding و تخصیص جاوا اسکریپت (=) در این است که binding یک قرارداد است و در طول عمر binding صادق است، در حالی که تخصیص جاوا اسکریپت (=) یک بار انجام میشود و با تغییرات بعدی پراپرتیها کاری ندارد. یک binding زمانی به اتمام میرسد که یک binding جدید تنظیم ود یا یک تخصیص جاوا اسکریپت صورت بپذیرد به عنوان مثال، یک کنترل کننده کلید که ویژگی متن را روی یک رشته خالی تنظیم می کند، نمایش افزایشی ما را از بین می برد:
Keys.onEscapePressed: {
label.text = ' '
}
پس از فشار دادن escape، فشار دادن کلید فاصله نمایشگر را دیگر بهروزرسانی نمیکند، زیرا binding قبلی پراپرتی متن (text: “Space pressed: ” + spacePresses + ” times”) از بین رفته است.
هنگامی که استراتژی های متناقضی برای تغییر یک ویژگی مانند این مورد دارید (متن به روز شده با تغییر به یک افزایش ویژگی از طریق یک binding و متن پاک شده توسط یک انتساب جاوا اسکریپت) پس نمیتوانید از bindings استفاده کنید! شما باید از انتساب در هر دو مسیر تغییر ویژگی استفاده کنید زیرا اتصال توسط انتساب از بین می رود (قرارداد شکسته!).
برای ادامه آموزش Qt Quick حتما کانال تلگرام ما را دنبال کنید همچنین پس از تکمیل ویدئو آموزش Qt Quick لینک آپارات و یوتیوب آن در همین صفحه قرار خواهد گرفت.
کانال تلگرام لینک ویدئو(به زودی)