درس یازدهم: تکمیل لایه‌ی نمایشی

07 اردیبهشت 1399
pyqt11

تکمیل لایه نمایشی

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

ابتدا نیاز دارید که موارد زیر را به بالای کد نوشته شده در درس قبل (قالب کلی برنامه) اضافه کنید:

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. تنظیم می گردد.

نکته: وقتی بحث اندازه ی ویجت می شود، باید گفت که در PyQt به ندرت می توانید واحدهای اندازه گیری را پیدا کنید. فرض می شود که واحد اندازه گیری، پیکسل باشد (بجز QPrinter که از نقاط یا points استفاده می کند.

حال لایه نمایش یا رابط گرافیکی ماشین حساب می تواند صفحه و بدنه را نشان دهد اما هنوز راهی برای بروزرسانی اطلاعات نمایشی روی صفحه خروجی نیست. مشکل بوسیله ی افزودن  چند متد اضافه به شرح زیر حل می شود:

  1. ()setDisplayText. برای تنظیم و بروزرسانی متن صفحه ی خروجی ماشین حساب
  2. ()displayText. برای گرفتن متن جاری در صفحه ی خروجی ماشین حساب
  3. ()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

تمام فصل‌های سری ترتیبی که روکسو برای مطالعه‌ی دروس سری ساخت ماشین حساب گرافیکی با PyQt توصیه می‌کند:
نویسنده شوید

دیدگاه‌های شما

در این قسمت، به پرسش‌های تخصصی شما درباره‌ی محتوای مقاله پاسخ داده نمی‌شود. سوالات خود را اینجا بپرسید.