سؤال

أنا بدأت تعلم 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 &
مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top