2016-06-07 60 views
0

我嘗試使用PyQt5.6(Python 3.4)和QML設置一個簡單的樹視圖示例。我剛剛發現了一些C++示例,但沒有涉及到PyQt。我選擇了使用PyQt源代碼的simpletreemodel示例並對其進行了修改(https://github.com/baoboa/pyqt5/tree/master/examples/itemviews/simpletreemodel)。PyQt5 QML樹視圖示例

該模型很可能有問題。我有兩個錯誤消息:

simpletreemodel.qml:13:5: QML TreeView: Binding loop detected for property "model"

...qt/5.6/gcc_64/qml/QtQuick/Controls/TreeView.qml:94:16: Unable to assign [undefined] to QAbstractItemModel*

任何想法怎麼回事和/或錯? qml treeview剛剛在Qt 5.5中引入,可能它在PyQt中沒有完全工作?沒有找到任何有關這方面的信息。

這裏是我的代碼:

simpletreemodel.qml

import QtQuick 2.5 
import QtQuick.Controls 1.4 
import QtQml.Models 2.2 

Rectangle { 
    width: 480 
    height: 640 

    TreeView { 
     id: treeView 
     anchors.fill: parent 
     anchors.margins: 6 
     anchors.top: parent.top 
     anchors.horizontalCenter: parent.horizontalCenter 

     model: model 

     TableViewColumn { 
      title: "Title" 
      role: "TitleRole" 
      resizable: true 
     } 

     TableViewColumn { 
      title: "Summary" 
      role: "SummaryRole" 
      resizable: true 
     } 
    } 
} 

simpletreemodel.py

#!/usr/bin/env python 

from PyQt5.QtCore import (
    QAbstractItemModel, QFile, 
    QIODevice, QModelIndex, Qt, 
    QUrl 
) 
from PyQt5.QtGui import QGuiApplication 
from PyQt5.QtQuick import QQuickView 

import simpletreemodel_rc 

class TreeItem(object): 
    def __init__(self, data, parent=None): 
     self.parentItem = parent 
     self.itemData = data 
     self.childItems = [] 

    def appendChild(self, item): 
     self.childItems.append(item) 

    def child(self, row): 
     return self.childItems[row] 

    def childCount(self): 
     return len(self.childItems) 

    def columnCount(self): 
     return len(self.itemData) 

    def data(self, column): 
     try: 
      return self.itemData[column] 
     except IndexError: 
      return None 

    def parent(self): 
     return self.parentItem 

    def row(self): 
     if self.parentItem: 
      return self.parentItem.childItems.index(self) 

     return 0 


class TreeModel(QAbstractItemModel): 
    def __init__(self, data, parent=None): 
     super(TreeModel, self).__init__(parent) 

     self.rootItem = TreeItem(("Title", "Summary")) 
     self.setupModelData(data.split('\n'), self.rootItem) 

    def roleNames(self): 
     roles = { 
      Qt.UserRole + 1: b"TitleRole", 
      Qt.UserRole + 2: b"SummaryRole" 
     } 
     return roles 

    def columnCount(self, parent): 
     if parent.isValid(): 
      return parent.internalPointer().columnCount() 
     else: 
      return self.rootItem.columnCount() 

    def data(self, index, role): 
     if not index.isValid(): 
      return None 

     if role != Qt.DisplayRole: 
      return None 

     item = index.internalPointer() 

     return item.data(index.column()) 

    def flags(self, index): 
     if not index.isValid(): 
      return Qt.NoItemFlags 

     return Qt.ItemIsEnabled | Qt.ItemIsSelectable 

    def headerData(self, section, orientation, role): 
     if orientation == Qt.Horizontal and role == Qt.DisplayRole: 
      return self.rootItem.data(section) 

     return None 

    def index(self, row, column, parent): 
     if not self.hasIndex(row, column, parent): 
      return QModelIndex() 

     if not parent.isValid(): 
      parentItem = self.rootItem 
     else: 
      parentItem = parent.internalPointer() 

     childItem = parentItem.child(row) 
     if childItem: 
      return self.createIndex(row, column, childItem) 
     else: 
      return QModelIndex() 

    def parent(self, index): 
     if not index.isValid(): 
      return QModelIndex() 

     childItem = index.internalPointer() 
     parentItem = childItem.parent() 

     if parentItem == self.rootItem: 
      return QModelIndex() 

     return self.createIndex(parentItem.row(), 0, parentItem) 

    def rowCount(self, parent): 
     if parent.column() > 0: 
      return 0 

     if not parent.isValid(): 
      parentItem = self.rootItem 
     else: 
      parentItem = parent.internalPointer() 

     return parentItem.childCount() 

    def setupModelData(self, lines, parent): 
     parents = [parent] 
     indentations = [0] 

     number = 0 

     while number < len(lines): 
      position = 0 
      while position < len(lines[number]): 
       if lines[number][position] != ' ': 
        break 
       position += 1 

      lineData = lines[number][position:].trimmed() 

      if lineData: 
       # Read the column data from the rest of the line. 
       columnData = [s for s in lineData.split('\t') if s] 

       if position > indentations[-1]: 
        # The last child of the current parent is now the new 
        # parent unless the current parent has no children. 

        if parents[-1].childCount() > 0: 
         parents.append(parents[-1].child(parents[-1].childCount() - 1)) 
         indentations.append(position) 

       else: 
        while position < indentations[-1] and len(parents) > 0: 
         parents.pop() 
         indentations.pop() 

       # Append a new item to the current parent's list of children. 
       parents[-1].appendChild(TreeItem(columnData, parents[-1])) 

      number += 1 


if __name__ == '__main__': 
    import sys 

    app = QGuiApplication(sys.argv) 
    view = QQuickView() 

    f = QFile(':/default.txt') 
    f.open(QIODevice.ReadOnly) 
    model = TreeModel(f.readAll()) 
    f.close() 

    root_context = view.rootContext().setContextProperty('model', model) 
    view.setSource(QUrl.fromLocalFile('simpletreemodel.qml')) 
    view.show() 
    sys.exit(app.exec_()) 

回答

0
root_context = view.rootContext().setContextProperty('model', model) 

不要使用模式作爲模型的名稱。

+0

你能更具體一些爲什麼我應該防止這種情況嗎? – user2638109