ویجت های PyQt به عنوان گیرنده ی رویداد عمل می کنند، یعنی هر ویجت می تواند تعداد خاصی از رویدادها را بگیرد؛ مثل کلیک ماوس، فشردن کلیدها و... در پاسخ به این رویدادها ویجت ها همواره یک سیگنالی را منتشر می کنند که نوعی پیام مبنی بر تغییر در وضعیت خود می باشد.
سیگنال به خودی خود نمی تواند فعالیتی را انجام دهد. اگر می خواهید یک سیگنال فعالیتی را انجام دهد نیاز به متصل کردن آن به یک شکاف یا همان slot دارید. این یک تابع یا متد است که فعالیتی را در هنگام انتشار سیگنال متصل شده انجام می دهد. شما می توانید هر مورد قابل فراخوانی از پایتون را به عنوان اسلات استفاده نمایید.
درصورتیکه یک سیگنال به یک اسلات متصل شده باشد، پس زمانیکه سیگنال منتشر می شود اسلات فراخوانی می گردد. در صورتی هم که سیگنالی به هیچ اسلاتی متصل نباشد هیچ اتفاقی نخواهد افتاد و سیگنال منتشر شده قابل چشم پوشی خواهد بود. در زیر مهم ترین خصوصیات این مکانیسم آمده است:
می توانید سینتکس یا دستور کلی زیر را برای اتصال یک سیگنال به شکاف استفاده کنید:
widget.signal.connect(slot_function)
این دستور slot_function را به widget.signal متصل خواهد کرد. هرزمان که signal منتشر شد ()slot_function فراخوانی خواهد گردید.
در نهایت کد زیر هم نحوه ی استفاده از مکانیزم سیگنال ها و شکاف ها را نشان می دهد:
# Filename: signals_slots.py """Signals and slots example.""" import sys from PyQt5.QtWidgets import QApplication from PyQt5.QtWidgets import QLabel from PyQt5.QtWidgets import QPushButton from PyQt5.QtWidgets import QVBoxLayout from PyQt5.QtWidgets import QWidget def greeting(): """Slot function.""" if msg.text(): msg.setText("") else: msg.setText("Hello World!") app = QApplication(sys.argv) window = QWidget() window.setWindowTitle('Signals and slots') layout = QVBoxLayout() btn = QPushButton('Greet') btn.clicked.connect(greeting) # Connect clicked to greeting() layout.addWidget(btn) msg = QLabel('') layout.addWidget(msg) window.setLayout(layout) window.show() sys.exit(app.exec_())
در خط 13 ()greeting را ایجاد می کنید که به عنوان اسلات از ان استفاده خواهید کرد. سپس در خط 26 سیگنال ناشی از کلیک دکمه(clicked) را به ()greeting متصل می کنید. با این روش هنگامی که کاربر روی دکمه کلیک می کند greeting فراخوانی شده و msg
بین پیغام "hello world" و یک رشته خالی عوض و بدل خواهد شد.
وقتی بر روی greet کلیک میکنید پیغام "hello world" در روی صفحه ظاهر و یا پنهان خواهد شد.
نکته: هر ویجت دارای مجموعه ای از سیگنال های از پیش تعریف شده ی خود می باشد که می توانید آن ها را از صفحه ی اسناد مربوط به آن ویجت بررسی کنید.
اگر تابع اسلات شما نیاز به دریافت آرگومان های اضافه دارد، می توانید آن ها را با استفاده از functools.partial به تابع گذر بدهید. برای نمونه می توانید greeting را به صورت زیر تغییر دهید:
def greeting(who): """Slot function.""" if msg.text(): msg.setText('') else: msg.setText(f'Hello {who}')
حالا ()greeting نیاز به دریافت یک آرگومان به نام who دارد. اگر می خواهید این نسخه ی جدید از آن را به سیگنال btn.clicked
متصل کنید، می توانید کاری به شکل زیر انجام دهید:
btn.clicked.connect(functools.partial(greeting, 'World!'))
برای اینکه این کد کار کند ابتدا نیاز دارید که functools
را وارد برنامه کنید. فراخوانی ()functools.partial یک شئ که همانند فراخوانی ()greeting با '!who='world عمل می کند را برمی گرداند. حال وقتی کاربر روی دکمه کلیک می کند، پیغام «سلام دنیا!» همانند قبل بر روی صفحه نشان داده خواهد شد.
توجه: همچنین می توانید از توابع لاندا برای اتصال سیگنال به یک اسلاتی که نیازمند آرگومان های اضافی است، استفاده کنید (توابع لاندا توابع غیررسمی در پایتون هستند که فارغ از دستور def و بدون نام ایجاد می شوند). برای تمرین کد بالا را با استفاده از لاندا بجای ()functools.partial امتحان کنید.
مکانیزم اسلات ها و سیگنال ها چیزی است که برای جان بخشی به برنامه با رابط گرافیکی PyQt استفاده می شود. این مکانیزم موجب تبدیل رویدادهای کاربر به عملیات واقعی می گردد. می توانید با نگاه کردن به PyQt5 documentation در سیگنال ها و اسلات ها عمیق تر بپرید!
تا اینجا مهم ترین مفاهیم PyQt5 را به اتمام رساندید. با این دانش و کتابخانه ی اسناد مربوطه در دست، آماده ی آغاز به کار طراحی برنامه های گرافیکی خود هستید. در بخش های بعدی اولین برنامه با رابط گرافیکی تابع گرای محض را خواهید ساخت.
منبع: سایت Real Python
در این قسمت، به پرسشهای تخصصی شما دربارهی محتوای مقاله پاسخ داده نمیشود. سوالات خود را اینجا بپرسید.