如何使用pyQt在qml中的python文件中显示QAbstractTableModel
Posted
技术标签:
【中文标题】如何使用pyQt在qml中的python文件中显示QAbstractTableModel【英文标题】:how to display a QAbstractTableModel in python file in qml using pyQt 【发布时间】:2018-01-16 11:00:38 【问题描述】:我创建了一个 QAbstactTableModel 子类并将其与 qml 中的 tableview 绑定。我需要对 python 文件而不是 c++ 做同样的事情。我怎样才能做到这一点。我不太了解python。表视图.py
from os import path
import PyQt5
from PyQt5.QtCore import *
from PyQt5.QtCore import pyqtProperty, QObject, pyqtSignal
from PyQt5.QtGui import QGuiApplication
from PyQt5.QtQml import QQmlApplicationEngine
from PyQt5.QtCore import pyqtProperty, QCoreApplication, QObject, QUrl
from PyQt5.QtQml import qmlRegisterType, QQmlComponent, QQmlEngine, QQmlListProperty
from PyQt5.QtCore import QTimer, pyqtSignal,pyqtSlot
from PyQt5.QtQml import QQmlListProperty
from PyQt5.QtCore import QUrl
from PyQt5.QtWidgets import QApplication
from PyQt5.QtQuick import QQuickView
class TableModel(QAbstractTableModel):
def __init__(self, parent=None, *args):
super(TableModel, self).__init__()
self.datatable = None
def update(self, dataIn):
print ('Updating Model')
self.datatable = dataIn
def rowCount(self, parent=QModelIndex()):
return len(self.datatable.index)
def columnCount(self, parent=QModelIndex()):
return len(self.datatable.columns.values)
def data(self, index, role=Qt.DisplayRole):
if role == QtCore.Qt.DisplayRole:
i = index.row()
j = index.column()
return '0'.format(self.datatable.iget_value(i, j))
else:
return QtCore.QVariant()
def flags(self, index):
return QtCore.Qt.ItemIsEnabled
class MainWindow(QQuickView):
def __init__(self, parent=None):
super().__init__(parent)
self.tablemodel=TableModel()
self.rootContext().setContextProperty('PersonModel', self.tablemodel)
self.rootContext().setContextProperty('MainWindow', self)
self.setSource(QUrl('main.qml'))
myApp = QApplication(sys.argv)
ui = MainWindow()
ui.show()
sys.exit(myApp.exec_())
main.qml
import QtQuick 2.3
import QtQuick.Window 2.2
import QtQuick.Controls 1.4
Window
visible: true
width: 640
height: 480
title: qsTr("Hello World")
TableView
id: idTableView
anchors.fill: parent
model: PersonModel
Component.onCompleted:
console.log("column count", columnCount)
console.log("model column count", PersonModel.columnCount())
for (var i = 0; i < PersonModel.columnCount(); i++)
var myTableViewColumn;
var component = Qt.createComponent("MyTableViewColumn.qml")
if (component.status === Component.Ready)
myTableViewColumn = component.createObject();
if (null !== myTableViewColumn)
console.log("add column")
// myTableViewColumn.role = dataModel.modelRoles[i]
// myTableViewColumn.title = dataModel.modelRoles[i]
idTableView.addColumn(myTableViewColumn)
Button
text: "click"
anchors.bottom: parent.bottom
onClicked:
idTableView.addColumn(idColumnComponent)
Component
id: idColumnComponent
TableViewColumn
id: idColumn
当我运行此代码时,我收到类似 return len(self.datatable.index) 的错误 AttributeError: 'NoneType' 对象没有属性 'index'
【问题讨论】:
好的,所以你希望有人为你写代码? 很抱歉问题不完整 【参考方案1】:问题是datatable
是None所以它没有列或索引(我不知道datatable
是什么类型的结构),解决方法是为rowCount()
和columnCount()
设置一个大小0如果是 None 否则我们分别通过 index
或 columns
。
另一个问题是你不应该使用QQuickView
,因为你在.qml中除了Window之外生成另一个topLevel,所以会出现2个窗口,你应该只使用QQmlApplicationEngine
:
class TableModel(QAbstractTableModel):
def __init__(self, parent=None, *args):
super(TableModel, self).__init__()
self.datatable = None
def update(self, dataIn):
print ('Updating Model')
self.datatable = dataIn
def rowCount(self, parent=QModelIndex()):
return len(self.datatable.index) if self.datatable else 0
def columnCount(self, parent=QModelIndex()):
return len(self.datatable.columns.values) if self.datatable else 0
def data(self, index, role=Qt.DisplayRole):
if role == Qt.DisplayRole:
i = index.row()
j = index.column()
return '0'.format(self.datatable.iget_value(i, j))
else:
return QVariant()
def flags(self, index):
return Qt.ItemIsEnabled
if __name__ == '__main__':
import sys
myApp = QGuiApplication(sys.argv)
engine = QQmlApplicationEngine()
tablemodel=TableModel()
engine.rootContext().setContextProperty('PersonModel', tablemodel)
engine.load(QUrl.fromLocalFile(QDir.current().absoluteFilePath('main.qml')))
if len(engine.rootObjects()) == 0:
sys.exit(-1)
sys.exit(myApp.exec_())
【讨论】:
我的数据表是一个字典数组 self.datatable = [ 'value1': 10, 'value2': 17, 'value3': 16, 'value4': 10, 'value1 ':11,'value2':13,'value3':17,'value4':16,'value1':12,'value2':15,'value3':12,'value4':12,]以上是关于如何使用pyQt在qml中的python文件中显示QAbstractTableModel的主要内容,如果未能解决你的问题,请参考以下文章
如何正确地将 ComboBox 的模型从 python (pyQt5) 传递给 QML?