کار با ویجتها و المنتها در کیوت
سلام دوستان خوبم درخشانی هستم با قسمت چهارم آموزش کیوت از سری آموزش برنامه نویسی در خدمت شما هستم.
خوب هستید؟ یا نیستید؟ عصبانی هستید به خاطر تأخیر آموزش هفتهی قبل؟ بله حق دارید! باید ببخشید آخر سالی است و سر شلوغی! امیدوارم کمکم نظم و روال ثابتی بتوانیم به آموزشها بدهیم.
اگر درست به خاطر بیارم طبق سرفصلها، از مقدمات کیوت شروع کردیم و بعد از بررسی محیط Qt_Creator رسیدیم به کار با widgets و المانها یعنی سرفصل سوم.
فصل سوم: کار با ویجتها و المنتها در کیوت
مقدمات تئوری:
تعریف ویجت: بهطورکلی هر چیزی رو که بشه با چشم سر دید در کیوت ما بهش میگیم ویجت! و هر آنچه را که بشه با چشم دل دید... نه دیگِ همچین چیزی ندارم، کلاس ادبیات نیست که.
پس کلیهی اجزای فیزیکی(در دنیای نرمافزار البته) و قابلمشاهده در برنامه ازجمله #دکمهها، برچسبها، طرحبندیها، تکستادیتورها، تصاویر و ... و ... را ویجت مینامیم. اینها اجزای فرمها و پنجرهها و پیغامها و ...ی ما خواهند بود و ما در بخش طراحی ظاهری(UI) به آن خواهیم پرداخت. ویجتها کلاسهایی هستند که در ظاهر برنامه هم نمایش داده میشوند.
سیگنال (Signals): هر ویجت یا به صورت کلی هر کلاسی، میتواند مثل یک فرستندهی رادیویی یا مثل یک بلندگو از خود امواجی منتشر کنند. سیگنالها در کیوت همان رویدادها در زبانهایی مثل C# است.
اسلات (#Slots): هر ویجت یا کلاسی میتواند مثل یک گیرندهی رادیویی یا مثل یک گوش عمل کند و امواجی را از یک فرستندهی خاص بگیرد و متناسب با آن عکسالعملی(مثل پخش کردن یا هر چیزی) انجام دهد.
اصلاً این دو تا چه ربطی به هم داشتند؟ هیچی! من و دوستانم هم نمیدانیم اما همینقدر کافی است که بدانیم اینیک انقلاب در صنعت توسعهی نرمافزار است.
با این امکان شما میتوانید بهراحتی دست کلاسهای مختلف را تو دست هم بذارید و بینشان تشریکمساعی برقرار کنید(یعنی همان ارتباط خودمان)!
مثال بدنی: وقتی فردی گرسنه است و با یک غذای لذیذ مواجه میشود، شکمش سیگنال قاروقور ساطع میکنه! و اسلات سیستم اعصاب این سیگنال را میگیرد و واکنش متناسب با آن را که ترشح بزاق است نشان میدهد.
مثال فنی: فرض کنید که کیوت دست دکمهی ۱ را در دست پنجرهی ۲ گذاشته است. یعنی اومده سیگنال کلیک شدن دکمهی ۱ (بلندگو) را در دست اسلات(گوش) باز شدنِ پنجره ۲ گذاشته. حالا وقتی دکمهی 1 کلیک میشود، سیگنال کلیک شدن را در برنامه صادر میکند(داد میزند که کلیک شدم)، سپس اسلات باز شدن پنجرهی 2 فعال میشود و پنجرهی ۲ را باز میکند.
یا مثلاً سیگنال «کلیک شدن» دکمهی ۱ را به اسلات «بسته شدن» در پنجرهی ۲ وصل میکند. چه اتفاقی میافتد؟ وقتی دکمهی دکمهی ۱ کلیک شد، پنجرهی ۲ متوجه میشود و بسته میشود. همین.
به این میگن سیستم سیگنال و اسلات در کیوت. یکجور جانبخشی به اشیاء!
به تصویر ۱ دقت کنید. هر کلاس در کیوت جدا از بخشهای اصلیاش(private و public و ...) دارای دو بخش دیگر هم هست: سیگنالها و اسلاتها. همانطور که در شکل میبینید Signal 1 در Class X به Slot A در Class Y وصل است و متقابلاً Signal 1 در Class Y به Slot A در Class 1 وصل شده است.
این معنی خودمانیاش چی میشه؟ توضیح با شما.
اما این سیگنال و اسلاتها چی هستند؟ متغییرن؟ کلاسن؟
هیچکدام. دقیقا از جنس تابع اند! اما دسته بندیشون اسمش سیگنال و اسلاتِ همین.
اینا رو گفتیم که بریم یه مثال عملی بزنیم.
مثال:
میخواهیم برنامهای طراحی کنیم که یه فرم سادهی ورود (login) رو شبیهسازی کنه و با واردکردن
نام کاربری: admin
و
رمز: admin
پیغام خوشآمد گویی به کاربر نشان بده.
مرحلهی ۱: مطابق آموزش جلسه سوم یک پروژه از نوع Qt Widget Application بسازید.
مرحلهی ۲: در پنل سمت چپ، روی پوشهی Forms و سپس روی mainwindow.ui کلیک کنید. صفحهای مطابق تصویر ۲ که شامل یک فرم خالی در وسط و یکسری ویجتها(یا کنترلها) در سمت چپ است جلوی رویتان ظاهر میشود.
مرحله ۳: چهارتا Label رو برای نمایش متن روی فرم بکشید. برای تغییر متن روی Label ها روی آنها دابل کلیک کنید ( مطابق تصویر 4)
مرحله 4: دو LineEdit روی فرم بکشید.(تصویر 5)
مرحله 5: یک PushButton روی فرم بکشید. برای تغییر متن روی PushButton روی آن دابل کلیک کنید(تصویر 6)
خب تا اینجا یک فرم ساده طراحی کردیم.
نوبت این است که به دکمه مون رفتار یاد بدیم! روی دکمهای که ساختهاید راست کلیک کنید و Go to slot… رو برنید. در پنجرهی بازشده زیر قسمت Select signal گزینهی Clicked و درنهایت Ok را بزنید. (تصویر 7)
با این کار درواقع داریم یک اسلاتِ به گوش درست میکنیم برای سیگنال Clicked دکمه. یعنی به فارسیاش میشه این: یک تابع از نوع Slot تعریف میکنیم که هر وقت دکمه کلیک شد فراخوانی بشه.
کدهای زیر را مطابق شکل 8 الف وارد کرده و کلید Ctrl + R یا دکمهی سبز پایین سمت چپ کیوت کریتور را بزنید تا برنامه اجرا شود. (اگر احیاناً پنجرهی Save Changes ظاهر شد Save All رو بزنید)
درصورتیکه کدهایتان را بهدرستی نوشته باشید خروجیای شبیه تصویر 9 مشاهده خواهید کرد. زیباست نه؟! دیدید که همزمان با کد C++ چگونه از HTML و CSS هم داخل کدمان برای زیباتر شدن کار استفاده کردیم. این کار ضرورتی نداشت لذا میتوانستید بهجای تگ، متن ساده بنویسید.(مثل تصویر 8 ب)
خب تبریک عرض میکنم اولین برنامهی کیوت خودتان رو نوشتید!
تصویر 1 سیگنال و اسلات Signals Slots
تصویر ۲ فرم خالی
تصویر ۳ اضافه کردن 4 عدد Label
تصویر 4 اضافه کردن 2 عدد LineEdit
تصویر 5 اضافه کردن یک عدد PushButton
تصویر 6 راست کلیک روی دکمه و انتخاب #Go_to_slot...
تصویر 7 انتخاب نوع #سیگنال #Clicked برای دکمه
تصویر 8 الف نوشتن کد برای عکس العمل دکمه هنگام کلیک شدن (بکاربردن HTML و CSS در متن پیغام)
تصویر 8 ب نوشتن کد برای عکس العمل دکمه هنگام کلیک شدن (متن ساده)
خروجی فرم ساده ی Login
این هم کد اسلات دکمه برای دوستانی که طرفدار کپی پیست هستند صرفا برای بالا بردن دقت(نه خدای ناکرده تنبلی!!):
void MainWindow::on_pushButton_clicked() { if(ui->lineEdit->text()==\"admin\" && ui->lineEdit_2->text()==\"admin\"){ ui->label_4->setText(\"شما با موفقیت وارد شدید\"); }else{ ui->label_4->setText(\"لطفا مجددا سعی فرمایید!\"); } }
اما توضیحاتی مختصر درباره این کدها عرض کنم و ادامه را موکول کنیم به جلسه/جلسات بعد:
نکته 1: برای دسترسی به هر ویجتی در کیوت، چون همه ی ویجت ها جزو UI برنامه به حساب میان(بعلاوه ی چند دلیل جدی تر و درست تر که این جلسه بهش نمی رسیم)، از فضای اسمی ui استفاده میکنیم. سپس دات(نقطه - dot) و ID ویجت. یعنی اگر بخواهیم دسترسی به متن یک تسکت باکس(LineEdit) با آی.دی myLineEdit داشته باشیم باید بنویسیم:
ui->myLineEdit->text()
اما چرا اون رو اینجوری نمی نویسیم؟
دلیلش را با گفتن یک کلمه ی کلیدی به خودتان واگذار میکنم که تحقیق کنید:
Pointer ها یا اشاره گرها
نکته ۲:
برای خواندن/ نوشتن مقادیر ویجتها باید از Setter/Getter استفاده کنیم که در مباحث پایه ای زبان C++ بهش میرسیم.
بطور ساده و محدود: هیچ وقت نمی توان مقادیر متغییرهای کلاسهای کیوت را بطور مستقیم تغییر داد یا خواند. بلکه باید برای این کار از توابع مخصوصی که بدین منظور تعیین شده است استفاده کرد. مثل تابع text() در LineEdit که مسئول خواندن متن داخل تسکت باکس و setText() در Label که مسئول تغییر متن برچسب می باشد.
خب این جلسه هم تمام شد. امیدوار بودم برسم که دو جلسه ی متوالی رو در خدمتتون باشم اما متاسفانه وقت نیست و باید بیفتم دنبال غم نان و جان و خان(این آخری منظورم انتخابات بود).
براتون آرزوی موفقیت، آسمانی آبی، دلی سرخ و شاد و تنفسی عمیق و آرام را دارم.
تا جلسه آینده بدرود.
نظرات کاربران