Python Programming

ساخت برنامه‌های دسکتاپ چندسکویی با PyQt6: سیگنال‌ها، اسلات‌ها و یکپارچه‌سازی QML مدرن

زمینه توسعه برنامه‌های دسکتاپ به طور قابل توجهی تغییر کرده است. توسعه‌دهندگان دیگر به سینتکس خشک و طولانی رابط‌های مبتنی بر ویجت محدود نیستند. در عوض، تقاضا برای رابط‌های کاربری زیبا، واکنش‌گرا و کاملاً قابل سفارشی‌سازی، فناوری‌هایی مانند Qt و پایتون را به پیشانی صحنه آورده است. PyQt6، جدیدترین نسخه از bindings محبوب پایتون برای Qt، چارچوبی قدرتمند برای ساخت برنامه‌های دسکتاپ چندسکویی ارائه می‌دهد. در این راهنما، ما بررسی خواهیم کرد که چگونه می‌توان از مکانیسم‌های مدرن سیگنال-اسلات استفاده کرد و QML (زبان شیء متا Qt) را یکپارچه ساخت تا رابط‌های گرافیکی چشم‌نوازی ایجاد شود که به راحتی روی ویندوز، مک‌او‌اس و لینوکس اجرا می‌شوند.

چرا PyQt6 و QML؟

در حالی که PyQt6 منطق قدرتمند نسخه پیشین خود را حفظ کرده است، اما بهبودهای عملکردی، راهنمایی‌های نوع (type hinting) بهتر و API تمیزتری را معرفی می‌کند. با این حال، قدرت واقعی Qt در زبان رابط کاربری اعلانی آن، یعنی QML نهفته است. QML به توسعه‌دهندگان اجازه می‌دهد تا رابط‌ها را با استفاده از سینتکسی شبیه به جاوااسکریپت طراحی کنند و لایه بصری را از منطق کسب‌وکار که در پایتون قرار دارد، جدا کند. این جدایی دغدغه‌ها منجر به کدهای تمیزتر و نگهداری آسان‌تر می‌شود. با ترکیب قدرت محاسباتی پایتون و قابلیت‌های رندرینگ QML، می‌توانید برنامه‌هایی بسازید که ظاهری بومی دارند و احساس سرعت فوق‌العاده‌ای منتقل می‌کنند.

سیگنال‌ها و اسلات‌های مدرن

سیگنال‌ها و اسلات‌ها ستون فقرات مدیریت رویدادها در Qt هستند. آن‌ها راهی ایمن از نظر نوع و جدا شده برای ارتباط بین اشیاء فراهم می‌کنند. در PyQt6، سینتکس برای پایتونیک‌تر شدن اصلاح شده است. یک سیگنال توسط یک شیء ارسال می‌شود و یک اسلات (یک تابع فراخوانی‌پذیر) به عنوان پاسخ اجرا می‌شود. اتصال می‌تواند مستقیم، صف‌بندی شده یا مسدود باشد که بستگی به زمینه رشته‌ای (threading context) دارد و ایمنی رشته را بدون مکانیسم‌های قفل‌گذاری صریح تضمین می‌کند.

یک رویداد کلیک ساده روی دکمه را در نظر بگیرید. در نسخه‌های قدیمی‌تر Qt، سینتکس ممکن است پیچیده‌تر بوده است. اکنون، با PyQt6، می‌توانید سیگنال‌ها را با استفاده از ارجاعات متد استاندارد یا لامبداها برای نمونه‌سازی سریع متصل کنید.

پیاده‌سازی یک اتصال سیگنال-اسلات پایه

بیایید به یک مثال عملی نگاه کنیم که در آن سیگنال کلیک یک دکمه را به یک متد پایتون متصل می‌کنیم. این الگو برای مدیریت تعاملات کاربر در هر برنامه دسکتاپی ضروری است.

import sys
from PyQt6.QtWidgets import QApplication, QWidget, QPushButton, QVBoxLayout
from PyQt6.QtCore import pyqtSlot

