如何使用pyqt5在模型/ view qml中查看我的数据

时间:2019-01-19 16:09:17

标签: python python-3.x pyqt qml pyqt5

由于模型/视图编程,我想在QmL GUI中查看我的数据! 我使用mysql.connector从mysql获取数据

我不太了解模型/视图,我了解模型/视图的概念,但是很难编码!请帮我提供我的代码,给我一个解决方案,我说法语,请原谅我在英语上的错误

#Main.py
#!/usr/bin/env python
# -*- coding: utf-8 -*-
#ligne d'importation des  classes necessaire
import sys
from PyQt5.QtCore import QObject



class MainApp(QObject):
    def __init__(self, context, parent=None):
        super(MainApp, self).__init__(parent)
        self.win = parent
        self.ctx = context

def Insert(self):
    nom = self.win.findChild(QObject, "nName").property("text")
    prenom = self.win.findChild(QObject, "nFirstname").property("text")
    self.win.findChild(QObject, "LOB").setProperty("text","cliqué")

    # insert(nom,prenom)
    return 0

SqlFunc.py

import mysql.connector

mydb = mysql.connector.connect(
   host="localhost",
   user="root",
   passwd="",
   database="agenda"
 )


mycursor = mydb.cursor()

def insert(nom,prenom):
    var=0
    sql = "INSERT INTO contact (numero, nom) VALUES (%s, %s)"
    val = (nom, prenom)
    if  mycursor.execute(sql, val):
        mydb.commit()
        return "Enregistrement effectué"
    else:
        return "Echec de l'enregistrement contact déjà enregistré!"


def select():
    mycursor.execute("SELECT * FROM contact")
    data_from = mycursor.fetchall()
    if data_from == "":
       return "Aucun contact enregistré"
    else:
       return data_from


