由于模型/视图编程,我想在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在执行后崩溃,并且当我修改代码时,视图中什么都没有显示
答案 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
}
}
}
}
}