Trong bài 48 các bạn đã biết cách sử dụng ngôn ngữ lập trình Python để tương tác cơ sở dữ liệu MySQL Server “studentmanagement”, Các bạn đã lập trình nhuần nhuyễn CRUD để thêm mới dữ liệu, truy vấn dữ liệu, sắp xếp dữ liệu, cập nhật dữ liệu, xóa dữ liệu, phân trang dữ liệu….
Bài học này chúng ta sẽ ứng dụng để thiết kế giao diện tương tác người dùng, giao diện như dưới đây:
Phần mềm sử dụng cơ sở dữ liệu và các mã lệnh đã học ở các bài trước.
Phần mềm gồm có các chức năng sau:
(1) Tải toàn bộ dữ liệu từ bảng student lên QTableWidget
(2) “New”: Xóa dữ liệu trong các Widget để cho nhập mới dữ liệu
(3) “Insert”: Thêm mới student vào cơ sở dữ liệu MySQL
(4) “Update”: Chỉnh sữa dữ liệu student
(5) “Remove”: Xóa Student khỏi cơ sở dữ liệu MySQL
(6) “Avatar”/”Remove Avatar”: Chọn và xóa Avatar. Hình Ảnh sẽ được mã hóa thành base64string
(7) Xem chi tiết student: Nhấn chọn student trong QTableWidget, thông tin chi tiết của Student sẽ hiển thị vào các Widget cơ bản
Ta đi vào chi tiết:
Bước 1: Tạo cấu trúc thư mục và tập tin cho dự án “StudentManagement” như dưới đây:
- images: Thư mục này lưu các hình ảnh, icon của phần mềm, tùy bạn lựa chọn
- MainWindow.ui: Tập tin giao diện phần mềm
- MainWindow.py: Tập tin python gencode của giao diện
- MainWindowEx.py: Tập tin kết thừa lớp giao diện được tạo ra từ MainWindow.py
- MyApp.py: Tập tin thực thi phần mềm
Bước 2: Bạn thiết kế giao diện như hình dưới đây:
Thiết kế giao diện, đặt tên các Widget như hình trên.
Bước 3: Sau đó Gencode “MainWindow.py”:
# Form implementation generated from reading ui file 'E:\Elearning\StudentManagement\MainWindow.ui'
#
# Created by: PyQt6 UI code generator 6.7.1
#
# WARNING: Any manual changes made to this file will be lost when pyuic6 is
# run again. Do not edit this file unless you know what you are doing.
from PyQt6 import QtCore, QtGui, QtWidgets
class Ui_MainWindow(object):
def setupUi(self, MainWindow):
MainWindow.setObjectName("MainWindow")
MainWindow.resize(456, 552)
icon = QtGui.QIcon()
icon.addPixmap(QtGui.QPixmap("E:\\Elearning\\StudentManagement\\images/ic_logo.jpg"), QtGui.QIcon.Mode.Normal, QtGui.QIcon.State.Off)
MainWindow.setWindowIcon(icon)
self.centralwidget = QtWidgets.QWidget(parent=MainWindow)
self.centralwidget.setObjectName("centralwidget")
self.label = QtWidgets.QLabel(parent=self.centralwidget)
self.label.setGeometry(QtCore.QRect(20, 0, 371, 41))
font = QtGui.QFont()
font.setPointSize(12)
font.setBold(True)
font.setWeight(75)
self.label.setFont(font)
self.label.setAlignment(QtCore.Qt.AlignmentFlag.AlignCenter)
self.label.setObjectName("label")
self.groupBox = QtWidgets.QGroupBox(parent=self.centralwidget)
self.groupBox.setGeometry(QtCore.QRect(20, 450, 411, 61))
self.groupBox.setStyleSheet("background-color: rgb(236, 255, 199);")
self.groupBox.setObjectName("groupBox")
self.pushButtonRemove = QtWidgets.QPushButton(parent=self.groupBox)
self.pushButtonRemove.setGeometry(QtCore.QRect(300, 20, 91, 28))
self.pushButtonRemove.setStyleSheet("background-color: rgb(255, 170, 255);")
icon1 = QtGui.QIcon()
icon1.addPixmap(QtGui.QPixmap("E:\\Elearning\\StudentManagement\\images/ic_delete.png"), QtGui.QIcon.Mode.Normal, QtGui.QIcon.State.Off)
self.pushButtonRemove.setIcon(icon1)
self.pushButtonRemove.setIconSize(QtCore.QSize(24, 24))
self.pushButtonRemove.setObjectName("pushButtonRemove")
self.pushButtonInsert = QtWidgets.QPushButton(parent=self.groupBox)
self.pushButtonInsert.setGeometry(QtCore.QRect(100, 20, 81, 28))
self.pushButtonInsert.setStyleSheet("background-color: rgb(255, 170, 255);")
icon2 = QtGui.QIcon()
icon2.addPixmap(QtGui.QPixmap("E:\\Elearning\\StudentManagement\\images/ic_save.png"), QtGui.QIcon.Mode.Normal, QtGui.QIcon.State.Off)
self.pushButtonInsert.setIcon(icon2)
self.pushButtonInsert.setIconSize(QtCore.QSize(24, 24))
self.pushButtonInsert.setObjectName("pushButtonInsert")
self.pushButtonNew = QtWidgets.QPushButton(parent=self.groupBox)
self.pushButtonNew.setGeometry(QtCore.QRect(10, 20, 71, 28))
self.pushButtonNew.setStyleSheet("background-color: rgb(255, 170, 255);")
icon3 = QtGui.QIcon()
icon3.addPixmap(QtGui.QPixmap("E:\\Elearning\\StudentManagement\\images/ic_new.png"), QtGui.QIcon.Mode.Normal, QtGui.QIcon.State.Off)
self.pushButtonNew.setIcon(icon3)
self.pushButtonNew.setIconSize(QtCore.QSize(24, 24))
self.pushButtonNew.setObjectName("pushButtonNew")
self.pushButtonUpdate = QtWidgets.QPushButton(parent=self.groupBox)
self.pushButtonUpdate.setGeometry(QtCore.QRect(200, 20, 81, 28))
self.pushButtonUpdate.setStyleSheet("background-color: rgb(255, 170, 255);")
icon4 = QtGui.QIcon()
icon4.addPixmap(QtGui.QPixmap("E:\\Elearning\\StudentManagement\\images/ic_update.png"), QtGui.QIcon.Mode.Normal, QtGui.QIcon.State.Off)
self.pushButtonUpdate.setIcon(icon4)
self.pushButtonUpdate.setIconSize(QtCore.QSize(24, 24))
self.pushButtonUpdate.setObjectName("pushButtonUpdate")
self.groupBox_2 = QtWidgets.QGroupBox(parent=self.centralwidget)
self.groupBox_2.setGeometry(QtCore.QRect(20, 240, 411, 201))
self.groupBox_2.setStyleSheet("background-color: rgb(255, 201, 243);")
self.groupBox_2.setObjectName("groupBox_2")
self.label_4 = QtWidgets.QLabel(parent=self.groupBox_2)
self.label_4.setGeometry(QtCore.QRect(20, 110, 41, 16))
self.label_4.setObjectName("label_4")
self.label_3 = QtWidgets.QLabel(parent=self.groupBox_2)
self.label_3.setGeometry(QtCore.QRect(20, 80, 41, 16))
self.label_3.setObjectName("label_3")
self.lineEditName = QtWidgets.QLineEdit(parent=self.groupBox_2)
self.lineEditName.setGeometry(QtCore.QRect(70, 80, 171, 22))
self.lineEditName.setStyleSheet("background-color: rgb(251, 255, 206);")
self.lineEditName.setObjectName("lineEditName")
self.lineEditAge = QtWidgets.QLineEdit(parent=self.groupBox_2)
self.lineEditAge.setGeometry(QtCore.QRect(70, 110, 171, 22))
self.lineEditAge.setStyleSheet("background-color: rgb(251, 255, 206);")
self.lineEditAge.setObjectName("lineEditAge")
self.label_2 = QtWidgets.QLabel(parent=self.groupBox_2)
self.label_2.setGeometry(QtCore.QRect(20, 50, 41, 16))
self.label_2.setObjectName("label_2")
self.lineEditCode = QtWidgets.QLineEdit(parent=self.groupBox_2)
self.lineEditCode.setGeometry(QtCore.QRect(70, 50, 171, 22))
self.lineEditCode.setStyleSheet("background-color: rgb(251, 255, 206);")
self.lineEditCode.setObjectName("lineEditCode")
self.label_5 = QtWidgets.QLabel(parent=self.groupBox_2)
self.label_5.setGeometry(QtCore.QRect(20, 150, 41, 16))
self.label_5.setObjectName("label_5")
self.lineEditIntro = QtWidgets.QLineEdit(parent=self.groupBox_2)
self.lineEditIntro.setGeometry(QtCore.QRect(70, 140, 171, 41))
self.lineEditIntro.setStyleSheet("background-color: rgb(251, 255, 206);")
self.lineEditIntro.setObjectName("lineEditIntro")
self.labelAvatar = QtWidgets.QLabel(parent=self.groupBox_2)
self.labelAvatar.setGeometry(QtCore.QRect(250, 10, 151, 141))
self.labelAvatar.setStyleSheet("background-color: rgb(170, 255, 255);\n"
"border-color: rgb(85, 85, 0);")
self.labelAvatar.setText("")
self.labelAvatar.setPixmap(QtGui.QPixmap("E:\\Elearning\\StudentManagement\\images/ic_no_avatar.png"))
self.labelAvatar.setScaledContents(True)
self.labelAvatar.setObjectName("labelAvatar")
self.pushButtonAvatar = QtWidgets.QPushButton(parent=self.groupBox_2)
self.pushButtonAvatar.setGeometry(QtCore.QRect(250, 160, 61, 23))
self.pushButtonAvatar.setStyleSheet("background-color: rgb(170, 255, 127);")
self.pushButtonAvatar.setObjectName("pushButtonAvatar")
self.label_6 = QtWidgets.QLabel(parent=self.groupBox_2)
self.label_6.setGeometry(QtCore.QRect(20, 20, 41, 16))
self.label_6.setObjectName("label_6")
self.lineEditId = QtWidgets.QLineEdit(parent=self.groupBox_2)
self.lineEditId.setEnabled(False)
self.lineEditId.setGeometry(QtCore.QRect(70, 20, 81, 22))
self.lineEditId.setStyleSheet("background-color: rgb(251, 255, 206);")
self.lineEditId.setReadOnly(True)
self.lineEditId.setObjectName("lineEditId")
self.pushButtonRemoveAvatar = QtWidgets.QPushButton(parent=self.groupBox_2)
self.pushButtonRemoveAvatar.setGeometry(QtCore.QRect(320, 160, 81, 23))
self.pushButtonRemoveAvatar.setStyleSheet("background-color: rgb(170, 255, 127);")
self.pushButtonRemoveAvatar.setObjectName("pushButtonRemoveAvatar")
self.groupBox_3 = QtWidgets.QGroupBox(parent=self.centralwidget)
self.groupBox_3.setGeometry(QtCore.QRect(20, 40, 411, 191))
self.groupBox_3.setStyleSheet("background-color: rgb(251, 255, 206);")
self.groupBox_3.setObjectName("groupBox_3")
self.verticalLayout = QtWidgets.QVBoxLayout(self.groupBox_3)
self.verticalLayout.setObjectName("verticalLayout")
self.tableWidgetStudent = QtWidgets.QTableWidget(parent=self.groupBox_3)
self.tableWidgetStudent.setStyleSheet("background-color: rgb(207, 255, 235);")
self.tableWidgetStudent.setObjectName("tableWidgetStudent")
self.tableWidgetStudent.setColumnCount(4)
self.tableWidgetStudent.setRowCount(0)
item = QtWidgets.QTableWidgetItem()
self.tableWidgetStudent.setHorizontalHeaderItem(0, item)
item = QtWidgets.QTableWidgetItem()
self.tableWidgetStudent.setHorizontalHeaderItem(1, item)
item = QtWidgets.QTableWidgetItem()
self.tableWidgetStudent.setHorizontalHeaderItem(2, item)
item = QtWidgets.QTableWidgetItem()
self.tableWidgetStudent.setHorizontalHeaderItem(3, item)
self.verticalLayout.addWidget(self.tableWidgetStudent)
MainWindow.setCentralWidget(self.centralwidget)
self.menubar = QtWidgets.QMenuBar(parent=MainWindow)
self.menubar.setGeometry(QtCore.QRect(0, 0, 456, 22))
self.menubar.setObjectName("menubar")
MainWindow.setMenuBar(self.menubar)
self.statusbar = QtWidgets.QStatusBar(parent=MainWindow)
self.statusbar.setObjectName("statusbar")
MainWindow.setStatusBar(self.statusbar)
self.retranslateUi(MainWindow)
QtCore.QMetaObject.connectSlotsByName(MainWindow)
MainWindow.setTabOrder(self.tableWidgetStudent, self.lineEditCode)
MainWindow.setTabOrder(self.lineEditCode, self.lineEditName)
MainWindow.setTabOrder(self.lineEditName, self.lineEditAge)
MainWindow.setTabOrder(self.lineEditAge, self.pushButtonNew)
MainWindow.setTabOrder(self.pushButtonNew, self.pushButtonInsert)
MainWindow.setTabOrder(self.pushButtonInsert, self.pushButtonRemove)
def retranslateUi(self, MainWindow):
_translate = QtCore.QCoreApplication.translate
MainWindow.setWindowTitle(_translate("MainWindow", "Trần Duy Thanh - Student Management"))
self.label.setText(_translate("MainWindow", "Student Management"))
self.groupBox.setTitle(_translate("MainWindow", "Actions:"))
self.pushButtonRemove.setText(_translate("MainWindow", "Remove"))
self.pushButtonInsert.setText(_translate("MainWindow", "Insert"))
self.pushButtonNew.setText(_translate("MainWindow", "New"))
self.pushButtonUpdate.setText(_translate("MainWindow", "Update"))
self.groupBox_2.setTitle(_translate("MainWindow", "Student Details:"))
self.label_4.setText(_translate("MainWindow", "Age:"))
self.label_3.setText(_translate("MainWindow", "Name:"))
self.label_2.setText(_translate("MainWindow", "Code:"))
self.label_5.setText(_translate("MainWindow", "Intro:"))
self.pushButtonAvatar.setText(_translate("MainWindow", "Avatar"))
self.label_6.setText(_translate("MainWindow", "ID:"))
self.pushButtonRemoveAvatar.setText(_translate("MainWindow", "Remove Avatar"))
self.groupBox_3.setTitle(_translate("MainWindow", "List of Students:"))
item = self.tableWidgetStudent.horizontalHeaderItem(0)
item.setText(_translate("MainWindow", "ID"))
item = self.tableWidgetStudent.horizontalHeaderItem(1)
item.setText(_translate("MainWindow", "Code"))
item = self.tableWidgetStudent.horizontalHeaderItem(2)
item.setText(_translate("MainWindow", "Name"))
item = self.tableWidgetStudent.horizontalHeaderItem(3)
item.setText(_translate("MainWindow", "Age"))
Bước 4: Tạo MainWindowEx.py
Bước 4.1: Coding kế thừa Ui_MainWindow, và định nghĩa các biến như bên dưới:
import base64
import traceback
import mysql.connector
from PyQt6.QtGui import QPixmap
from PyQt6.QtWidgets import QTableWidgetItem, QFileDialog, QMessageBox
from MainWindow import Ui_MainWindow
class MainWindowEx(Ui_MainWindow):
def __init__(self):
super().__init__()
self.default_avatar="images/ic_no_avatar.png"
self.id = None
self.code = None
self.name = None
self.age = None
self.avatar = None
self.intro = None
Bước 4.2: Override phương thức setupUI:
def setupUi(self, MainWindow):
super().setupUi(MainWindow)
self.MainWindow=MainWindow
self.tableWidgetStudent.itemSelectionChanged.connect(self.processItemSelection)
self.pushButtonAvatar.clicked.connect(self.pickAvatar)
self.pushButtonRemoveAvatar.clicked.connect(self.removeAvatar)
self.pushButtonInsert.clicked.connect(self.processInsert)
self.pushButtonUpdate.clicked.connect(self.processUpdate)
self.pushButtonRemove.clicked.connect(self.processRemove)
def show(self):
self.MainWindow.show()
Hàm trên, ta thiết lập hàm nạp giao diện và khai báo các signals + slots
Bước 4.3: Viết mã lệnh kết nối MySQL Server, cơ sở dữ liệu studentmanagement (lưu ý nó là CSDL ở bài trước)
def connectMySQL(self):
server = "localhost"
port = 3306
database = "studentmanagement"
username = "root"
password = "@Obama123"
self.conn = mysql.connector.connect(
host=server,
port=port,
database=database,
user=username,
password=password)
Bước 4.4: Viết lệnh truy vấn toàn bộ Student và hiển thị lên QTableWidget
def selectAllStudent(self):
cursor = self.conn.cursor()
# query all students
sql = "select * from student"
cursor.execute(sql)
dataset = cursor.fetchall()
self.tableWidgetStudent.setRowCount(0)
row=0
for item in dataset:
row = self.tableWidgetStudent.rowCount()
self.tableWidgetStudent.insertRow(row)
self.id = item[0]
self.code = item[1]
self.name = item[2]
self.age = item[3]
self.avatar = item[4]
self.intro = item[5]
self.tableWidgetStudent.setItem(row, 0, QTableWidgetItem(str(self.id)))
self.tableWidgetStudent.setItem(row, 1, QTableWidgetItem(self.code))
self.tableWidgetStudent.setItem(row, 2, QTableWidgetItem(self.name))
self.tableWidgetStudent.setItem(row, 3, QTableWidgetItem(str(self.age)))
cursor.close()
Bước 4.5: Viết hàm hiển thị thông tin chi tiết student khi nhấn vào từng dòng dữ liệu trong QTableWidget
def processItemSelection(self):
row=self.tableWidgetStudent.currentRow()
if row ==-1:
return
try:
code = self.tableWidgetStudent.item(row, 1).text()
cursor = self.conn.cursor()
# query all students
sql = "select * from student where code=%s"
val = (code,)
cursor.execute(sql, val)
item = cursor.fetchone()
if item != None:
self.id = item[0]
self.code = item[1]
self.name = item[2]
self.age = item[3]
self.avatar = item[4]
self.intro = item[5]
self.lineEditId.setText(str(self.id))
self.lineEditCode.setText(self.code)
self.lineEditName.setText(self.name)
self.lineEditAge.setText(str(self.age))
self.lineEditIntro.setText(self.intro)
# self.labelAvatar.setPixmap(None)
if self.avatar != None:
imgdata = base64.b64decode(self.avatar)
pixmap = QPixmap()
pixmap.loadFromData(imgdata)
self.labelAvatar.setPixmap(pixmap)
else:
pixmap = QPixmap("images/ic_no_avatar.png")
self.labelAvatar.setPixmap(pixmap)
else:
print("Not Found")
cursor.close()
except:
traceback.print_exc()
Bước 4.6: Viết lệnh chọn Avatar và xóa Avatar, có tạo base64string
def pickAvatar(self):
filters = "Picture PNG (*.png);;All files(*)"
filename, selected_filter = QFileDialog.getOpenFileName(
self.MainWindow,
filter=filters,
)
if filename=='':
return
pixmap = QPixmap(filename)
self.labelAvatar.setPixmap(pixmap)
with open(filename, "rb") as image_file:
self.avatar = base64.b64encode(image_file.read())
print(self.avatar)
pass
def removeAvatar(self):
self.avatar=None
pixmap = QPixmap(self.default_avatar)
self.labelAvatar.setPixmap(pixmap)
Bước 4.7: Viết hàm thêm mới Student:
def processInsert(self):
try:
cursor = self.conn.cursor()
# query all students
sql = "insert into student(Code,Name,Age,Avatar,Intro) values(%s,%s,%s,%s,%s)"
self.code = self.lineEditCode.text()
self.name = self.lineEditName.text()
self.age = int(self.lineEditAge.text())
if not hasattr(self, 'avatar'):
avatar = None
intro = self.lineEditIntro.text()
val = (self.code, self.name, self.age, self.avatar, self.intro)
cursor.execute(sql, val)
self.conn.commit()
print(cursor.rowcount, " record inserted")
self.lineEditId.setText(str(cursor.lastrowid))
cursor.close()
self.selectAllStudent()
except:
traceback.print_exc()
Bước 4.8: Viết hàm cập nhật Student
def processUpdate(self):
cursor = self.conn.cursor()
# query all students
sql = "update student set Code=%s,Name=%s,Age=%s,Avatar=%s,Intro=%s" \
" where Id=%s"
self.id=int(self.lineEditId.text())
self.code = self.lineEditCode.text()
self.name = self.lineEditName.text()
self.age = int(self.lineEditAge.text())
if not hasattr(self, 'avatar'):
self.avatar = None
self.intro = self.lineEditIntro.text()
val = (self.code,self.name,self.age,self.avatar ,self.intro,self.id )
cursor.execute(sql, val)
self.conn.commit()
print(cursor.rowcount, " record updated")
cursor.close()
self.selectAllStudent()
Bước 4.9: Viết hàm xóa Student:
def processRemove(self):
dlg = QMessageBox(self.MainWindow)
dlg.setWindowTitle("Confirmation Deleting")
dlg.setText("Are you sure you want to delete?")
dlg.setIcon(QMessageBox.Icon.Question)
buttons = QMessageBox.StandardButton.Yes | QMessageBox.StandardButton.No
dlg.setStandardButtons(buttons)
button = dlg.exec()
if button == QMessageBox.StandardButton.No:
return
cursor = self.conn.cursor()
# query all students
sql = "delete from student "\
" where Id=%s"
val = (self.lineEditId.text(),)
cursor.execute(sql, val)
self.conn.commit()
print(cursor.rowcount, " record removed")
cursor.close()
self.selectAllStudent()
self.clearData()
Bước 4.10: Viết hàm xóa dữ liệu trên giao diện của phần chi tiết
def clearData(self):
self.lineEditId.setText("")
self.lineEditCode.setText("")
self.lineEditName.setText("")
self.lineEditAge.setText("")
self.lineEditIntro.setText("")
self.avatar=None
Dưới đây là mã lệnh đầy đủ của MainWindowEx.py:
import base64
import traceback
import mysql.connector
from PyQt6.QtGui import QPixmap
from PyQt6.QtWidgets import QTableWidgetItem, QFileDialog, QMessageBox
from MainWindow import Ui_MainWindow
class MainWindowEx(Ui_MainWindow):
def __init__(self):
super().__init__()
self.default_avatar="images/ic_no_avatar.png"
self.id = None
self.code = None
self.name = None
self.age = None
self.avatar = None
self.intro = None
def setupUi(self, MainWindow):
super().setupUi(MainWindow)
self.MainWindow=MainWindow
self.tableWidgetStudent.itemSelectionChanged.connect(self.processItemSelection)
self.pushButtonAvatar.clicked.connect(self.pickAvatar)
self.pushButtonRemoveAvatar.clicked.connect(self.removeAvatar)
self.pushButtonInsert.clicked.connect(self.processInsert)
self.pushButtonUpdate.clicked.connect(self.processUpdate)
self.pushButtonRemove.clicked.connect(self.processRemove)
def show(self):
self.MainWindow.show()
def connectMySQL(self):
server = "localhost"
port = 3306
database = "studentmanagement"
username = "root"
password = "@Obama123"
self.conn = mysql.connector.connect(
host=server,
port=port,
database=database,
user=username,
password=password)
def selectAllStudent(self):
cursor = self.conn.cursor()
# query all students
sql = "select * from student"
cursor.execute(sql)
dataset = cursor.fetchall()
self.tableWidgetStudent.setRowCount(0)
row=0
for item in dataset:
row = self.tableWidgetStudent.rowCount()
self.tableWidgetStudent.insertRow(row)
self.id = item[0]
self.code = item[1]
self.name = item[2]
self.age = item[3]
self.avatar = item[4]
self.intro = item[5]
self.tableWidgetStudent.setItem(row, 0, QTableWidgetItem(str(self.id)))
self.tableWidgetStudent.setItem(row, 1, QTableWidgetItem(self.code))
self.tableWidgetStudent.setItem(row, 2, QTableWidgetItem(self.name))
self.tableWidgetStudent.setItem(row, 3, QTableWidgetItem(str(self.age)))
cursor.close()
def processItemSelection(self):
row=self.tableWidgetStudent.currentRow()
if row ==-1:
return
try:
code = self.tableWidgetStudent.item(row, 1).text()
cursor = self.conn.cursor()
# query all students
sql = "select * from student where code=%s"
val = (code,)
cursor.execute(sql, val)
item = cursor.fetchone()
if item != None:
self.id = item[0]
self.code = item[1]
self.name = item[2]
self.age = item[3]
self.avatar = item[4]
self.intro = item[5]
self.lineEditId.setText(str(self.id))
self.lineEditCode.setText(self.code)
self.lineEditName.setText(self.name)
self.lineEditAge.setText(str(self.age))
self.lineEditIntro.setText(self.intro)
# self.labelAvatar.setPixmap(None)
if self.avatar != None:
imgdata = base64.b64decode(self.avatar)
pixmap = QPixmap()
pixmap.loadFromData(imgdata)
self.labelAvatar.setPixmap(pixmap)
else:
pixmap = QPixmap("images/ic_no_avatar.png")
self.labelAvatar.setPixmap(pixmap)
else:
print("Not Found")
cursor.close()
except:
traceback.print_exc()
def pickAvatar(self):
filters = "Picture PNG (*.png);;All files(*)"
filename, selected_filter = QFileDialog.getOpenFileName(
self.MainWindow,
filter=filters,
)
if filename=='':
return
pixmap = QPixmap(filename)
self.labelAvatar.setPixmap(pixmap)
with open(filename, "rb") as image_file:
self.avatar = base64.b64encode(image_file.read())
print(self.avatar)
pass
def removeAvatar(self):
self.avatar=None
pixmap = QPixmap(self.default_avatar)
self.labelAvatar.setPixmap(pixmap)
def processInsert(self):
try:
cursor = self.conn.cursor()
# query all students
sql = "insert into student(Code,Name,Age,Avatar,Intro) values(%s,%s,%s,%s,%s)"
self.code = self.lineEditCode.text()
self.name = self.lineEditName.text()
self.age = int(self.lineEditAge.text())
if not hasattr(self, 'avatar'):
avatar = None
intro = self.lineEditIntro.text()
val = (self.code, self.name, self.age, self.avatar, self.intro)
cursor.execute(sql, val)
self.conn.commit()
print(cursor.rowcount, " record inserted")
self.lineEditId.setText(str(cursor.lastrowid))
cursor.close()
self.selectAllStudent()
except:
traceback.print_exc()
def processUpdate(self):
cursor = self.conn.cursor()
# query all students
sql = "update student set Code=%s,Name=%s,Age=%s,Avatar=%s,Intro=%s" \
" where Id=%s"
self.id=int(self.lineEditId.text())
self.code = self.lineEditCode.text()
self.name = self.lineEditName.text()
self.age = int(self.lineEditAge.text())
if not hasattr(self, 'avatar'):
self.avatar = None
self.intro = self.lineEditIntro.text()
val = (self.code,self.name,self.age,self.avatar ,self.intro,self.id )
cursor.execute(sql, val)
self.conn.commit()
print(cursor.rowcount, " record updated")
cursor.close()
self.selectAllStudent()
def processRemove(self):
dlg = QMessageBox(self.MainWindow)
dlg.setWindowTitle("Confirmation Deleting")
dlg.setText("Are you sure you want to delete?")
dlg.setIcon(QMessageBox.Icon.Question)
buttons = QMessageBox.StandardButton.Yes | QMessageBox.StandardButton.No
dlg.setStandardButtons(buttons)
button = dlg.exec()
if button == QMessageBox.StandardButton.No:
return
cursor = self.conn.cursor()
# query all students
sql = "delete from student "\
" where Id=%s"
val = (self.lineEditId.text(),)
cursor.execute(sql, val)
self.conn.commit()
print(cursor.rowcount, " record removed")
cursor.close()
self.selectAllStudent()
self.clearData()
def clearData(self):
self.lineEditId.setText("")
self.lineEditCode.setText("")
self.lineEditName.setText("")
self.lineEditAge.setText("")
self.lineEditIntro.setText("")
self.avatar=None
Bước 5: Viết MyApp.py để thực thi phần mềm:
from PyQt6.QtWidgets import QApplication, QMainWindow
from MainWindowEx import MainWindowEx
app=QApplication([])
myWindow=MainWindowEx()
myWindow.setupUi(QMainWindow())
myWindow.connectMySQL()
myWindow.selectAllStudent()
myWindow.show()
app.exec()
Thực thi phần mềm ta có kết quả như mong muốn.
Đây là Case Study rất hay và quan trọng, làm nền tảng để làm các dự án khác, các bạn cố gắng thực hiện.
Source code đầy đủ của dự án bạn tải ở đây:
https://www.mediafire.com/file/c7x331c2pq5j4kp/StudentManagement.rar/file
Bài học tiếp theo Tui sẽ hướng dẫn các bạn cách mô hình hóa hướng đối tượng khi tương tác cơ sở dữ liệu
Chúc các bạn thành công
One thought on “Bài 49: Tương tác Python với Cơ sở dữ liệu MySQL Server -Quản lý Sinh viên”