I am currently creating a class creating pyqtSignal (int) and pyqtSlot (int). The difficulty lies in creating a signal that emits a specific value.
Suppose I want to do something similar to the following simple example:
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_())
My first question for the above code:
- Why use the pyqtSlot () decorator at all when removing
pyqtSlot(int) does not affect the code? - Can you give an example of when this was necessary?
For specific reasons, I would like to create my own signal using the pyqtSignal () factory and get decent documentation here . The only problem, however, is that a simple simple example does not provide a solid basis for emitting certain signals.
Here is what I am trying to do, but have lost myself:
- Create a metaclass that allows you to implement many different subclasses of QWidget.
- Provide the metaclass with its own signal that can be called from outside the class.
This is what I am going to do:
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
As you can see. I give the widget a name because I find it useful, and I'm also trying to instantiate a QWidget from a class to simplify the code.
This is how I would like the main class to create widgets from the first example:
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):
Here you need to solve only two problems:
- The template metaclass is not configured correctly, and I cannot create an instance of QWidget from the metaclass.
Q_Type tells me that its type is PyQt5.QtCore.pyqtWrapperType when it should be PyQt5.QtWidgets.QSlider . - Even if I create newSignal through a template class, how do I get
QSlider to send the modified value that I want to send. I believe that this is where emit() comes into play, but does not have enough knowledge about how this is useful. I know that I could make some kind of call to the self.sld.emit(35) function if I wanted the signal to pass the value 35 to the slot function. The question is not, but, but where should I implement this function?
I can completely abandon the solution and rethink the solution, feel free to correct my code so that I can make my signal emit the value of a slider.