درس چهارم: یادگیری مبانی (Layout Managers)

15 اردیبهشت 1399

چینش گرها یا Layout Managers در PyQt

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

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

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

موثرترین روش جایگزین هم استفاده از چینش گرهاست که هم بهره وری و هم قابلیت نگهداری برنامه تان را افزایش می دهد.

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

نکته: در طراحی برنامه های جهانی و ترجمه ی برچسب ها شاید دیده باشید که برچسب به دلیل پر واژه بودن زبان مقصد، کوتاه تر از طول عبارت است در این حالات هم باز چینش گرها به کمک طراح برنامه می آیند.

PyQt چهار چینش گر پایه را ارائه می دهد:

  1. QHBoxLayout
  2. QVBoxLayout
  3. QGridLayout
  4. QFormLayout

اولین کلاس از لیست بالا ویجت ها را به صورت افقی از چپ به راست مرتب می کند:

کلاس QHBoxLayout

ویجت ها یکی پس از دیگری از چپ کنار هم قرار می گیرند.

این کد نمونه که در زیر آمده است، استفاده از این کلاس چینش گر را به شما نشان می دهد. دقت کنید که دکمه ها به صورت افقی کنار هم مرتب شده اند:

# Filename: h_layout.py

"""Horizontal layout example."""

import sys

from PyQt5.QtWidgets import QApplication
from PyQt5.QtWidgets import QHBoxLayout
from PyQt5.QtWidgets import QPushButton
from PyQt5.QtWidgets import QWidget

app = QApplication(sys.argv)
window = QWidget()
window.setWindowTitle('QHBoxLayout')
layout = QHBoxLayout()
layout.addWidget(QPushButton('Left'))
layout.addWidget(QPushButton('Center'))
layout.addWidget(QPushButton('Right'))
window.setLayout(layout)
window.show()
sys.exit(app.exec_())

خطوط با رنگ نارنجی نیاز به توضیح دارند:

  • خط 15 یک شئ از QHBoxLayout به نام layout ایجاد می کند.
  • خطوط 16 تا 18 با استفاده از ()setLayout. سه دکمه به layout تعریف شده اضافه می کنند.
  • خط 19 layout را به عنوان چینش گر، پنجره با استفاده از ()setLayout. تنظیم می کند.

وقتی این برنامه را اجرا کنید با خروجی زیر مواجه خواهید شد:

کلاس QHBoxLayout

توجه کنید که دکمه ها از چپ به راست به ترتیبی که در روی کد افزودید کنار هم قرار می گیرند.

کلاس بعدی QVBoxLayout است که ویجت ها را به صورت عمودی از بالا به پایین مرتب می کند.

کلاس QVBoxLayout

هر ویجت جدید در زیر ویجت قبلی ظاهر می شود. با این کلاس می توان چیدمان جعبه ای ایجاد کرده و ویجت ها را از بالا به پایین سازماندهی نمود.

در زیر نحوه ی ایجاد و استفاده از شئ QVBoxLayout را می بینید:

# Filename: v_layout.py

"""Vertical layout example."""

import sys

from PyQt5.QtWidgets import QApplication
from PyQt5.QtWidgets import QPushButton
from PyQt5.QtWidgets import QVBoxLayout
from PyQt5.QtWidgets import QWidget

app = QApplication(sys.argv)
window = QWidget()
window.setWindowTitle('QVBoxLayout')
layout = QVBoxLayout()
layout.addWidget(QPushButton('Top'))
layout.addWidget(QPushButton('Center'))
layout.addWidget(QPushButton('Bottom'))
window.setLayout(layout)
window.show()
sys.exit(app.exec_())

در خط 15 نمونه ای از QVBoxLayout ایجاد می کنید و در سه خط بعدی سه دکمه به layout اضافه می کنید و نهایتا از layout برای چیدمان عمودی ویجت ها استفاده می نمایید.

هنگام اجرای این برنامه با خروجی شبیه زیر مواجه خواهید شد:

کلاس QVBoxLayout

