PySide2 SQLITE 表视图

在尝试QSQLITE在 QML 中显示表中的数据时,TableView我偶然发现了这个答案并试图跟进它。我理解重新实施的必要性,data()但是roleNames()当涉及到QVariantPySide2 中不存在的问题时,我遇到了问题。我明白了NameError: name 'QVariant' is not defined。我已经测试了从数据库读取数据,它的工作。是否有任何数据类型可以代替QVariantPySide2 使用?我的计划是拥有来自不同表的多个数据源。这个例子使用setContextProperty,在这种情况下使用是更好的做法qmlRegisterType吗?

文件夹结构


├── ViewModel

│   └── QCond.py

├── Qml

│   └── Modellist.qml

└── qmlengine.py

qmlengine.py


import os

import sys

from PySide2.QtCore import QUrl, QStringListModel, QCoreApplication, Qt

from PySide2.QtGui import QGuiApplication

from PySide2.QtQml import QQmlApplicationEngine, qmlRegisterType

from PySide2.QtSql import QSqlDatabase, QSqlQuery, QSqlQueryModel

from ViewModel.QCond import *

if __name__ == "__main__":

    app = QGuiApplication(sys.argv)

    engine = QQmlApplicationEngine()

    db = QSqlDatabase.addDatabase("QSQLITE")

    db.setDatabaseName("C:\\Users\\terao\\Documents\\ctmd\\CatData.db")

    db.open()

    qry = QSqlQuery()

    qry=db.exec_("SELECT tip,s FROM uzad")

    tabmodel = QtCond()

    tabmodel.setQuery(qry)

    engine.rootContext().setContextProperty("tabmodel", tabmodel)

    engine.load(QUrl.fromLocalFile('Qml/Modellist.qml'))

    if not engine.rootObjects():

        sys.exit(-2)

    sys.exit(app.exec_())

QCond.py


import sys

from PySide2 import QtCore, QtGui, QtQml

from PySide2.QtCore import QObject, Qt,Signal, Slot, QUrl, QStringListModel, QCoreApplication

import sqlite3

from PySide2.QtSql import QSqlDatabase, QSqlQuery, QSqlQueryModel

class QtCond(QSqlQueryModel):

    def __init__(self):

        super(QtCond, self).__init__()


    def roleNames(self):

        roles = {

            Qt.UserRole + 1 : 'tip',

            Qt.UserRole + 2 : 's'

        }

        return roles


    def data(self, index, role):

        if role < Qt.UserRole:

            # caller requests non-UserRole data, just pass to papa

            return super(QtTabModel, self).data(index, role)


任何帮助表示赞赏。提前致谢。


萧十郎
浏览 206回答 1
1回答

MMTTMM

