نخستین برنامه با PyQt5

در چارچوب Qt (و همچنین PyQt) دو شیوه ساخت برنامه GUI هست که یکی از آنها همان شیوه گذشته تا کنون است که در همه سیستم عامل ها برای ساخت برنامه های GUI دیده ایم. در این شیوه بر پایه ماژولی به نام QtWidgets است. شیوه تازه تر، QML نام دارد که شیوه ای اعلامی (Declarative) است. بنابراین دو شیوه برای ساخت GUI در Qt داریم:

  • واسط کاربری بر پایه ویجت (Widget-based User Interfaces)
  • واسط کاربری بر پایه QML (یا QML Graphical User Interfaces)

ساخت نخستین ویجت با کلاس QWidget

ماژول QtWidgets دارای سه کلاس به نام های QDialog و QWidget و QMainWindow است که همگی یک پنجره (Window) را نمایش می دهند. QMainWindow یک ویجت با قابلیت افزوده شدن دیگر ویجت ها مانند QToolBar یا QMenuBar یا QStatusBar است ولی اینها را نمی توان بر روی QWidget یا QDialog افرود. ولی دیگر ویجت ها مانند QLabel یا QTextEdit یا QLineEdit و دیگر ویجت ها را بر روی هر سه تای اینها اضافه کینم. شکل زیر یک QWidget را نشان می دهد که دیگر ویجت ها روی آن چسبانده شده اند.

کلاس QWidget

در کد و شکل زیر نخست ماژول sys از پایتون به برنامه پیوست شده است زیرا پس از این به متد ()exit از آن نیاز داریم. سپس دو کلاس QApplication و QWidget از ماژول PyQt5.QtWidgets به برنامه پیوست شده اند. در Qt دو کلاس به نام های QCoreApplication و QApplication هستند که جریان و روند اجرای برنامه کیوت را اداره می کنند. QCoreApplication ویژه برنامه های کنسولی (غیر GUI) و QApplication ویژه برنامه GUI است.

https://virgool.io/@linux_internals/%D9%86%D8%AE%D8%B3%D8%AA%DB%8C%D9%86-%D8%A8%D8%B1%D9%86%D8%A7%D9%85%D9%87-%DA%A9%D9%86%D8%B3%D9%88%D9%84%DB%8C-qt-%D9%88-%DA%86%D8%A7%D9%BE-%D8%AE%D8%B1%D9%88%D8%AC%DB%8C-%D8%A8%D8%A7-qdebug-ukiawgf7m8xf

بنابراین چه در زبان سی پلاس پلاس و چه در PyQt و زبا پایتون برای ساخت یک برنامه بر پایه ویجت نیاز به کلاس QApplication داریم. بنابراین هر برنامه GUI در کیوت تنها نیاز به یک شی (نمونه) از کلاس QApplication دارد بدون توجه به اینکه آیا برنامه هیچ، یک، دو یا بیشتر پنجره در یک زمان داشته باشد.

کلاس QApplication بر پایه پیکربندی میزکار (Desktop) سیستم عامل مانند فونت سراسری میزکار، برنامه کیوت را راه اندازی می کند. بنابراین QApplication از پیکربندی های میزکار آگاه است و نمای برنامه با تغییر این پیکربندی ها، در راه اندازی دوباره، اعمال می شوند.

برنامه نویسی رویدا گرا

برنامه های GUI از دسته برنامه رویداد گرا (Event Oriented) هستند به گونه ای که زمانی که برنامه اجرا می شود، در انتظار ورود یک رویداد مانند کلیک شدن ماوس یا فشردن یک دگمه می ماند. QApplication وظیفه اداره کردن رویداد ها را دارد. هر رویداد باید بدست یک مولفه از برنامه پاسخ داده شود. به عبارت دیگر QApplication به گونه ای است که می داند کدام مولفه باید پاسخ گوی یک رویداد مانن فشرده شده یک دگمه باشد.

