1
votes

The problem is as follows.

I have this ListView in a "main.qml" QML file:

ListView {
    id: websiteListView
    orientation: ListView.Vertical
    flickableDirection: Flickable.VerticalFlick
    anchors.fill: parent
    model: websiteModel
    focus: true
    highlight: Rectangle { color: "lightsteelblue";}
    highlightFollowsCurrentItem: true
    objectName: "websiteListView"

    delegate: Component {
        Item {
            property variant itemData: model.modelData
            width: parent.width
            height: 20

            Row {
                id: row1
                spacing: 10
                anchors.fill: parent

                Text {
                    text: name
                    font.bold: true
                    anchors.verticalCenter: parent.verticalCenter
                }

                MouseArea {
                    id: websiteMouseArea
                    anchors.fill: parent
                    onClicked: {
                        websiteListView.currentIndex = index
                    }
                }
            }
        }
    }
}

I also possess this Python script:

    self.__engine = QQmlApplicationEngine()
    self.__engine.load("main.qml")

    website_list = self.__engine.rootObjects()[0].findChild(QObject, "websiteListView")
    website_list.currentIndexChanged.connect(self.__website_event_print)

And the function responsible for signal handling:

@pyqtSlot(int, int)
def __website_event_print(self, current, previous):

    print(current)
    print(previous)

The code shown above is just an excerpt from the whole application but I believe that other lines of code will have nothing to do with the problem.

As I am trying to run my application an error occurs

TypeError: decorated slot has no signature compatible with currentIndexChanged()

I have tried already a plentiful of variations of above code but nothing seems to work. Is my style of handling the signal correct ? And if so, what is the signature of the "currentIndexChanged" ?

1

1 Answers

0
votes

It is not advisable to connect qml items outside of QML since you can only obtain it as QObject as your code shows and never the real object since it is private, besides currentIndexChanged notifies that there has been a change but no parameter passes it for what you get those mistakes.

A possible solution is to create an object that is inserted in QML through setContextProperty() and invoke the function when the signal is emited:

.py:

class Helper(QObject):
    @pyqtSlot(int)
    def foo(self, index):
        print(index)

# ...

engine = QQmlApplicationEngine()
helper = Helper()
engine.rootContext().setContextProperty("helper", helper)
engine.load(QUrl.fromLocalFile("main.qml"))

.qml

ListView {
    onCurrentIndexChanged: helper.foo(currentIndex)
    // ...
}

In the following link there is an example