Pregunta
Me estoy empezando a aprender Qt4 y Python, tras lo largo de alguna clase particular que encontré en la interwebs. Tengo el siguiente dos archivos:
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_())
Cuando corro esto me sale el siguiente error:
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)
He leído que las ranuras de PyQt no son más que métodos, que he definido, así que lo que estoy haciendo mal?
También estoy aprendiendo Qt4 con Ruby, que es donde se origina a partir de este código, lo traduje desde Ruby a Python. En la versión de Ruby LCDRange la clase se define como la siguiente:
class LCDRange < Qt::Widget
signals 'valueChanged(int)'
slots 'setValue(int)'
def initialize(parent = nil)
...
Así que mi conjetura es que tengo que declarar la existencia de alguna forma de la ranura de costumbre?
Solución
Prueba esto:
self.connect(lcdRange, QtCore.SIGNAL('valueChanged'), previousRange.setValue)
¿Cuál es la diferencia?
La documentación PyQt tiene una sección acerca de las señales / ranuras en PyQt, trabajan un poco diferente.
SIGNAL
SIGNAL('valueChanged')
es algo que se llama un corto señal de circuito. Trabajan sólo para los métodos de Python-a-Python, pero que son más rápidos y más fáciles de poner en práctica.
SLOT
Si usted tiene una ranura pitón, puede especificar simplemente inclinando el método: previousRange.setValue
. Esto funciona para todos los métodos accesibles por Python.
Si sus ranuras deben ser accesibles como C ++ Qt ranuras, como se ha intentado en su código, usted tiene que utilizar una sintaxis especial. Puede encontrar información sobre pyqtSignature decorador en el sitio web PyQt.
Otros consejos
se olvidó de poner
@Qt.pyqtSlot()
anterior método que está utilizando como ranura.
Por ejemplo, su código debería tener este aspecto
@Qt.pyqtSlot('const QPoint&')
def setValue(self,value):
self.slider.setValue(value)
Aquí es una buena página sobre el decorador ranura pyqt:
adiós
NOTA
El "texto" dentro de la señal debe coincidir con el C ++ documentación de la API.
# This will work - its IDENTICAL to the documentation
QtCore.SIGNAL('customContextMenuRequested(const QPoint&)')
# this wont
QtCore.SIGNAL('customContextMenuRequested(QPoint&)')
# and this wont
QtCore.SIGNAL('customContextMenuRequested(const QPoint)')
# Spot the bug
QtCore.SIGNAL('selectionChanged(const QItemSelection,const QItemSelection&)')
^ < missing &