I am starting to learn Qt4 and Python, following along some tutorial i found on the interwebs. I have the following two files:
lcdrange.py:
from PyQt4 import QtGui, QtCore class LCDRange(QtGui.QWidget): def __init__(self, parent=None): QtGui.QWidget.__init__(self, parent) lcd = QtGui.QLCDNumber(2) self.slider = QtGui.QSlider() self.slider.setRange(0,99) self.slider.setValue(0) self.connect(self.slider, QtCore.SIGNAL('valueChanged(int)'), lcd, QtCore.SLOT('display(int)')) self.connect(self.slider, QtCore.SIGNAL('valueChanged(int)'), self, QtCore.SIGNAL('valueChanged(int)')) layout = QtGui.QVBoxLayout() layout.addWidget(lcd) layout.addWidget(self.slider) self.setLayout(layout) def value(self): self.slider.value() def setValue(self,value): self.slider.setValue(value)
main.py:
import sys from PyQt4 import QtGui, QtCore from lcdrange import LCDRange class MyWidget(QtGui.QWidget): def __init__(self, parent=None): QtGui.QWidget.__init__(self, parent) quit = QtGui.QPushButton('Quit') quit.setFont(QtGui.QFont('Times', 18, QtGui.QFont.Bold)) self.connect(quit, QtCore.SIGNAL('clicked()'), QtGui.qApp, QtCore.SLOT('quit()')) grid = QtGui.QGridLayout() previousRange = None for row in range(0,3): for column in range(0,3): lcdRange = LCDRange() grid.addWidget(lcdRange, row, column) if not previousRange == None: self.connect(lcdRange, QtCore.SIGNAL('valueChanged(int)'), previousRange, QtCore.SLOT('setValue(int)')) previousRange = lcdRange layout = QtGui.QVBoxLayout() layout.addWidget(quit) layout.addLayout(grid) self.setLayout(layout) app = QtGui.QApplication(sys.argv) widget = MyWidget() widget.show() sys.exit(app.exec_())
When i run this i get the following errors:
Object::connect: No such slot LCDRange::setValue(int) Object::connect: No such slot LCDRange::setValue(int) Object::connect: No such slot LCDRange::setValue(int) Object::connect: No such slot LCDRange::setValue(int) Object::connect: No such slot LCDRange::setValue(int) Object::connect: No such slot LCDRange::setValue(int) Object::connect: No such slot LCDRange::setValue(int) Object::connect: No such slot LCDRange::setValue(int)
I’ve read that PyQt slots are nothing more than methods, which i have defined, so what am i doing wrong?
I am also learning Qt4 with Ruby which is where this code originates from, i translated it from Ruby to Python. In the Ruby version the LCDRange class is defined as this:
class LCDRange < Qt::Widget signals 'valueChanged(int)' slots 'setValue(int)' def initialize(parent = nil) ...
So my guess was that i have to somehow declare the existence of the custom slot?
Try this:
What’s the difference?
The PyQt documentation has a section about SIGNALS/SLOTS in PyQt, they work a little differently.
SIGNAL
SIGNAL('valueChanged')is something called a short-circuit signal. They work only for Python-to-Python methods, but they are faster and easier to implement.SLOT
If you have a python slot, you can specify it just by tipping the method:
previousRange.setValue. This works for all methods accessible by Python.If your slots should be accessible like C++ Qt slots, as you tried in your code, you have to use a special syntax. You can find information about pyqtSignature decorator on the PyQt website.