没有hack就无法在PySide2上运行QAbstractListModel子类

时间:2018-01-22 22:06:39

标签: python pyside2

使用正在进行的工作PySide2(能够使用Qt5),我有以下代码:

main.qml:

import QtQuick 2.0
import QtQuick.Controls 1.3

ApplicationWindow {
    visible: true
    ListView {
        width: 100
        height: 100
        model: listModel
        delegate: Text {
            text: model.name
        }
    }
}

main.py:

from sys import argv, exit

from PySide2.QtCore import QAbstractListModel
from PySide2.QtGui import QGuiApplication
from PySide2.QtQml import QQmlApplicationEngine


class TaskListModel(QAbstractListModel):

    _COLUMNS = ('name',)

    def data(self, index, role):
        if role == self._COLUMNS.index('name'):
            return str(index.row())
        return None

    def roleNames(self):
        return dict(enumerate(self._COLUMNS))

    def rowCount(self, parent):
        return 1


app = QGuiApplication(argv)
engine = QQmlApplicationEngine()
engine.rootContext().setContextProperty('listModel', None)
engine.load('main.qml')
engine.rootContext().setContextProperty('listModel', TaskListModel())
exit(app.exec_())

main.py 结尾处对engine对象调用3方法的原因是:

  1. 如果我使用的话,我会Unable to assign [undefined] to QString

    engine.rootContext().setContextProperty('listModel', TaskListModel())
    engine.load('main.qml')
    
  2. 如果我使用的话,我会ReferenceError: listModel is not defined

    engine.load('main.qml')
    engine.rootContext().setContextProperty('listModel', TaskListModel())
    
  3. 我的方式是正确做到这一点的唯一方法吗?我上面的第一张子弹中的代码也不应该起作用吗?

1 个答案:

答案 0 :(得分:1)

如果你将PySide2分配给某个变量,TaskListModel()似乎从内存中删除app = QGuiApplication(argv) engine = QQmlApplicationEngine() model = TaskListModel() engine.rootContext().setContextProperty('listModel', model) engine.load('main.qml') exit(app.exec_()) ,我找到了2个解决方案:

  • 创建一个存储模型的变量:
app = QGuiApplication(argv)
engine = QQmlApplicationEngine()
engine.rootContext().setContextProperty('listModel', TaskListModel(engine))
engine.load('main.qml')
exit(app.exec_())
  • 将父级传递给模型:
onSearchChange(value) {
  this.setState((state) => {
    return {
       filter: {
         ...state.filter,
         search: value
       }
  })
}