class MainWindow(QWidget):
    def __init__(self):
        super().__init__()
        
        self.setWindowTitle("PyQt6 Signals Demo")
        self.resize(300, 200)
        
        layout = QVBoxLayout()
        
        # Create a button
        self.btn = QPushButton("Click Me")
        
        # Connect the clicked signal to a slot
        self.btn.clicked.connect(self.on_button_click)
        
        layout.addWidget(self.btn)
        self.setLayout(layout)

    @pyqtSlot()
    def on_button_click(self):
        print("Button was clicked!")
        # Logic to update UI or perform calculations goes here

if __name__ == "__main__":
    app = QApplication(sys.argv)
    window = MainWindow()
    window.show()
    sys.exit(app.exec())

به استفاده از دکوراتور @pyqtSlot توجه کنید. اگرچه در موارد ساده اختیاری است، اما برای برنامه‌های پیشرفته بسیار توصیه می‌شود. این دکوراتور تضمین می‌کند که اسلات در رشته مرتبط با شیء دریافت‌کننده اجرا می‌شود و از شرایط رقابتی (race conditions) هنگام کار با چندین رشته جلوگیری می‌کند.

یکپارچه‌سازی QML با پایتون

با بزرگ‌تر شدن برنامه شما، مدیریت منطق رابط کاربری درون کلاس‌های پایتون می‌تواند دشوار شود. اینجاست که QML درخشش می‌کند. فایل‌های QML رابط کاربری را به صورت اعلانی تعریف می‌کنند، در حالی که پایتون منطق بک‌اند را مدیریت می‌کند. PyQt6 موتور QQmlApplicationEngine را برای پل زدن بین این دو جهان ارائه می‌دهد.

راه‌اندازی موتور QML

برای یکپارچه‌سازی QML، ابتدا یک فایل QML ایجاد می‌کنید که عناصر رابط کاربری شما را تعریف می‌کند. سپس این فایل را در یک برنامه PyQt6 بارگذاری می‌کنید. کلید این یکپارچه‌سازی، قرار دادن اشیاء پایتون در دسترس زمینه QML است.

import sys
from PyQt6.QtCore import QObject, pyqtProperty
from PyQt6.QtGui import QQmlApplicationEngine
from PyQt6.QtQml import qmlRegisterType

class DataModel(QObject):
    def __init__(self, parent=None):
        super().__init__(parent)
        self._message = "Hello from Python!"

    @pyqtProperty(str)
    def message(self):
        return self._message

    @message.setter
    def message(self, value):
        if self._message != value:
            self._message = value
            self.messageChanged.emit() # You would define this signal

    def update_message(self, new_text):
        self.message = new_text

if __name__ == "__main__":
    app = QApplication(sys.argv)
    
    engine = QQmlApplicationEngine()
    
    # Create a Python model and expose it to QML
    model = DataModel()
    engine.rootContext().setContextProperty("myModel", model)
    
    engine.load("main.qml")
    
    if not engine.rootObjects():
        sys.exit(-1)
        
    sys.exit(app.exec())

در فایل main.qml خود، اکنون می‌توانید ویژگی‌ها را مستقیماً به شیء پایتون متصل کنید. به عنوان مثال، یک عنصر Text می‌تواند myModel.message را نمایش دهد و یک دکمه می‌تواند myModel.updateMessage("New Text") را فراخوانی کند. این رویکرد کد رابط کاربری شما را مختصر و منطق کسب‌وکار شما را سازمان‌یافته نگه می‌دارد.

نتیجه‌گیری

ساخت برنامه‌های دسکتاپ چندسکویی با PyQt6 و QML یک استراتژی قدرتمند برای توسعه نرم‌افزار مدرن است. با بهره‌گیری از ماهیت اعلانی QML و استحکام پایتون، توسعه‌دهندگان می‌توانند برنامه‌هایی ایجاد کنند که نه تنها کاربردی، بلکه از نظر بصری جذاب و قابل نگهداری هستند. تسلط بر سیگنال‌ها، اسلات‌ها و ویژگی‌های زمینه، ارتباطی بدون اصطکاک بین رابط کاربری و منطق شما را تضمین می‌کند و تجربه کاربری واکنش‌گرا را فراهم می‌سازد. چه در حال ساخت یک ابزار تجسم داده باشید و چه یک برنامه سازمانی پیچیده، PyQt6 ابزارهای لازم را برای موفقیت در نرم‌افزار رقابتی امروز فراهم می‌کند.

Share: