2016-07-14 6 views
6

나는 나의 Python3/PyQt5 (5.6) 코드에서 pyqtSlot 장식 방법에 QMLListView에서 activated 신호를 연결하고 싶습니다.PyQt5 pyqtSlot을 QML ListView 신호 "연결"에 연결하는 방법은 무엇입니까?

내 현재 접근법은 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" 
     } 
    } 
    } 

} 

답변

1

당신이 할 수 QQuickView를 사용하는 대신 QQmlApplicationEngine에 의해.

QQuickView에서 상속받은 새로운 클래스를 추가하도록 python 스크립트를 변경하고 "myList"라는 QML 객체에 신호를 추가했습니다.

또한 QML에 유형의 Window 유형을 삭제했습니다. 을 QQuickView과 함께 사용할 수 없습니다. 애플리케이션을 전체 화면으로 표시하려면 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" 
     } 
    } 
    } 

}