目次
シグナルとスロットを使用する理由
シグナルとスロットを使用する利点は、コードをより小さく再利用可能な部分に分割できるため、コードが読みやすく、保守しやすくなることです。このメカニズムにより、異なるオブジェクトが相互にメソッドを直接呼び出すことなく通信できるようになります。
関数を直接呼び出すと、コードが密結合になり、コードのメンテナンスや拡張に役立ちません。さらに、シグナルとスロットは異なるスレッド間で通信できるため、マルチスレッド プログラミングもシグナルとスロットを使用して簡単に実装できます。
これがシグナルとスロットを使用する目的です。
- コード間のデカップリングに使用されます
- 子スレッドはメインスレッドにインターフェースを更新するように通知します。
ファイル内の信号とスロットを定義する
PyQt でシグナルとスロットをカスタマイズする手順は次のとおりです。
- シグナルの定義: クラス内でシグナルを定義し、PyQt のシグナル メカニズムを使用してカスタム シグナルを実装します。信号オブジェクトは
pyqtSignal()
メソッドを通じて作成できます。 pyqtSignal パラメータ スロット関数のパラメータ タイプ- シグナルが配置されるクラス: QObject を継承し、初期化関数でスーパー初期化関数を呼び出す必要があります。
- スロットの定義: クラス内にスロット関数を定義し、
@pyqtSlot()
デコレータを使用してメソッドをスロット関数として登録します。- 信号とスロットを接続する:
信号.connect(槽函数)
メソッドを使用して信号とスロットを接続します。- トリガー信号: トリガー信号が必要な場合は、
信号.emit()
メソッドを使用して信号をトリガーします。パラメーターはスロット関数のパラメーターと一致します。
以下は、PyQt を使用してカスタム信号とスロットを作成する方法を示す簡単な例です。
from PyQt5.QtCore import pyqtSignal, pyqtSlot, QObject
class MyObject(QObject):
# 定义一个自定义信号
my_signal = pyqtSignal(str)
# 定义一个槽函数
@pyqtSlot(str)
def my_slot(self, message):
print("Received message: ", message)
# 创建一个对象
obj = MyObject()
# 连接信号和槽
obj.my_signal.connect(obj.my_slot)
# 触发信号
obj.my_signal.emit("Hello, World!")
上記の例では、最初にmy_signal
という名前のカスタム信号を定義しました。次に、 my_slot
という名前のスロット関数を定義し、 @pyqtSlot()
デコレータを使用してスロット関数として登録します。最後に、 MyObject
オブジェクトを作成し、 my_signal
信号を my_slot
スロット関数に接続します。最後に、emit()
メソッドを呼び出してシグナルをトリガーし、メッセージをスロット関数に渡します。
クラスが既に PyQt からコンポーネントを継承している場合は不要です (例: QWidget
、QDialog
、QMainWindow
)。 継承 a>QObject
もう一度説明します。これらのコンポーネントはすでに継承されているためQObject
別のファイルで信号とスロットを定義する
異なるクラスの信号とスロットを接続する場合は、QObject.connect()
メソッドを使用して接続を確立する必要があります。 2 つのクラス Sender
と Receiver
があり、クラス Sender
が信号 my_signal
を定義するとします。 Receiver
クラスはスロット関数を定義しmy_slot
、接続プロセスは次のようになります。
from PyQt5.QtCore import QObject, pyqtSignal, pyqtSlot
class Sender(QObject):
my_signal = pyqtSignal(str)
def send_data(self):
data = "Hello, World!"
self.my_signal.emit(data)
class Receiver(QObject):
@pyqtSlot(str)
def my_slot(self, data):
print("Received data: ", data)
sender = Sender()
receiver = Receiver()
# 将信号连接到槽
sender.my_signal.connect(receiver.my_slot)
# 触发信号
sender.send_data()
上の例では、2 つのクラス Sender
と Receiver
を作成し、それぞれのオブジェクト < a i=3> と sender
をインスタンス化しました。 a> メソッドを呼び出して信号をトリガーします。これにより、スロット関数が呼び出され、受信データが出力されます。 。最後に、 クラス スロット関数 を クラスの信号 メソッドを使用して、 receiver
。次に、 connect()
Sender
my_signal
Receiver
my_slot
send_data()