调用QListWidgetItem方法会给出“TypeError:native Qt signal is not callable”消息

时间:2014-03-09 10:33:51

标签: qt python-2.7 pyqt qt-signals

我将QListWidget(名为List)子类化,其中pyqtSignal名为dataChanged,在另一个基类DataWidget中发出。实际上一切正常,

如果setForeground中某个项目(setTooltip)的方法QListWidgetItemList被调用,我就会知道

TypeError: native Qt signal is not callable

消息。 pyqtSignal类的另一个itemLeft名称List如果不是在基类中发出,而是在List类中发出,并且没有问题。

所以,我想知道的是:

  • 为什么在调用listitem的方法时会出现此消息?
    为什么调用方法与该信号有关?!
  • 代码有什么问题? /我需要改变什么?

这是一个重现它的MWE。

from __future__ import print_function
import sys
from PyQt4.QtGui import (QMainWindow, QApplication, QFormLayout, QListWidget,
                         QListWidgetItem, QColor)
from PyQt4.QtCore import pyqtSignal

class DataWidget(object):
    """ A widget to drop data """
    def dropEvent(self, event):
        """ Emits the dataChanged signal """
        # actions to be taken on drop
        self.dataChanged.emit()

class List(QListWidget, DataWidget):
    """ List widget used for, e. g. features  """
    # This signal makes no problems
    itemLeft = pyqtSignal()
    # but this one does
    dataChanged = pyqtSignal()

    def __init__(self, parent):
        super(List, self).__init__(parent)
        self.setAcceptDrops(True)
        self.setMouseTracking(True)
        self.setSortingEnabled(True)

    def leaveEvent(self, event):
        self.itemLeft.emit()


class ApplicationWindow(QMainWindow):
    def __init__(self):
        QMainWindow.__init__(self)

        # The ListWidget
        self.list = List(self)
        self.setCentralWidget(self.list)

        self.list.itemLeft.connect(self.doOnItemLeft)
        self.list.dataChanged.connect(self.doOnDrop)

        # Adding an item to self.list
        item = QListWidgetItem('List Item Name', self.list)

        textcolor, tooltip = QColor(), None
        textcolor.setRgb(50, 50, 115)
        tooltip = 'Tool tip'
        # Calling following methods gives causes
        # TypeError: native Qt signal is not callable
        print('calling: QListWidgetItem.setForeground() for', str(item.text()))
        item.setForeground(textcolor)
        print('calling: QListWidgetItem.setToolTip() for', str(item.text()))
        item.setToolTip(tooltip)

    def doOnItemLeft(self):
        # make gui adaptions...
        print('Widget left')

    def doOnDrop(self):
        # get data from widget and so on...
        pass

app = QApplication(sys.argv)
win = ApplicationWindow()

win.show()
sys.exit(app.exec_())

>>> PyQt4.pyqtconfig.Configuration().pyqt_version_str
'4.9.6'
>>> sys.version_info
sys.version_info(major=2, minor=7, micro=5, releaselevel='final', serial=0)

1 个答案:

答案 0 :(得分:1)

正如Vahancho和Osterfeld所指出的,问题是QListWidget继承自QAbstractItemView,它定义了一个名为“dataChanged”的受保护插槽:在模型中更改项目时调用插槽,从而允许派生类(在这种情况下为QListWidget)采取行动。

因此创建一个同名信号是没有意义的。在列表项上调用方法setForegroundsetTooltip会导致调用槽,只有槽已被信号覆盖,从而导致观察到的错误。