در قسمت قبل با مقدماتی از اضافه کردن کنترلها در qml آشنا شدیم و قرار بر این شد که این قسمت به کنترلها حرکت دهیم. برای این کار چون میخواهیم از رویداد ماوس برای حرکت کردن کنترلها استفاده کنیم کنترل MouseArea را زیر مجموعه کنترل مستطیل قرار میدهیم. با این کار وقت نشانه گر ماوس داخل محدوده مستطیل میشود عملیات تعریف شده ما انجام میشود.
خب برای اینکه کنترل MouseArea را زیر مجموعه کنترل مستطیل قرار دهیم:
• در حالت design مربوط به qtcreator باید کنترل MouseArea را با ماوس گرفته و روی کنترل مستطیل ببریم و رها کنیم. به این ترتیب در قسمت
• Navigator چیزی شبیه تصویر زیر مشاهده میشود.
همینطور که در شکل بالا میبینید کنترل مستطیل ما به اسم topLeftRectangle میباشد و کنترل MouseArea زیر مجموعه آن قرار گرفته است و علامت مثلث کوچکی در سمت چپ آن نمایان شده است.
• در حالت Edit مربوط به qtcreator کافی است که MouseArea را در محدوده کنترل مستطیل (در بین آکلاد باز و بسته بعد از Rectangle قرار گیرد). به کد زیر دقت کنید.
Rectangle { id: topLeftRectangle x: 10 y: 20 width: 64 height: 64 color: "#00000000" radius: 6 border.color: "#808080" MouseArea { anchors.fill: parent onClicked: { Qt.quit(); } } }
حال باید دو تا مستطیل به همراه کنترل MouseArea در دو نقطه دیگر از فرم ایجاد کنیم تا با کلیک بر روی آنها لوگوی faceit بین آنها جابجا شود. برای راحتی کار در حالت Edit مربوط به qtcreator کد بالا را کپی میکنیم و دوبار پیست میکنیم با این کار سه تا مستطیل داریم فقط نکته مهم این است که سه کنترل مستطیل باید دارای id منحصر به فرد باشند و علاوه بر آن باید مقدار x و y آنها متفاوت باشد. به صورت زیر:
Rectangle { id: topLeftRectangle x: 10 y: 20 width: 64 height: 64 color: "#00000000" radius: 6 border.color: "#808080" MouseArea { anchors.fill: parent onClicked: { Qt.quit(); } } } Rectangle { id: middleRightRectangle x: 426 y: 218 width: 64 height: 64 color: "#00000000" radius: 6 border.color: "#808080" MouseArea { anchors.fill: parent onClicked: { Qt.quit(); } } } Rectangle { id: bottomLeftRectangle x: 10 y: 416 width: 64 height: 64 color: "#00000000" radius: 6 border.color: "#808080" MouseArea { anchors.fill: parent onClicked: { Qt.quit(); } } }
حال باید رویداد کنترل MouseArea را مدیریت کنیم. در حال حاضر رویداد onClicked آن با کد Qt.quit تعریف شده که منجر به بسته شدن فرم میشود. به عبارت دیگر اگر برنامه را اجرا کنیم و بر روی هر یک از کنترلهای مستطیل کلیک کنیم فرم بسته میشود و اجرای برنامه خاتمه مییابد. اما هدف ما حرکت کردن لوگو است وقتی لوگو از یک کنترل مستطیل به یک کنترل مستطیل دیگر میرود، درواقع به این معنی است که شکل ظاهری فرم تغییر میکند به همین منظور باید چند حالت مختلف از فرم تعیین کنیم که در هر کدام مشخص شده باشد که وضعیت کنترلها در آن به چه صورت است. به هر کدام از این حالات State میگویند.
نکته: اگر برنامه ما به صورتی باشد که برای فرم خود نیاز به حالات مختلف داشته باشیم باید زیر مجموعه کنترل Window که در زمان ایجاد پروژه به صورت پیشفرض میسازد از Rectangle استفاده کنیم و سپس بقیه کنترلها را در این Rectangle تعریف کنیم. به عبارت دیگر در کنترل Window مستقیم نمیتوان چند حالت یا state ایجاد کرد.
طبق نکته بالا ما یک Rectangle برای فرم ایجاد میکنیم که لوگو و کنترلهای مستطیل و ماوس در آن قرار میگیرند و id آن را form قرار میدهیم، این کنترل را در بدنه Window تعریف میکنیم.
برای تعریف حالات مختلف فرم در بدنه form (بین آکلاد باز و بسته کنترل Rectangle زیر مجموعه کنترل Window) باید به صورت زیر عمل کنیم.
states: [ State { name: "state1" PropertyChanges { target: faceit x: middleRightRectangle.x y: middleRightRectangle.y } }, State { name: "state2" PropertyChanges { target: faceit x: bottomLeftRectangle.x y: bottomLeftRectangle.y } } ]
برای هر حالت یک نام اختصاص میدهیم و تغییراتی که ایجاد میشود را در PropertyChanges مینویسیم. برای مثال اینجا target ما همان لوگوی faceit است که از نوع کنترل Image بوده و id آن faceit میباشد. برای اینکه مکان لوگو را در state1 تعیین کنیم از مختصات کنترلهای مستطیل استفاده میکنیم. در اینجا از مختصات کنترل مستطیل سمت راست بهره گرفتیم زیرا میخواهیم هر وقت که بر روی آن مستطیل کلیک شد لوگو به آن مستطیل برود.
اکنون باید در رویداد کلیک کنترل MouseArea به جای Qt.quit حالت را عوض کنیم. به صورت زیر:
Rectangle { id: topLeftRectangle x: 10 y: 20 width: 64 height: 64 color: "#00000000" radius: 6 border.color: "#808080" MouseArea { anchors.fill: parent onClicked: form.state = '' } } Rectangle { id: middleRightRectangle x: 426 y: 218 width: 64 height: 64 color: "#00000000" radius: 6 border.color: "#808080" MouseArea { anchors.fill: parent onClicked: form.state = 'state1' } } Rectangle { id: bottomLeftRectangle x: 10 y: 416 width: 64 height: 64 color: "#00000000" radius: 6 border.color: "#808080" MouseArea { anchors.fill: parent onClicked: form.state = 'state2' } }
همانطور که در کد بالا میبینید از حالتهایی که ایجاد کردیم بهره بردیم. تا اینجا به هدف خود رسیدهایم اما میتوانیم نحوه تغییر حالت و سرعت تغییر حالت را نیز تحت کنترل قرار دهیم که انیمیشن به صورت نرم اجرا شود. برای این کار از transitions و آن هم در بدنه همان form مینویسیم. به صورت زیر:
transitions: [ Transition { from: "*" to: "state1" NumberAnimation { target: faceit properties: "x,y" duration: 2000 easing.type: Easing.InOutQuad } }, Transition { from: "*" to: "state2" NumberAnimation { target: faceit properties: "x,y" duration: 1000 easing.type: Easing.OutBounce } }, Transition { NumberAnimation { properties: "x,y"; duration: 200 } } ]
با توجه به کد بالا مقدار from که ستاره است به این معنی است که فرقی ندارد حالت قبلی کدام بوده. البته میتوان دقیقاً نوع حالت قبل را نیز در اینجا کنترل کرد و به جای ستاره نام حالت را بنویسیم. مقدار to نشان دهنده حالتی است که به آن میرود در اینجا نیز این امکان وجود دارد که ستاره استفاده کنیم. NumberAnimation کنترل هدف را مشخص میکند (target) و خصوصیاتی که توسط آن باید کنترل شوند(x و y) و مدت زمان بین تغییر حالت (مثلاً ۱۰۰۰)، درواقع خصوصیات x , y را یکی یکی با سرعتی تنظیم شده اینقدر تغییر میدهد که به x و y حالت بعد برسد. در آخر همنوع انیمیشن توسط easing.type مشخص میشود که دو نمونه از آن در اینجا به عنوان نمونه به کار رفته است. در نهایت کد کامل qml به صورت زیر میشود.
import QtQuick 2.0 import QtQuick.Window 2.0 Window { id: window1 color: "#343434" visible: true width: 500 height: 500 Rectangle{ id:form Image { id: faceit x: 10 y: 20 width: 64 height: 64 source: "faceit_logo.jpg" } Rectangle { id: topLeftRectangle x: 10 y: 20 width: 64 height: 64 color: "#00000000" radius: 6 border.color: "#808080" MouseArea { anchors.fill: parent onClicked: form.state = '' } } Rectangle { id: middleRightRectangle x: 426 y: 218 width: 64 height: 64 color: "#00000000" radius: 6 border.color: "#808080" MouseArea { anchors.fill: parent onClicked: form.state = 'state1' } } Rectangle { id: bottomLeftRectangle x: 10 y: 416 width: 64 height: 64 color: "#00000000" radius: 6 border.color: "#808080" MouseArea { anchors.fill: parent onClicked: form.state = 'state2' } } states: [ State { name: "state1" PropertyChanges { target: faceit x: middleRightRectangle.x y: middleRightRectangle.y } }, State { name: "state2" PropertyChanges { target: faceit x: bottomLeftRectangle.x y: bottomLeftRectangle.y } } ] transitions: [ Transition { from: "*" to: "state1" NumberAnimation { target: faceit properties: "x,y" duration: 2000 easing.type: Easing.InOutQuad } }, Transition { from: "*" to: "state2" NumberAnimation { target: faceit properties: "x,y" duration: 1000 easing.type: Easing.OutBounce } }, Transition { NumberAnimation { properties: "x,y"; duration: 200 } } ] } }
برنامه هدف ما ایجاد شد و در عکس زیر میتوانید اجرا شده آن را ببینید.
در جلسات آینده با ما همراه باشید.
ثبت نظر