Pergunta

Eu estou começando a aprender Qt4 e Python, seguindo ao longo de algum tutorial que encontrei na interwebs. Eu tenho os dois seguintes arquivos:

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_())

Quando eu executar este eu recebo os seguintes erros:

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)

Eu li que as faixas horárias PyQt são nada mais do que os métodos que tenho definidos, então o que estou fazendo de errado?

Eu também estou aprendendo Qt4 com Ruby que é onde este se origina de código a partir, eu traduzido lo de Ruby para Python. Na versão do Ruby classe LCDRange é definido como este:

class LCDRange < Qt::Widget
  signals 'valueChanged(int)'
  slots 'setValue(int)'

  def initialize(parent = nil)
  ...

Então, meu palpite era que eu tenho que declarar alguma forma a existência do slot personalizado?

Foi útil?

Solução

Tente isto:

self.connect(lcdRange, QtCore.SIGNAL('valueChanged'), previousRange.setValue)

Qual é a diferença?

A documentação PyQt tem uma seção sobre os sinais / slots no PyQt, eles trabalham um pouco diferente.

SINAL

SIGNAL('valueChanged') é algo chamado curto circuito de sinal. Eles trabalham apenas para métodos Python-a-Python, mas eles são mais rápidos e mais fáceis de implementar.

SLOT

Se você tem um slot de python, você pode especificá-lo apenas por depósito do método: previousRange.setValue. Isso funciona para todos os métodos acessíveis por Python.

Se os slots devem ser acessíveis como ranhuras C ++ Qt, como você tentou no seu código, você tem que usar uma sintaxe especial. Você pode encontrar informações sobre pyqtSignature decorador no site do PyQt.

Outras dicas

Você esqueceu de colocar


@Qt.pyqtSlot()

método acima você está usando como slot.

Por exemplo, seu código deve ter esta aparência


@Qt.pyqtSlot('const QPoint&')
def setValue(self,value):
        self.slider.setValue(value)

Aqui está uma página bem sobre decorador entalhe PyQt:

clique: -)

Bye

NOTA

O "texto" dentro do sinal deve corresponder ao c ++ documentação da 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 &
Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top