مفهوم Event Loop یا حلقه رویداد به این اشاره دارد که پس از آغاز برنامه کیوت، در یک حلقه بی پایان، برنامه به رویداد های ورودی گوش می دهد و هر رویداد را به پاسخ دهنده خودش واگذار می کند. در کد زیر یک تابع به نام ()make_window نوشته ایم که درون بدنه آن، پیش از هر چیز نمونه ای از کلاس QApplication به نام متغیر app ساخته می شود. سپس بی توجه به کدهای دیگر، در خط پایانی از کدهای تابع (خط ۱۱) متد ()exit از ماژول sys فرخوانی شده است که متد ()_exec از کلاس QApplication به آن فرستاده شده است.

app = QApplication(sys.argv)
# Codes
sys.exit(app.exec_())

کلاس QWidget

پس ساخت یک نمونه از کلاس QApplication و فرستادن متد ()_exec از آن به متد ()exit از ماژول sys نوبت به ساخت یک پنجره با کلاس QWidget است. در خط ۶ از کد بالا، یک نمونه از کلاس QWidget به نام main_widget ساخته ایم.

main_widget = QWidget()

سپس پشت هم دو متد از چندین متد کلاس QWidget را فراخوانی و مقداردهی کرده ایم. در خط ۸ متد ()setWindowTitle فراخوانی شده است که یک رشته برابر با عنوان پنجره را دریافت کرده و سپس آن رشته را برای عنوان پنجره انتخاب می کند. در خط ۷، متدی به نام ()setGeometry فراخوانی شده است. این متد در کلاس QWidget به گونه Overload است، یعنی دو متد همنام ولی با ورودی های گوناگون در کلاس شناسانده شده است.

در خط ۷ متد ۴ورودی شماره صحیح را دریافت می کند که دو پارامتر نخست x و y هستند که مختصات نقطه ای از نمایشگر را نشان نی دهند که پنجره در آن جا نمایش داده می شود. دو پارامتر دیگر width و height هستند که عرض و طول پنجره را نشان می دهند. در کد بالا طول و عرض برابر با ۲۰۰ هستند ولی شما می توانید هر چهار گزینه را تغییر دهید.

main_widget.setGeometry(200, 200, 500, 300)
main_widget.setWindowTitle(&quotPyQt5 Application&quot)