在您的情况下,roleNameArray 返回一个列表,正如我在这个答案中指出的那样,您必须使用“QVariantList”。另一方面,我通过根据我的旧答案概括示例来改进示例:(1),(2),考虑到解决方案是:├── db│&nbsp; &nbsp;└── CatData.db├── qml│&nbsp; &nbsp;└── Modellist.qml├── qmlengine.py└── ViewModel&nbsp; &nbsp; └── model.py视图模型/model.pyfrom PySide2 import QtCore, QtSqlclass SqlQueryModel(QtSql.QSqlQueryModel):&nbsp; &nbsp; def data(self, index, role=QtCore.Qt.DisplayRole):&nbsp; &nbsp; &nbsp; &nbsp; value = None&nbsp; &nbsp; &nbsp; &nbsp; if index.isValid():&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; if role < QtCore.Qt.UserRole:&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; value = super(SqlQueryModel, self).data(index, role)&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; else:&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; columnIdx = role - QtCore.Qt.UserRole - 1&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; modelIndex = self.index(index.row(), columnIdx)&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; value = super(SqlQueryModel, self).data(&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; modelIndex, QtCore.Qt.DisplayRole&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; )&nbsp; &nbsp; &nbsp; &nbsp; return value&nbsp; &nbsp; def roleNames(self):&nbsp; &nbsp; &nbsp; &nbsp; roles = dict()&nbsp; &nbsp; &nbsp; &nbsp; for i in range(self.record().count()):&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; roles[QtCore.Qt.UserRole + i + 1] = self.record().fieldName(i).encode()&nbsp; &nbsp; &nbsp; &nbsp; return roles&nbsp; &nbsp; @QtCore.Slot(result="QVariantList")&nbsp; &nbsp; def roleNameArray(self):&nbsp; &nbsp; &nbsp; &nbsp; names = []&nbsp; &nbsp; &nbsp; &nbsp; for i in range(self.record().count()):&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; names.append(self.record().fieldName(i))&nbsp; &nbsp; &nbsp; &nbsp; return namesqml/模型列表.qmlimport QtQuick 2.5import QtQuick.Controls 1.4import QtQuick.Controls 2.5ApplicationWindow{&nbsp; &nbsp; width: 1000&nbsp; &nbsp; height: 1000&nbsp; &nbsp; visible: true&nbsp; &nbsp; TableView {&nbsp; &nbsp; &nbsp; &nbsp; anchors.fill: parent&nbsp; &nbsp; &nbsp; &nbsp; model: tabmodel&nbsp; &nbsp; &nbsp; &nbsp; /*TableViewColumn {&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; role: "tip"&nbsp; &nbsp; &nbsp; &nbsp; }&nbsp; &nbsp; &nbsp; &nbsp; TableViewColumn {&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; role: "s"&nbsp; &nbsp; &nbsp; &nbsp; }*/&nbsp; &nbsp; &nbsp; &nbsp; Component.onCompleted: {&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; var roles = model.roleNameArray()&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; for (var i=0; i<roles.length; i++) {&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; var column = addColumn( Qt.createQmlObject(&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; "import QtQuick.Controls 1.1; TableViewColumn {}",&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; this) )&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; column.role = roles[i]&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; column.title = roles[i]&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; }&nbsp; &nbsp; &nbsp; &nbsp; }&nbsp; &nbsp; }}qmlengine.pyimport osimport sysfrom PySide2 import QtCore, QtGui, QtSql, QtQmlfrom ViewModel.model import SqlQueryModeldef create_connection(path):&nbsp; &nbsp; db = QtSql.QSqlDatabase.addDatabase('QSQLITE')&nbsp; &nbsp; db.setDatabaseName(path)&nbsp; &nbsp; if not db.open():&nbsp; &nbsp; &nbsp; &nbsp; print('''Unable to establish a database connection.\n&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; This example needs SQLite support. Please read&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; the Qt SQL driver documentation for information&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; how to build it.\n\n Click Cancel to exit.''')&nbsp; &nbsp; &nbsp; &nbsp; return False&nbsp; &nbsp; return Trueif __name__ == "__main__":&nbsp; &nbsp; current_dir = os.path.dirname(os.path.realpath(__file__))&nbsp; &nbsp; app = QtGui.QGuiApplication(sys.argv)&nbsp; &nbsp; engine = QtQml.QQmlApplicationEngine()&nbsp; &nbsp; db_path = os.path.join(current_dir, "db", "CatData.db")&nbsp; &nbsp; if not create_connection(db_path):&nbsp; &nbsp; &nbsp; &nbsp; sys.exit(-1)&nbsp; &nbsp; tabmodel = SqlQueryModel()&nbsp; &nbsp; tabmodel.setQuery("SELECT tip,s FROM uzad")&nbsp; &nbsp; engine.rootContext().setContextProperty("tabmodel", tabmodel)&nbsp; &nbsp; qml_path = os.path.join("qml", "Modellist.qml")&nbsp; &nbsp; engine.load(QtCore.QUrl.fromLocalFile(qml_path))&nbsp; &nbsp; if not engine.rootObjects():&nbsp; &nbsp; &nbsp; &nbsp; sys.exit(-2)&nbsp; &nbsp; sys.exit(app.exec_())&nbsp;输出:qmlRegisterType 的目标是通过抽象起源和实现在 QML 中注册 Python/C++ 类型。在您的情况下,如果您想注册它,最好是查询是一个 qproperty,以便可以从 QML 访问它:视图模型/model.pyfrom PySide2 import QtCore, QtSqlclass SqlQueryModel(QtSql.QSqlQueryModel):&nbsp; &nbsp; queryStrChanged = QtCore.Signal(str)&nbsp; &nbsp; def get_query_str(self):&nbsp; &nbsp; &nbsp; &nbsp; return self.query().lastQuery()&nbsp; &nbsp; def set_query_str(self, query):&nbsp; &nbsp; &nbsp; &nbsp; if self.get_query_str() == query:&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; return&nbsp; &nbsp; &nbsp; &nbsp; self.setQuery(query)&nbsp; &nbsp; &nbsp; &nbsp; self.queryStrChanged.emit(query)&nbsp; &nbsp; query_str = QtCore.Property(&nbsp; &nbsp; &nbsp; &nbsp; str, fget=get_query_str, fset=set_query_str, notify=queryStrChanged&nbsp; &nbsp; )&nbsp; &nbsp; def data(self, index, role=QtCore.Qt.DisplayRole):&nbsp; &nbsp; &nbsp; &nbsp; value = None&nbsp; &nbsp; &nbsp; &nbsp; if index.isValid():&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; if role < QtCore.Qt.UserRole:&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; value = super(SqlQueryModel, self).data(index, role)&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; else:&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; columnIdx = role - QtCore.Qt.UserRole - 1&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; modelIndex = self.index(index.row(), columnIdx)&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; value = super(SqlQueryModel, self).data(&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; modelIndex, QtCore.Qt.DisplayRole&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; )&nbsp; &nbsp; &nbsp; &nbsp; return value&nbsp; &nbsp; def roleNames(self):&nbsp; &nbsp; &nbsp; &nbsp; roles = dict()&nbsp; &nbsp; &nbsp; &nbsp; for i in range(self.record().count()):&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; roles[QtCore.Qt.UserRole + i + 1] = self.record().fieldName(i).encode()&nbsp; &nbsp; &nbsp; &nbsp; return roles&nbsp; &nbsp; @QtCore.Slot(result="QVariantList")&nbsp; &nbsp; def roleNameArray(self):&nbsp; &nbsp; &nbsp; &nbsp; names = []&nbsp; &nbsp; &nbsp; &nbsp; for i in range(self.record().count()):&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; names.append(self.record().fieldName(i))&nbsp; &nbsp; &nbsp; &nbsp; return namesqml/模型列表.qmlimport QtQuick 2.5import QtQuick.Controls 1.4import QtQuick.Controls 2.5import mycomponents 1.0ApplicationWindow{&nbsp; &nbsp; width: 1000&nbsp; &nbsp; height: 1000&nbsp; &nbsp; visible: true&nbsp; &nbsp; SqlQueryModel{&nbsp; &nbsp; &nbsp; &nbsp; id: tabmodel&nbsp; &nbsp; &nbsp; &nbsp; query_str: "SELECT tip,s FROM uzad"&nbsp; &nbsp; }&nbsp; &nbsp; TableView {&nbsp; &nbsp; &nbsp; &nbsp; anchors.fill: parent&nbsp; &nbsp; &nbsp; &nbsp; model: tabmodel&nbsp; &nbsp; &nbsp; &nbsp; /*TableViewColumn {&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; role: "tip"&nbsp; &nbsp; &nbsp; &nbsp; }&nbsp; &nbsp; &nbsp; &nbsp; TableViewColumn {&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; role: "s"&nbsp; &nbsp; &nbsp; &nbsp; }*/&nbsp; &nbsp; &nbsp; &nbsp; Component.onCompleted: {&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; var roles = model.roleNameArray()&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; for (var i=0; i<roles.length; i++) {&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; var column = addColumn( Qt.createQmlObject(&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; "import QtQuick.Controls 1.1; TableViewColumn {}",&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; this) )&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; column.role = roles[i]&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; column.title = roles[i]&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; }&nbsp; &nbsp; &nbsp; &nbsp; }&nbsp; &nbsp; }}qmlengine.pyimport osimport sysfrom PySide2 import QtCore, QtGui, QtSql, QtQmlfrom ViewModel.model import SqlQueryModeldef create_connection(path):&nbsp; &nbsp; db = QtSql.QSqlDatabase.addDatabase('QSQLITE')&nbsp; &nbsp; db.setDatabaseName(path)&nbsp; &nbsp; if not db.open():&nbsp; &nbsp; &nbsp; &nbsp; print('''Unable to establish a database connection.\n&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; This example needs SQLite support. Please read&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; the Qt SQL driver documentation for information&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; how to build it.\n\n Click Cancel to exit.''')&nbsp; &nbsp; &nbsp; &nbsp; return False&nbsp; &nbsp; return Trueif __name__ == "__main__":&nbsp; &nbsp; current_dir = os.path.dirname(os.path.realpath(__file__))&nbsp; &nbsp; QtQml.qmlRegisterType(SqlQueryModel, "mycomponents", 1, 0, "SqlQueryModel")&nbsp; &nbsp; app = QtGui.QGuiApplication(sys.argv)&nbsp; &nbsp; engine = QtQml.QQmlApplicationEngine()&nbsp; &nbsp; db_path = os.path.join(current_dir, "db", "CatData.db")&nbsp; &nbsp; if not create_connection(db_path):&nbsp; &nbsp; &nbsp; &nbsp; sys.exit(-1)&nbsp; &nbsp; qml_path = os.path.join("qml", "Modellist.qml")&nbsp; &nbsp; engine.load(QtCore.QUrl.fromLocalFile(qml_path))&nbsp; &nbsp; if not engine.rootObjects():&nbsp; &nbsp; &nbsp; &nbsp; sys.exit(-2)&nbsp; &nbsp; sys.exit(app.exec_())
打开App,查看更多内容
随时随地看视频慕课网APP

相关分类

Python