تکمیل لایه نمایشی
رابط گرافیکی که در درس قبل ایجاد کرده اید، شبیه ماشین حساب واقعی نیست. پس این رابط گرافیکی را با هم و با افزودن دکمه ها و صفحه نمایش خروجی تکمیل خواهیم کرد (لایه ی نمایشی). همچنین قرار است دکمه هایی برای عملیات ساده ی ریاضی و دکمه ی پاکسازی صفحه نمایش اضافه کنید.
ابتدا نیاز دارید که موارد زیر را به بالای کد نوشته شده در درس قبل (قالب کلی برنامه) اضافه کنید:
from PyQt5.QtCore import Qt from PyQt5.QtWidgets import QGridLayout from PyQt5.QtWidgets import QLineEdit from PyQt5.QtWidgets import QPushButton from PyQt5.QtWidgets import QVBoxLayout
قرار است از QVBoxLayout برای چیدمان کلی ماشین حساب و از شی QGridLayout برای مرتب کردن دکمه ها استفاده کنید. در نهایت QLineEdit را برای صفحه نمایش و QPushButton را برای دکمه ها وارد برنامه می کنید. حالا باید 8 دستور import در بالای فایل خود داشته باشید.
اکنون می توانید سازنده ی (تابعی که به صورت خودکار برای کلاس ایجاد شده مقداردهی اولیه را انجام می دهد) کلاس PyCalcUi را به روز رسانی کنید.
# Create a subclass of QMainWindow to setup the calculator's GUI
class PyCalcUi(QMainWindow):
"""PyCalc's View (GUI)."""
def __init__(self):
"""View initializer."""
super().__init__()
# Set some main window's properties
self.setWindowTitle('PyCalc')
self.setFixedSize(235, 235)
# Set the central widget and the general layout
self.generalLayout = QVBoxLayout()
self._centralWidget = QWidget(self)
self.setCentralWidget(self._centralWidget)
self._centralWidget.setLayout(self.generalLayout)
# Create the display and the buttons
self._createDisplay()
self._createButtons()
اینجا خطوط کد با رنگ مختلف را اضافه کردید و از QVBoxLayout برای قرار دادن صفحه ی خروجی در بالا و دکمه ها در چیدمان شبکه ای در زیر آن استفاده خواهید کرد.
فراخوانی متدهای ()createDisplay_ و ()createButtons_ به دلیل عدم پیاده سازی موقتی آن ها در حال حاضر کار نخواهد کرد که در صدد حل آن، باهم کدنویسی می کنیم:
class PyCalcUi(QMainWindow):
# Snip
def _createDisplay(self):
"""Create the display."""
# Create the display widget
self.display = QLineEdit()
# Set some display's properties
self.display.setFixedHeight(35)
self.display.setAlignment(Qt.AlignRight)
self.display.setReadOnly(True)
# Add the display to the general layout
self.generalLayout.addWidget(self.display)
برای ایجاد ویجت صفحه ی خروجی ماشین حساب از شی QLineEdit استفاده و سپس خصوصیات زیر را تنظیم می کنید:
- این صفحه اندازه ی ثابت 35 پیکسلی دارد.
- این صفحه متن را به صورت چپ چین نمایش می دهد.
- صفحه باید فقط خواندنی باشد تا از ویرایش مستقیم جلوگیری به عمل آید.
خط آخری نیز صفحه ی خروجی را در چیدمان کلی ماشین حساب با استفاده از ()generalLayout.addWidget اضافه می کند.
سپس متد ()createButtons_. را پیاده سازی (نوشتن کدهای تعریف یک متد) می کنید تا دکمه های ماشین حساب را خلق کرده باشیم. برای نگهداری متن و موقعیت هر دکمه در شبکه نیز از دیکشنری استفاده خواهید کرد. همچنین QGridLayout برای مرتب کردن دکمه ها در پنجره ی ماشین حساب استفاده می شود. کد نهایی شبیه زیر خواهد بود:
# Snip
def _createButtons(self):
"""Create the buttons."""
self.buttons = {}
buttonsLayout = QGridLayout()
# Button text | position on the QGridLayout
buttons = {'7': (0, 0),
'8': (0, 1),
'9': (0, 2),
'/': (0, 3),
'C': (0, 4),
'4': (1, 0),
'5': (1, 1),
'6': (1, 2),
'*': (1, 3),
'(': (1, 4),
'1': (2, 0),
'2': (2, 1),
'3': (2, 2),
'-': (2, 3),
')': (2, 4),
'0': (3, 0),
'00': (3, 1),
'.': (3, 2),
'+': (3, 3),
'=': (3, 4),
}
# Create the buttons and add them to the grid layout
for btnText, pos in buttons.items():
self.buttons[btnText] = QPushButton(btnText)
self.buttons[btnText].setFixedSize(40, 40)
buttonsLayout.addWidget(self.buttons[btnText], pos[0], pos[1])
# Add buttonsLayout to the general layout
self.generalLayout.addLayout(buttonsLayout)
ابتدا یک دیکشنری خالی self.buttons را برای نگهداری دکمه ها ایجاد می کنید. سپس یک دیکشنری موقت را برای نگهداری برچسب ها و موقعیت های نسبی آن ها در روی شبکه (grid یا توری که به عنوان مجموعه ای از خطوط عمودی و افقی متقاطع می باشد) می سازید (buttonsLayout).
داخل حلقه ی for دکمه ها را ایجاد کرده و آن ها را به هر دوی self.buttons و buttonsLayout اضافه می کنید (دو دیکشنری مذکور). هر دکمه دارای اندازه ی ثابت 40*40 خواهد بود که با متد (40,40)setFixedSize. تنظیم می گردد.
حال لایه نمایش یا رابط گرافیکی ماشین حساب می تواند صفحه و بدنه را نشان دهد اما هنوز راهی برای بروزرسانی اطلاعات نمایشی روی صفحه خروجی نیست. مشکل بوسیله ی افزودن چند متد اضافه به شرح زیر حل می شود:
- ()setDisplayText. برای تنظیم و بروزرسانی متن صفحه ی خروجی ماشین حساب
- ()displayText. برای گرفتن متن جاری در صفحه ی خروجی ماشین حساب
- ()clearDisplay. برای پاکسازی متن موجود در صفحه ی مذکور
این متدها رابط عمومی گرافیکی را شکل می دهند و کلاس نمایش ماشین حساب پایتونی شما را کامل می کنند. در زیر یک پیاده سازی ممکن آمده است:
class PyCalcUi(QMainWindow):
# Snip
def setDisplayText(self, text):
"""Set display's text."""
self.display.setText(text)
self.display.setFocus()
def displayText(self):
"""Get display's text."""
return self.display.text()
def clearDisplay(self):
"""Clear the display."""
self.setDisplayText('')
عملی که هر تابع انجام می دهد به شرح زیر است:
- ()setDisplayText. از متد setText. برای بروزرسانی و تنظیم متن صفحه خروجی ماشین حساب و setFocus. نیز برای تنظیم توجه اشاره گر ماوس روی صفحه بکار می رود.
- ()displayText. یک متد getter (متدهایی که وظیفه ی آنها بدست آوردن مقادیر متغیرها و صفات موجود در کلاس می باشد) است که متن جاری در صفحه ی خروجی ماشین حساب را بازمی گرداند. هنگامی که کاربر روی علامت (=) کلیک می کند، برنامه از مقدار بازگشتی این متد به عنوان عبارت ریاضی جهت ارزیابی استفاده می کند.
- ()clearDisplay. متن صفحه ی خروجی ماشین حساب را به رشته ی خالی (‘ ‘) تنظیم می کند تا کاربر بتواند عبارت ریاضی جدید را وارد کند.
حالا رابط کاربری ماشین حسابتان آماده شده است و اگر اجرا شود، پنجره ای مانند زیر را خواهید دید:

رابط گرافیکی برنامه را با موفقیت تمام کردید ولی متوجه خواهید شد که ماشین حسابتان کاری انجام نمی دهد و آن هم به دلیل عدم پیاده سازی لایه ی مدل و کنترلگر می باشد. بعد از این یک کلاس ساده ی کنترلگر برای آغاز حیات برنامه به آن اضافه خواهیم کرد.
منبع: سایت Real Python
