无法在QML TableVi中显示QSqlQueryModel中的数据vi

2024-10-01 17:41:20 发布

您现在位置:Python中文网/ 问答频道 /正文

我试图在QML的TableView组件的帮助下,在表中显示MySQL数据库中的数据。在

最初,我尝试从QSqlQuery对象生成一个QSqlQueryModel对象,并将其作为属性传递给QML上下文。但我从Qt documentation开始了解到,我必须实现roleNames()来提供到TableView的列到角色映射,所以我将{}子类化如下

import sys
from PyQt5.QtCore import QUrl, Qt
from PyQt5.QtGui import QGuiApplication
from PyQt5.QtQuick import QQuickView
from PyQt5.QtSql import QSqlDatabase, QSqlQuery, QSqlQueryModel


class QtTabModel(QSqlQueryModel):
    def __init__(self):
        super(QtTabModel, self).__init__()

    @staticmethod
    def roleNames():
        roles = {
            Qt.UserRole + 1 : "id",
            Qt.UserRole + 2 : "name"
        }
        return roles

app = QGuiApplication(sys.argv)
view = QQuickView()
db = QSqlDatabase.addDatabase("QMYSQL")
db.setHostName("localhost")
db.setDatabaseName("qtdb")
db.setUserName("abc")
db.setPassword("xyz")
qry = QSqlQuery()
if db.open():
    qry = db.exec("SELECT id, name FROM qttab")
tabmodel = QtTabModel()
tabmodel.setQuery(qry)
ctx = view.rootContext()
ctx.setContextProperty("tabmodel", tabmodel)
view.setSource(QUrl.fromLocalFile("sqltabletest.qml"))
view.show()
app.exec()

我的QML是

^{pr2}$

但它什么也没显示,只是一个空白的窗口

blank window from Qt5 in Ubuntu 14.04

我可以看到我的QSqlQuery正在工作,因为我可以使用value(n)方法从数据库打印数据。我还检查了making rolenames()成员函数,但最终结果是一样的。在

def roleNames(self):
    roles = {
        Qt.UserRole + 1 : "id",
        Qt.UserRole + 2 : "name"
    }
    return roles

更新:

QSqlQueryModel使用widget类,我用QTableViewwidget测试过。但我需要让它和QML一起工作。在

import sys

from PyQt5.QtCore import Qt
from PyQt5.QtWidgets import QApplication, QTableView
from PyQt5.QtSql import QSqlDatabase, QSqlQuery, QSqlQueryModel


app = QApplication(sys.argv)
db = QSqlDatabase.addDatabase("QMYSQL")
db.setHostName("localhost")
db.setDatabaseName("qtdb")
db.setUserName("abc")
db.setPassword("xyz")
qry = QSqlQuery()
if db.open():
    qry = db.exec("SELECT id, name FROM qttab")
tabmodel = QSqlQueryModel()
tabmodel.setQuery(qry)
tabmodel.setHeaderData(0, Qt.Horizontal, "ID")
tabmodel.setHeaderData(1, Qt.Horizontal, "Name")
tabview = QTableView()
tabview.setModel(tabmodel)
tabview.show()
db.close()
app.exec()

working Qt5 code

有谁能帮我解决这个问题吗?提前谢谢。在


Tags: namefromimportiddbsysqtqml
1条回答
网友
1楼 · 发布于 2024-10-01 17:41:20

好吧,你的评论提醒我,为了QML的模型,你确实需要重新实现data()。为什么?因为QML的模型使用roleName()指定的角色调用data()。它不像QWidget世界中那样使用Qt::DisplayRole调用data()。此外,您需要用角色名定义TableViewColumn,否则模型将不会调用data()。下面是一个如何重新实现data()的示例:

import sys
from PyQt5.QtCore import QUrl, Qt, QVariant
from PyQt5.QtCore import QObject, pyqtSlot
from PyQt5.QtGui import QGuiApplication
from PyQt5.QtQuick import QQuickView
from PyQt5.QtSql import QSqlDatabase, QSqlQuery, QSqlQueryModel

class QtTabModel(QSqlQueryModel):
    def __init__(self):
        super(QtTabModel, self).__init__()

    def roleNames(self):
        roles = {
            Qt.UserRole + 1 : 'id',
            Qt.UserRole + 2 : 'name'
        }
        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)

        # caller requests UserRole data, convert role to column (role - Qt.UserRole -1) to return correct data
        return super(QtTabModel, self).data(self.index(index.row(), role - Qt.UserRole -1), Qt.DisplayRole)

    @pyqtSlot(result=QVariant)  # don't know how to return a python array/list, so just use QVariant
    def roleNameArray(self):
        # This method is used to return a list that QML understands
        list = []
        # list = self.roleNames().items()
        for key, value in self.roleNames().items():
            list.append(value)

        return QVariant(list)

TableViewColumn添加到TableView。请记住,角色区分大小写。它们必须与roleNames()返回的值完全匹配:

^{pr2}$

下面是一种自动生成TableViewColumn的方法。它调用上面python代码中定义的rolenamerray slot来获取角色名称列表。我们在这里不调用roleNames(),因为我不知道如何使QML理解它返回的结果:),所以我们必须将它转换为一个列表。最后我们循环查看列表并调用TableView.addColumn要创建列:

TableView {
    width: 200
    height: 300
    model: tabmodel
    Component.onCompleted: {
        var roles = model.roleNameArray()
        for (var i=0; i<roles.length; i++) {
          var column = addColumn( Qt.createQmlObject(
            "import QtQuick.Controls 1.1; TableViewColumn {}",
            this) )
          column.role = roles[i]
          column.title = roles[i]
        }
    }

}

相关问题 更多 >

    热门问题