این برنامه سه دکمه را یکی زیر دیگری نشان می دهد. دقت کنید که این دکمه ها به ترتیبی که در کد به برنامه اضافه کرده اید، قرار میگیرند.

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

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

کلاس QGridLayout - مفهوم Layout Managers در PyQt

QGridLayout فضای اختصاص داده شده به آن را بوسیله ی کلاس مادر خود می گیرد و آن را به ردیف ها و ستون هایی تقسیم می کند که هر ویجت را در سلول مربوطه اش بگذارد.

# Filename: g_layout.py

"""Grid layout example."""

import sys

from PyQt5.QtWidgets import QApplication
from PyQt5.QtWidgets import QGridLayout
from PyQt5.QtWidgets import QPushButton
from PyQt5.QtWidgets import QWidget

app = QApplication(sys.argv)
window = QWidget()
window.setWindowTitle('QGridLayout')
layout = QGridLayout()
layout.addWidget(QPushButton('Button (0, 0)'), 0, 0)
layout.addWidget(QPushButton('Button (0, 1)'), 0, 1)
layout.addWidget(QPushButton('Button (0, 2)'), 0, 2)
layout.addWidget(QPushButton('Button (1, 0)'), 1, 0)
layout.addWidget(QPushButton('Button (1, 1)'), 1, 1)
layout.addWidget(QPushButton('Button (1, 2)'), 1, 2)
layout.addWidget(QPushButton('Button (2, 0)'), 2, 0)
layout.addWidget(QPushButton('Button (2, 1) + 2 Columns Span'), 2, 1, 1, 2)
window.setLayout(layout)
window.show()
sys.exit(app.exec_())

در این مثال یک برنامه که از شئ QGridLayout برای سازماندهی ویجت هایش استفاده می کند، بهره می برید. در خط 23 دو پارامتر جدید به متد ()addWidget. اضافه می کنید که rowspan و columnspan خوانده می شوند. استفاده از این ها موجب اشغال کردن بیش از یک ردیف یا ستون توسط ویجت می گردد همانطور که اینجا با  QPushButton('Button (2, 1) + 2 Columns Span')انجام دادید.

اگر این اسکریپت را اجرا کنید پنجره ی زیر را در خروجی نشان می دهد:

کلاس QGridLayout - مفهوم Layout Managers در PyQt

می بنید که ویجت های شما در شبکه ای از ردیف ها و ستون ها مرتب شده اند. آخرین ویجت نیز بیش از یک سلول را اشغال نموده است (دستور خط 23).

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

کلاس QFormLayout - مفهوم Layout Managers در PyQt

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

کد زیر نحوه ی ایجاد برنامه ای را که از QFormLayoutبرای مرتب کردن ویجت هایش  استفاده می کند، نشان می دهد:

# Filename: f_layout.py

"""Form layout example."""

import sys

from PyQt5.QtWidgets import QApplication
from PyQt5.QtWidgets import QFormLayout
from PyQt5.QtWidgets import QLineEdit
from PyQt5.QtWidgets import QWidget

app = QApplication(sys.argv)
window = QWidget()
window.setWindowTitle('QFormLayout')
layout = QFormLayout()
layout.addRow('Name:', QLineEdit())
layout.addRow('Age:', QLineEdit())
layout.addRow('Job:', QLineEdit())
layout.addRow('Hobbies:', QLineEdit())
window.setLayout(layout)
window.show()
sys.exit(app.exec_())

خطوط 15 تا 20 در این مثال اصلی ترین کار را انجام می دهند. توجه کنید که QFormLayout یک متد دم دست به نام ()addRow. دارد که با استفاده از این می توان یک ردیف دارای دو ویجت را به چیدمان افزود. اولین آرگومان یا پارامتر این متد برچسب و دومی یک نوع ویجت با قابلیت دریافت ورودی یا ویرایش داده است.

خروجی این کد به صورت زیر است:

کلاس QFormLayout - مفهوم Layout Managers در PyQt

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

امیدواریم بحث مفهوم Layout Managers در PyQt برای شما مفید بوده باشد.


منبع: سایت Real Python

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

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