پس از هر گونه پیکربندی که برای یک QWidget مشخص کردیم، باید پیش از کد مربوط به تابع ()_exec، باید متد ()show از کلاس QWidget را فراخوانی کنیم تا پنجره ساخته شده با این کلاس نمایش داده شود. این متد تنها برای کلاس QWidget نیست، بلکه برای دو کلاس دیگر، یعنی ()QDialog و QMainWindow نیز هست.

  • متد ()show بدون توجه به اینکه در کدام یک از این سه کلاس فراخوانی می شود، باید پیش از دستور (()_sys.exit(app.exec فراخوانی شود.
  • تمامی پیکربندی های یک پنجره باید پیش از این متد مشخص شوند.
  • همه ویجت های دیگر که می خواهیم روی پنجره چسبانده شوند نیز باید پیش از این متد ساخته شوند.

کلاس QRect

از کلاس QRect که در زیر ماژول QtCore جای دارد برای آماده سازی پارامترهای یک مسطتیل و یا بهتر است بگوییم برای آماده سازی پارامترهای یک چهارگوش (مربع و مستطیل) به کار گرفته می شود. برای نمایش یک چهارگوش به یک مختصات (x, y) و اندازه طول و عرض (w, h) نیاز داریم. مختصات (x, y) نقطه سمت چپ و بالای مستطیل است و با داشتن این نقطه و همچنین با داشتن اندازه طول و عرض دیگر می توان یک چهار گوش را کشید.

متد سازنده این کلاس از چپ به راست چهار پارامتر x و y و w و h را دریافت می کند. در کد زیر یک متغیر به نام rect ساخته ایم که نمونه ای از کلاس QRect است و به یک چهارگوشی اشاره می کند که می خواهیم برای ساخت یک پنجره به کار ببریم. همچنین باید در بالای فایل کلاس QRect از PyQt5.QtCore را پیوست کرده باشید.

‍‍from PyQt5.QtCore import QRect

rect = QRect(200, 200, 500, 300)

بنابراین در خط های ۱۰ و ۱۱ از شکل زیر نخست یک نمونه از کلاس QRect به نام متغیر rect ساخته شده و سپس متغیر rect به متد ()setGeometry فرستاده شده است. بنابراین متد ()setGeometry به گونه Overload شده است و دو تعریف از آن در کلاس QWidget هست که یکی چهار شماره صحیح (یا همان پارامترهای کشیدن چهارگوش) و دیگری نمونه ای از کلاس QRect را دریافت می کند.

توجه کنید در کدهای بالا پنجره QWidget از نقطه ای در مخصتات (x=200, y=200) کشیده می شود که این مختصات نقطه ای در نمایشگر هست ولی من پنجره را برای نمایش یکجا، درون VSCode جای داده ام. در پایان هر دو کد نیز، تابع ()make_window در خط پایانی فراخوانی شده است.

پنجره با اندازه ثابت

اگر بخواهیم پنجره ساخته شده با کلاس QWidget دارای اندازه ثابتی باشد، باید متد ()seFixedSize رابه کار ببریم. این متد به گونه Overload شده است و در نخستین تعریف آن، دو شماره صحیح برای طول و عرض پنجره دریافت می شود. با فراخوانی این متد دیگر نمی توان اندازه پنجره را نه کوچک و نه بزرگ کرد.

در کدهای بازهم برای تعیین اندازه ویجت از متد ()setGeometry کمک گرفیتم ولی به دنبال آن متد ()setFixedSize با اندازه های یکسان طول و عرض فرستاده شده به ()setGeometry فراخوانی شده است، پس از این پس عرض و طول پنجره به ترتیب ۵۰۰ و ۳۰۰ خواهد بود. ولی اگر اندازه های فرستاده شده به ()setFixedSize با ()setGeometry یکسان نباشد چه می شود؟ برای نمونه در کد زیر اندازه های فرستاده شده به ()setFixedSize برابر با ۳۰۰ و ۳۰۰ است، پس در پایان اندازه های پنجره برابر با ۳۰۰ و ۳۰۰ و همچنین غیر قابل تغییر می شود.

main_widget.setFixedSize(300, 300)

کلاس QSize

بنابراین اگر بخواهیم اندازه های یک پنجره کلاس QWidget ثابت بماند، دیگر نیازی به ()setGeometry نیست ولی اگر بخواهیم اندازه های ثابت داشته باشیم و همچنین پنجره در مختصانی ویژه نشان داده شود، نخست نیاز به ()setGeometry و سپس ()setFixedSize داریم.

در QtCore یک کلاس به نام QSize هست که به کمک آن اندازه هایی برای دو بعد پهنا (Width) و درازا (ارتفاع - Height) را نشان می دهیم. متد ()setFixedSize نیز دارای دو تعریف است که در بالادو شماره صحیح رادریافت کرد ولی در دومین تعریف تنها یک نمونه از کلاس QSize را دریافت می کند.

در کد زیر نخست یک نمونه از کلاس QSize به نام fixed_size ساخته ایم و سپس آن را به متد ()setFixedSize فرستاده ایم. همچنین ببینید که دیگر متد ()setGeometry را فراخوانی نکرده ایم و تنها یکباره خود متد ()setFixedSize را برخوانی کرده ایم.

بنابراین در این نوشته با سه کلاس QWidget و QRect و QSize آشنا شدیم که به ترتیب برای ساخت پنجره، نمایش پارامترهای یک چهارگوش و نمایش دو نقطه به کار گرفته می شوند. کلاس QWidget دارای ویژگی ها و متدهای دیگری است که می توانید از اینجا بخوانید.

https://virgool.io/@linux_internals/نصب-pyqt5-به-همراه-qt-designer-yuw7a3ybahzs
https://virgool.io/@linux_internals/پیشگفتاری-بر-pyqt5-nkx6r3aemacf
https://dataset-academy.com