我现在正在创建一个类,它会产生一个pyqtSignal(int)和一个pyqtSlot(int)。难点在于创建一个可以发射特定值的信号。
假设我想要制作一个类似于以下简单示例的东西:
这里只有两个问题需要解决:
假设我想要制作一个类似于以下简单示例的东西:
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()工厂来生成自己的信号,并在这里获得了良好的文档(点击)。然而,唯一的问题是,非常简单的示例并没有为如何触发特定信号提供坚实的基础。
这就是我试图做的,但却感到迷茫:
- 创建一个元类,允许实现多种不同类型的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_())
这里只有两个问题需要解决:
- 模板元类设置不正确,我无法在元类中实例化QWidget。Q_Type告诉我它的类型是PyQt5.QtCore.pyqtWrapperType,而应该是PyQt5.QtWidgets.QSlider。
- 即使我通过模板类创建了新信号,我如何让QSlider发送我想要发送的更改值?我相信这就是emit()发挥作用的地方,但我对其有限的了解。如果我希望信号将值35传递给槽函数,我知道可以进行某种函数调用self.sld.emit(35)。问题变成了我应该在哪里实现这个函数?