7

我想将来自QMLactivated的信号连接到来自我的Python3/PyQt5 (5.6) 代码的装饰方法。 ListViewpyqtSlot

我目前的方法是在我的代码中加载 QML 场景,QQmlApplicationEngine然后使用它findChild()来获取对我的ListView.

问题是,我只能在搜索 QObject 时找到 ListView findChild(QObject, 'myList')。但是 htis 对象没有让我访问activated信号,很可能是因为这个信号只是为QAbstractItemView它的后代定义的。

所以如果我尝试findChild(QListView, 'myList')结果是None. 因此,我无法收到activated信号。这是 PyQt5 中的一个错误,还是有另一种方法可以让我连接到这个信号?

这是一些最小的工作示例。

列表.py:

import sys
from OpenGL import GL
from PyQt5.QtCore import QUrl, QObject
from PyQt5.QtWidgets import QApplication, QListView
from PyQt5.QtQml import QQmlApplicationEngine

# Main Function
if __name__ == '__main__':
    # Create main app
    app = QApplication(sys.argv)

    # Create QML engine
    engine = QQmlApplicationEngine(app)

    # Load the QML scene from file
    engine.load(QUrl('List.qml'))

    for root in engine.rootObjects():
        node = root.findChild(QListView, 'myList')
        if node:
            # At this point I would like to connect something to the
            # node.activated signal
            print(node)

    # Execute the application and exit
    sys.exit(app.exec_())

列表.qml:

import QtQuick 2.0
import QtQuick.Window 2.2

Window {
  visibility: Window.FullScreen
  visible: true
  ListView {
    objectName: "myList"
    anchors.fill: parent
    delegate: Item {
      width: parent.width * 0.8
      height: 40
      Row {
        id: row1
        Rectangle {
          width: 40
          height: 40
          color: colorCode
        }

        Text {
          text: name
          font.bold: true
          anchors.verticalCenter: parent.verticalCenter
        }
        spacing: 10
      }
    }
    model: ListModel {
      ListElement {
        name: "Grey"
        colorCode: "grey"
      }

      ListElement {
        name: "Red"
        colorCode: "red"
      }

      ListElement {
        name: "Blue"
        colorCode: "blue"
      }

      ListElement {
        name: "Green"
        colorCode: "green"
      }
    }
  }

}
4

1 回答 1

2

您可以通过使用QQuickView代替来做到这一点QQmlApplicationEngine

我更改了您的 python 脚本以添加一个继承自的新类QQuickView,并向名为“myList”的 QML 对象添加了一个信号。

此外,在 QML 中,我删除了Windowtype 的Item类型(您不能使用Windowwith QQuickView)。如果你想全屏显示你的应用程序,你必须在MyView类中指定它。在示例中,如果您单击其中一个彩色矩形,则索引将显示在控制台中。

列表.py:

import sys
from PyQt5.QtCore import QUrl, QObject
from PyQt5.QtWidgets import QApplication, QListView
from PyQt5.QtQuick import QQuickView, QQuickItem

class MyView(QQuickView):
    def __init__(self, parent=None):
        super().__init__(parent)
        # Load the QML scene from file
        self.setSource(QUrl('List.qml'))    
        #connect signal and source
        list = self.rootObject().findChild(QQuickItem, 'myList')
        list.mySignal.connect(self.mySlot)

    def mySlot(self, index):
        print(index)

# Main Function
if __name__ == '__main__':
    # Create main app
    app = QApplication(sys.argv)

    # Create QML view
    view = MyView()
    view.show()    

    # Execute the application and exit
    sys.exit(app.exec_())

列表.qml:

import QtQuick 2.0
import QtQuick.Window 2.2

Item {
  width: 500
  height: 500
  ListView {
    anchors.fill: parent
    id: list
    objectName: "myList"
    signal mySignal(int index)
    delegate: Item {
      width: parent.width * 0.8
      height: 40
      Row {
        id: row1
        Rectangle {
          width: 40
          height: 40
          color: colorCode

          MouseArea{
            anchors.fill: parent
            onClicked: list.mySignal(index)
          }
        }

        Text {
          text: name
          font.bold: true
          anchors.verticalCenter: parent.verticalCenter
        }
        spacing: 10
      }
    }
    model: ListModel {
      ListElement {
        name: "Grey"
        colorCode: "grey"
      }

      ListElement {
        name: "Red"
        colorCode: "red"
      }

      ListElement {
        name: "Blue"
        colorCode: "blue"
      }

      ListElement {
        name: "Green"
        colorCode: "green"
      }
    }
  }

}
于 2016-09-29T12:01:53.430 回答