如何在qml的ListView中显示列表中的项目

2024-09-30 16:32:41 发布

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

代码应该获取数据库表中的行数,并将其用作模型数,并且在单击btnShowList后显示ListView上的所有行 但是,单击后不会发生任何事情。有两个文件

main.qml

import QtQuick 2.15
import QtQuick.Window 2.15
import QtQuick.Controls 2.15

Window {
    width: 640
    height: 480
    visible: true
    title: qsTr("Hello World")
    property var numberOfModels: 1
    property var listofCust: []

    Rectangle{
        id: listViewContainer
        color: "pink"
        anchors.fill: parent
        ListModel {
            id: displayCustomers
            ListElement{
                firstName: "First Name"
                LastName: "Last Name"
                age: "Age"
                Sex: "Sex"
            }
        }
        Component{
            id:customersDelegate
            Row{
                spacing: 50
                Text{
                    text: firstName
                }
                Text {
                    text: LastName
                }
                Text {
                    text: age
                }
                Text {
                    text: Sex
                }
            }
        }

        ListView{
            anchors.fill: parent
            anchors.bottomMargin: 52
            model: displayCustomers
            delegate: customersDelegate
        }

        Button {
            id: btnShowList
            x: 518
            y: 440
            text: qsTr("show list")
            onClicked: {

                displayCustomers.append(backend.getCount)
            }
        }
    }

    Connections {
        target: backend

    function onGetCount(total, listofCust){
       count = total
       numberOfModels = total
       listofCus = listofCust
       return listofCust
        }
    }
}

main.py

import sys
import os
import mysql.connector


from PySide2.QtGui import QGuiApplication
from PySide2.QtQml import QQmlApplicationEngine
from PySide2.QtCore import QObject, Slot, Signal

class MainWindow(QObject):
    def __init__(self):
        QObject.__init__(self)

    count = Signal(int)
    listOfCus = Signal([])
    @Slot()
    def getCount(self):
        db = mysql.connector.connect(
               host = "localhost",
               user = "root",
               passwd = "",
               database = "test"
           )
        mycursor = db.cursor()

        mycursor.execute("SELECT * FROM customer")
        listofCustomers = []
        total = 0
        for x in mycursor:
            total = total + 1
            print(x)
            listofCustomers.append(x)

        self.count.emit(total)
        print(total)
        values = mycursor
        print(values)
        print(listofCustomers)
        self.listOfCus.emit()


if __name__ == "__main__":
    app = QGuiApplication(sys.argv)
    engine = QQmlApplicationEngine()

    #Get Context
    main = MainWindow()
    engine.rootContext().setContextProperty("backend", main)
    engine.load(os.path.join(os.path.dirname(__file__), "main.qml"))

    if not engine.rootObjects():
        sys.exit(-1)
    sys.exit(app.exec_())

执行时没有错误。当我打印客户名单和总数时,我得到了预期的输出。但单击按钮后,listView不会显示任何内容


Tags: textimportselfidmainsysenginetotal
2条回答

OP希望数据库信息神奇地显示在视图中,而不必至少将该信息发送到.qml

另一方面,“displayCustomers.append(backend.getCount)”一行令人困惑,您打算如何处理该代码?在该代码中,getCount函数被添加到模型中,这显然是不合逻辑的

这个想法是要有一个模型(在python或QML中),该模型的角色与委托使用的角色相同,插槽应该只用于填充模型,在本例中,我将使用python模型

import os
from pathlib import Path
import sys

import mysql.connector

from PySide2.QtCore import Property, QCoreApplication, QObject, Qt, QUrl, Slot
from PySide2.QtGui import QGuiApplication, QStandardItem, QStandardItemModel
from PySide2.QtQml import QQmlApplicationEngine


CURRENT_DIRECTORY = Path(__file__).resolve().parent

FIRSTNAME_ROLE = Qt.UserRole
LASTNAME_ROLE = Qt.UserRole + 1
AGE_ROLE = Qt.UserRole + 2
SEX_ROLE = Qt.UserRole + 3


class Backend(QObject):
    def __init__(self, parent=None):
        super().__init__(parent)
        self._model = QStandardItemModel()
        self._model.setItemRoleNames(
            {
                FIRSTNAME_ROLE: b"firstname",
                LASTNAME_ROLE: b"lastname",
                AGE_ROLE: b"age",
                SEX_ROLE: b"sex",
            }
        )
        self.add_row("Fistname", "LastName", "Age", "Sex")

    def get_model(self):
        return self._model

    model = Property(QObject, fget=get_model, constant=True)

    @Slot()
    def loadFromDB(self):
        self._model.clear()

        db = mysql.connector.connect(
            host="localhost", user="root", passwd="", database="test"
        )
        cursor = db.cursor()
        cursor.execute("SELECT * FROM customer")
        for row in cursor.fetchall():
            firstname = row[0]
            lastname = row[1]
            age = row[2]
            sex = row[3]
            self.add_row(firstname, lastname, age, sex)

    def add_row(self, firstname, lastname, age, sex):
        item = QStandardItem()
        item.setData(firstname, FIRSTNAME_ROLE)
        item.setData(lastname, LASTNAME_ROLE)
        item.setData(age, AGE_ROLE)
        item.setData(sex, SEX_ROLE)

        self._model.appendRow(item)


if __name__ == "__main__":
    app = QGuiApplication(sys.argv)
    engine = QQmlApplicationEngine()

    # Get Context
    backend = Backend(app)
    engine.rootContext().setContextProperty("backend", backend)
    filename = os.fspath(CURRENT_DIRECTORY / "main.qml")
    url = QUrl.fromLocalFile(filename)

    def handle_object_created(obj, obj_url):
        if obj is None and url == obj_url:
            QCoreApplication.exit(-1)

    engine.objectCreated.connect(handle_object_created, Qt.QueuedConnection)
    engine.load(url)
    sys.exit(app.exec_())

main.qml

import QtQuick 2.15
import QtQuick.Controls 2.15
import QtQuick.Window 2.15

Window {
    property var numberOfModels: 1
    property var listofCust: []

    width: 640
    height: 480
    visible: true
    title: qsTr("Hello World")

    Rectangle {
        id: listViewContainer

        color: "pink"
        anchors.fill: parent

        Component {
            id: customersDelegate

            Row {
                spacing: 50

                Text {
                    text: firstname
                }

                Text {
                    text: lastname
                }

                Text {
                    text: age
                }

                Text {
                    text: sex
                }

            }

        }

        ListView {
            anchors.fill: parent
            anchors.bottomMargin: 52
            model: backend.model
            delegate: customersDelegate
        }

        Button {
            id: btnShowList

            x: 518
            y: 440
            text: qsTr("show list")
            onClicked: {
                backend.loadFromDB();
            }
        }
    }
}

我想你已经混淆了什么是模型和代理。您的模型应该包含要显示的数据。您的代理定义了数据的显示方式。在您的示例中,您的委托不是可视项。看起来它正在检索数据,这些数据应该进入模型。下面是它应该是什么样子的示例:

ListView {
    // The model is the data
    model: [2,4,6,8]

    // The delegate is the view
    delegate: Text {
        text: modelData
    }
}

相关问题 更多 >