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

How to display items in a list in ListView in qml

该代码应该获取数据库 table 中的行数并将其用作模型数,并在单击 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_())

执行时没有错误。当我打印 listofCustomers 和 total 时,我得到了预期的输出。但是点击按钮后listView不显示任何东西

我认为您混淆了模型和委托是什么。您的模型应该包含要显示的数据。您的代表定义数据的显示方式。在您的示例中,您的代表不是视觉项目。看起来它正在检索数据,这些数据应该进入模型。这是它应该是什么样子的示例:

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

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

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();
            }
        }
    }
}