現在、pyqtSignal(int)とpyqtSlot(int)を生成するクラスを作成中です。難しいのは、特定の値を発する信号を作り出すことです。PyQt5シグナルスロットデコレータの例
私は次の簡単な例に似たものを作るにしたいと仮定します。上記のコードのための
import sys
from PyQt5.QtCore import (Qt, pyqtSignal, pyqtSlot)
from PyQt5.QtWidgets import (QWidget, QLCDNumber, QSlider,
QVBoxLayout, QApplication)
class Example(QWidget):
def __init__(self):
super().__init__()
self.initUI()
def printLabel(self, str):
print(str)
@pyqtSlot(int)
def on_sld_valueChanged(self, value):
self.lcd.display(value)
self.printLabel(value)
def initUI(self):
self.lcd = QLCDNumber(self)
self.sld = QSlider(Qt.Horizontal, self)
vbox = QVBoxLayout()
vbox.addWidget(self.lcd)
vbox.addWidget(self.sld)
self.setLayout(vbox)
self.sld.valueChanged.connect(self.on_sld_valueChanged)
self.setGeometry(300, 300, 250, 150)
self.setWindowTitle('Signal & slot')
self.show()
if __name__ == '__main__':
app = QApplication(sys.argv)
ex = Example()
sys.exit(app.exec_())
私の最初の質問は次のとおりです。
削除するときに、すべてのpyqtSlot()デコレータを使用する理由pyqtSlot(int)
はコードに影響しませんか?- 必要なときの例を挙げることはできますか?
は、特定の理由から、私はpyqtSignal()の工場を使用して独自の信号を生成したいとまともなドキュメントhereを与えられています。しかし、唯一の問題は、非常にsimple exampleが特定の信号を放出する方法の確固たる基盤を提供していないことです。ここで
は私がしようとしているものですが、自分が失っ発見した:
- QWidgetのサブクラスの多くの異なる種類の実装が可能になりますメタクラスを作成します。
- メタクラスは、クラス外から呼び出すことができる独自の信号を生成します。
これは私がつもりです:あなたが見ることができるように
from PyQt5.QtWidgets import QPushButton, QWidget
from PyQt5.QtCore import pyqtSignal, pyqtSlot
from PyQt5.QtWidgets import QSlider
def template(Q_Type, name: str, *args):
class MyWidget(Q_Type):
def __init__(self) -> None:
super().__init__(*args)
self._name = name
def setSignal(self,type):
self.signal = pyqtSignal(type)
def callSignal(self):
pass
return MyWidget
。私はこれを役に立つと思うのでウィジェットに名前を付けます。クラス内からQWidgetをインスタンス化してコードを単純化しようとします。
これは私が最初の例からウィジェットを生成するために、メインクラスをご希望の方法です:
- テンプレートメタクラス:
import sys from PyQt5.QtCore import (Qt, pyqtSignal, pyqtSlot) from PyQt5.QtWidgets import (QWidget, QLCDNumber, QSlider, QVBoxLayout, QApplication) class Example(QWidget): def __init__(self): super().__init__() self.initUI() def printLabel(self, str): print(str) @pyqtSlot(int) def sld_valChanged(self, value): self.lcd.display(value) self.printLabel(value) def initUI(self): #instantiate the QWidgets through template class self.lcd = template(QLCDNumber,'lcd_display') self.sld = template(QSlider, 'slider', Qt.Horizontal) #create signal #self.sld.setSignal(int) vbox = QVBoxLayout() vbox.addWidget(self.lcd) vbox.addWidget(self.sld) self.setLayout(vbox) #connect signal - this won't send the value of the slider #self.sld.signal.connect(self.sld_valChanged) self.sld.valueChanged.connect(self.sld_valChanged) self.setGeometry(300, 300, 250, 150) self.setWindowTitle('Signal & slot') self.show() if __name__ == '__main__': app = QApplication(sys.argv) ex = Example() sys.exit(app.exec_())
ここで解決する必要がある唯一の2の問題があります間違って設定されていて、メタクラス内からQWidgetをインスタンス化できません。
Q_Type
は、そのタイプがPyQt5.QtWidgets.QSlider
のときは、そのタイプがPyQt5.QtCore.pyqtWrapperType
であることを教えています。 - テンプレート化されたクラスを使用してnewSignalを作成していますが、送信する変更された値を送信するには、どうすれば
QSlider
を取得する必要がありますか。私はこれがemit()
が遊びに来るが、それがどのように役に立つかについて十分な知識がないと信じています。 シグナルがスロット機能に値35を渡したい場合、私は関数呼び出しself.sld.emit(35)
を作成することができます。どうやって問題になるのですか?
私は完全にオフベースであり、解決策を考え直しているかもしれません。自分の信号を修正して、自分の信号がスライダの値を放出できるようにしてください。
なぜこのような醜い、複雑すぎる、そして難しいコードを書こうとしていますか?あなたが解決しようとしている実際の問題はありますか?私はあなたが誤って彼らが働くように設計されているのではなく、働くべきだと思うようにAPIを強制的に働かせようとしている、まったく共通の新人ミスをしています。これは[XY問題](http://xyproblem.info/)の変形です。 – ekhumoro
@pyqtSignal()の使用は推奨されていません。 @pyqtSlot()のみを使用してください。マニュアルの使い方を調べてください。車輪を再構築しないでください。 (私に尋ねると、@ pyqtSlot()はPyQtの命名体系と一貫するために@pyQtSlot()という名前にする必要があります。 –