【问题标题】:How to connect PyQt5 pyqtSlot to QML ListView signal "activated"?如何将 PyQt5 pyqtSlot 连接到 QML ListView 信号“激活”?
【发布时间】:2016-11-16 23:14:11
【问题描述】:

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

我目前的做法是通过QQmlApplicationEngine在我的代码中加载QML场景,然后使用findChild()获取我的ListView的引用。

问题是,我只能在搜索像findChild(QObject, 'myList') 这样的 QObject 时找到 ListView。但是 htis 对象不允许我访问 activated 信号,很可能是因为此信号仅针对 QAbstractItemView 及其后代定义。

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

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

list.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_())

List.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"
      }
    }
  }

}

【问题讨论】:

    标签: python-3.x listview qml pyqt5 qqmlapplicationengine


    【解决方案1】:

    您可以使用QQuickView 而不是QQmlApplicationEngine 来做到这一点。

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

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

    list.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_())
    

    List.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"
          }
        }
      }
    
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2013-10-08
      • 2017-09-25
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多