def search(name):
      mycursor.execute("SELECT contact.numero, contact.nom WHERE                                                     
      contact.nom LIKE \'%{}%\' ORDER BY contact.nom".format(name))
      myresult = mycursor.fetchall()
      return myresult


def update(old_address,new_address):
      sql_request =  "UPDATE customers SET address = %s WHERE address = %s"
      valors = (old_address, new_address)
      if mycursor.execute( sql_request, valors):
           mydb.commit()
           return "Modification effectuer avec succes"
      else:
           return "Echec de la modification"


def delete(address):
    sql_request = "DELETE FROM customers WHERE address = %s"
    func_address = (address)

    if mycursor.execute(sql_request,func_address):
        mydb.commit()
        return "Suppression effectuée"
    else:
        return "Echec de la suppression"

databases.py

import SqlFunc

class DataBase():
    def __int__(self):
        self.data_from_databases

    @staticmethod
    def take_from_mysql():
        data_to_model = SqlFunc.select()
        return data_to_model

    @staticmethod
    def search_by_name(contact_name):
        search_result = SqlFunc.search(contact_name)
        return search_result

    @staticmethod
    def update_valor(old,new):
        update_result = SqlFunc.update(old,new)
        return update_result

    @staticmethod
    def delete_valor(address):
        delete_result = SqlFunc.delete(address)
        return delete_result

Star_app.py

 import sys, Modele,databases
 from PyQt5.QtWidgets import QApplication
 from PyQt5.QtQml import QQmlApplicationEngine
 from os import system

 try:
    system('start
    C:\\Users\\yyy\\PycharmProjects\\TEST_CEI_GUI\\mysql\\bin\\mysqld.exe')
 except:
    quit()
 else:
    from Main import MainApp
    if __name__ == "__main__":
        #data = databases.DataBase.take_from_mysql()
        sys.argv += ['--style', 'material']
        app = QApplication(sys.argv)
        engine = QQmlApplicationEngine()

        model = Modele.NewModel()
        ctx = engine.rootContext()

        engine.load('C:\\Users\yyy\PycharmProjects\TEST_CEI_GUI\GO7\\
                     main.qml')
        win = engine.rootObjects()[0]
        py_mainapp = MainApp(ctx, win)

        ctx.setContextProperty("py_MainApp", py_mainapp)
        ctx.setContextProperty("myModel", model)
        win.show()
        sys.exit(app.exec())

Modele.py

   class NewModel(QAbstractListModel):
       numero_role = Qt.UserRole + 1
       nom_role = Qt.UserRole + 2
       _roles = {numero_role: b"numero", nom_role: b"nom"}


       def __init__(self):
          super(NewModel, self).__init__()
          self._contact = []
          self._data = databases.DataBase().take_from_mysql()


       def update(self,search_term):
          self.beginResetModel()
          self._contact = self._data.search_by_name(search_term)
          self.endResetModel()

       @pyqtSlot(str)
       def search_input(self,searh_input):
          if len(searh_input) > 3:
              print(searh_input)
              self.update(searh_input)

       def rowCount(self, parent=None, *args, **kwargs):
              return len(self._data)

       def data(self, QModelIndex, role=None):
             row = QModelIndex.row()
             if role == self.numero_role:
                 return self._data[row]["numero"]

             if role == self.nom_role:
                 return self._data[row]["nom"]

       def roleNames(self):
             return self._roles

main.qml

             import QtQuick 2.9
            import QtQuick.Controls 2.4

            Page {
                width: 600
                height: 400
                clip: true
                contentHeight: 20

                title: qsTr("Consulter (Consulter les personnes enregistrer)")


                GridView {

                    id: gridView
                    keyNavigationWraps: true
                    cellWidth: 220
                    cellHeight: 320
                    visible: true

                    model: myModel // QML connection to python model
                    delegate: Rectangle {
                        id: thumb_frame
                        height: 330
                        width: 200

                        Text{
                            id: contactnumero
                            text: numero // 

                        }

                        Text{
                            id: contactnom
                            text: nom//

                        }


                    }
                }







            }

我的GUI在执行后崩溃,并且当我修改代码时,视图中什么都没有显示

1 个答案:

答案 0 :(得分:0)

问题是您假设fetchall()返回一个元组列表,而不是假定它返回了一个字典列表,因此在这种情况下,您应该更改为:

mycursor = mydb.cursor(dictionary=True)

另一方面,如果要在QML中使用模型,则必须在加载QML之前将其作为contextProperty加载:

if __name__ == "__main__":
    #data = databases.DataBase.take_from_mysql()
    sys.argv += ['--style', 'material']
    app = QApplication(sys.argv)
    engine = QQmlApplicationEngine()

    model = Modele.NewModel()
    ctx = engine.rootContext()

    ctx.setContextProperty("myModel", model)
    engine.load(r'main.qml')
    if not engine.rootObjects():
        sys.exit(-1)
    win = engine.rootObjects()[0]
    py_mainapp = MainApp(ctx, win)
    ctx.setContextProperty("py_MainApp", py_mainapp)
    sys.exit(app.exec())

另一方面,QQmlApplicationEngine等待窗口或ApplicationWindow,而不是页面,因此将QML更改为:

import QtQuick 2.9
import QtQuick.Controls 2.4

ApplicationWindow {
    width: 600
    visible: true
    height: 400
    title: qsTr("Consulter (Consulter les personnes enregistrer)")
    GridView {
        id: gridView
        anchors.fill: parent
        keyNavigationWraps: true
        cellWidth: 220
        cellHeight: 320
        visible: true
        model: myModel // QML connection to python model
        delegate: Rectangle {
            id: thumb_frame
            height: 330
            width: 200
            Row{
                Text{
                    id: contactnumero
                    text: numero //
                }
                Text{
                    id: contactnom
                    text: nom 
                }
            }
        }
    }
}

另一种方法是将QtSql与QSqlQueryModel一起使用:

main.py

from PyQt5 import QtCore, QtGui, QtSql, QtQml

class SqlQueryModel(QtSql.QSqlQueryModel):
    def data(self, index, role=QtCore.Qt.DisplayRole):
        value = QtCore.QVariant()
        if index.isValid():
            if role < QtCore.Qt.UserRole:
                value = super(SqlQueryModel, self).data(index, role)
            else:
                columnIdx = role - QtCore.Qt.UserRole - 1;
                modelIndex = self.index(index.row(), columnIdx)
                value =super(SqlQueryModel, self).data(modelIndex, QtCore.Qt.DisplayRole)
        return value

    def roleNames(self):
        roles = dict()
        for i in range(self.record().count()):
            roles[QtCore.Qt.UserRole + i +1] = self.record().fieldName(i).encode()
        return roles

class Manager(QtCore.QObject):
    def __init__(self, parent=None):
        super(Manager, self).__init__(parent)
        self._model = SqlQueryModel(self)
        self.take_from_mysql()

    @QtCore.pyqtProperty(SqlQueryModel)
    def model(self):
        return self._model

    @QtCore.pyqtSlot()
    def take_from_mysql(self):
        self._model.setQuery("SELECT * FROM contact")

    @QtCore.pyqtSlot(str)
    def search_by_name(self, name):
        query = QtSql.QSqlQuery()
        query.prepare('''SELECT * FROM contact WHERE nom LIKE ? ORDER BY nom;''')
        query.addBindValue("%{}%".format(name))
        query.exec()
        self._model.setQuery(query)

def createConnection():
    db = QtSql.QSqlDatabase.addDatabase('QMYSQL')
    db.setHostName("localhost")
    db.setDatabaseName("agenda")
    db.setUserName("root")
    db.setPassword("")
    if not db.open():
        print('''Unable to establish a database connection.\n
            This example needs SQLite support. Please read
            the Qt SQL driver documentation for information
            how to build it.\n\n Click Cancel to exit.''')
        return False
    return True

if __name__ == '__main__':
    import sys
    sys.argv += ['--style', 'material']
    app = QtGui.QGuiApplication(sys.argv)
    if not createConnection():
        sys.exit(-1)
    manager = Manager()
    engine = QtQml.QQmlApplicationEngine()
    ctx = engine.rootContext()
    ctx.setContextProperty("manager", manager)
    engine.load("main.qml")
    sys.exit(app.exec_())

main.qml

import QtQuick 2.9
import QtQuick.Controls 2.4

ApplicationWindow {
    width: 600
    visible: true
    height: 400
    title: qsTr("Consulter (Consulter les personnes enregistrer)")
    GridView {
        id: gridView
        anchors.fill: parent
        keyNavigationWraps: true
        cellWidth: 220
        cellHeight: 320
        visible: true
        model: manager.model // QML connection to python model
        delegate: Rectangle {
            id: thumb_frame
            height: 330
            width: 200
            Row{
                Text{
                    id: contactnumero
                    text: numero //
                }
                Text{
                    id: contactnom
                    text: nom 
                }
            }
        }
    }
}