Pyqt: لا توجد هذه الفتحة
سؤال
أنا بدأت تعلم QT4 و Python، بعد بعض البرنامج التعليمي الذي وجدته على Interwebs. لدي الملفين التاليان:
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_())
عندما أقوم بتشغيل هذا أحصل على الأخطاء التالية:
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)
لقد قرأت أن فتحات PYQT ليست أكثر من الأساليب التي حددتها، فما الذي أفعله خطأ؟
أنا أتعلم أيضا QT4 مع روبي وهو المكان الذي ينشأ فيه هذا الرمز، لقد ترجمته من روبي إلى بيثون. في إصدار Ruby، يتم تعريف فئة Lcdrange على أنه:
class LCDRange < Qt::Widget
signals 'valueChanged(int)'
slots 'setValue(int)'
def initialize(parent = nil)
...
لذلك كان تخميني أنني يجب أن أعلن بطريقة أو بأخرى وجود فتحة مخصصة؟
المحلول
جرب هذا:
self.connect(lcdRange, QtCore.SIGNAL('valueChanged'), previousRange.setValue)
ماهو الفرق؟
وثائق PYQT. لديه قسم حول إشارات / فتحات في PYQT، فإنها تعمل بشكل مختلف قليلا.
الإشارة
SIGNAL('valueChanged')
هو شيء يسمى إشارة قصيرة الدائرة. وبعد إنهم يعملون فقط من أجل أساليب Python to-Python، لكنهم أسرع وأسهل في التنفيذ.
فتحة
إذا كان لديك فتحة بيثون، فيمكنك تحديد ذلك فقط عن طريق البقشيش الطريقة: previousRange.setValue
. وبعد هذا يعمل لجميع الطرق التي يمكن الوصول إليها بواسطة Python.
إذا كان يجب الوصول إلى فتحاتك مثل فتحات C ++ QT، كما حاولت في التعليمات البرمجية الخاصة بك، فعليك استخدام بناء جملة خاص. يمكنك العثور على معلومات حول decoratore pyqtsignature. على موقع PYQT.
نصائح أخرى
نسيت أن تضع
@Qt.pyqtSlot()
الطريقة أعلاه التي تستخدمها كقميات.
على سبيل المثال، يجب أن تبدو الكود الخاص بك
@Qt.pyqtSlot('const QPoint&')
def setValue(self,value):
self.slider.setValue(value)
هنا صفحة واحدة جيدة حول Decorator Byqt Slot:
وداعا
ملاحظة
يجب أن يتطابق "النص" داخل الإشارة إلى وثائق API C ++.
# 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 &