因此,我使用PyQt5为数据库表单制作了一个GUI,它允许您对数据库执行不同的操作。选择、插入、删除、一般查看和清除。清除只是清除GUI表格中显示的数据。
选择、插入、删除和一般视图中的每一个,当按下时,都应该运行它们所连接的相应功能。在这些功能中,它们连接到数据库,运行查询并在表中显示结果。
然而,当我运行GUI并按下一个按钮,如General View,程序停止运行并崩溃,我在IDLE Shell中也没有得到任何追溯或错误报告。
我的代码如下:
from PyQt5 import QtCore, QtGui, QtWidgets
import mysql.connector as mc
from PyQt5.QtWidgets import QTableWidgetItem
class Ui_MainWindow(object):
def setupUi(self, MainWindow):
MainWindow.setObjectName("MainWindow")
MainWindow.resize(538, 487)
self.centralwidget = QtWidgets.QWidget(MainWindow)
self.centralwidget.setObjectName("centralwidget")
self.verticalLayout = QtWidgets.QVBoxLayout(self.centralwidget)
self.verticalLayout.setObjectName("verticalLayout")
self.gridLayout_2 = QtWidgets.QGridLayout()
self.gridLayout_2.setObjectName("gridLayout_2")
self.lineCMS = QtWidgets.QLineEdit(self.centralwidget)
self.lineCMS.setObjectName("lineCMS")
self.gridLayout_2.addWidget(self.lineCMS, 0, 1, 1, 1)
self.lineRoom = QtWidgets.QLineEdit(self.centralwidget)
self.lineRoom.setObjectName("lineRoom")
self.gridLayout_2.addWidget(self.lineRoom, 3, 1, 1, 1)
self.CMS = QtWidgets.QLabel(self.centralwidget)
self.CMS.setObjectName("CMS")
self.gridLayout_2.addWidget(self.CMS, 0, 0, 1, 1)
self.lineName = QtWidgets.QLineEdit(self.centralwidget)
self.lineName.setObjectName("lineName")
self.gridLayout_2.addWidget(self.lineName, 1, 1, 1, 1)
self.Room = QtWidgets.QLabel(self.centralwidget)
self.Room.setObjectName("Room")
self.gridLayout_2.addWidget(self.Room, 3, 0, 1, 1)
self.Department = QtWidgets.QLabel(self.centralwidget)
self.Department.setObjectName("Department")
self.gridLayout_2.addWidget(self.Department, 2, 0, 1, 1)
self.Name = QtWidgets.QLabel(self.centralwidget)
self.Name.setObjectName("Name")
self.gridLayout_2.addWidget(self.Name, 1, 0, 1, 1)
self.lineDepartment = QtWidgets.QLineEdit(self.centralwidget)
self.lineDepartment.setObjectName("lineDepartment")
self.gridLayout_2.addWidget(self.lineDepartment, 2, 1, 1, 1)
self.lineDOB = QtWidgets.QLineEdit(self.centralwidget)
self.lineDOB.setObjectName("lineDOB")
self.gridLayout_2.addWidget(self.lineDOB, 4, 1, 1, 1)
self.DOB = QtWidgets.QLabel(self.centralwidget)
self.DOB.setObjectName("DOB")
self.gridLayout_2.addWidget(self.DOB, 4, 0, 1, 1)
self.verticalLayout.addLayout(self.gridLayout_2)
self.horizontalLayout = QtWidgets.QHBoxLayout()
self.horizontalLayout.setObjectName("horizontalLayout")
self.Select = QtWidgets.QPushButton(self.centralwidget)
self.Select.setObjectName("Select")
self.horizontalLayout.addWidget(self.Select)
self.line = QtWidgets.QFrame(self.centralwidget)
self.line.setFrameShape(QtWidgets.QFrame.VLine)
self.line.setFrameShadow(QtWidgets.QFrame.Sunken)
self.line.setObjectName("line")
self.horizontalLayout.addWidget(self.line)
self.Insert = QtWidgets.QPushButton(self.centralwidget)
self.Insert.setObjectName("Insert")
self.horizontalLayout.addWidget(self.Insert)
self.line_2 = QtWidgets.QFrame(self.centralwidget)
self.line_2.setFrameShape(QtWidgets.QFrame.VLine)
self.line_2.setFrameShadow(QtWidgets.QFrame.Sunken)
self.line_2.setObjectName("line_2")
self.horizontalLayout.addWidget(self.line_2)
self.Delete = QtWidgets.QPushButton(self.centralwidget)
self.Delete.setObjectName("Delete")
self.horizontalLayout.addWidget(self.Delete)
self.line_3 = QtWidgets.QFrame(self.centralwidget)
self.line_3.setFrameShape(QtWidgets.QFrame.VLine)
self.line_3.setFrameShadow(QtWidgets.QFrame.Sunken)
self.line_3.setObjectName("line_3")
self.horizontalLayout.addWidget(self.line_3)
self.Clear = QtWidgets.QPushButton(self.centralwidget)
self.Clear.setObjectName("Clear")
self.horizontalLayout.addWidget(self.Clear)
self.verticalLayout.addLayout(self.horizontalLayout)
self.table = QtWidgets.QTableWidget(self.centralwidget)
self.table.setObjectName("table")
self.table.setColumnCount(5)
self.table.setRowCount(0)
item = QtWidgets.QTableWidgetItem()
self.table.setHorizontalHeaderItem(0, item)
item = QtWidgets.QTableWidgetItem()
self.table.setHorizontalHeaderItem(1, item)
item = QtWidgets.QTableWidgetItem()
self.table.setHorizontalHeaderItem(2, item)
item = QtWidgets.QTableWidgetItem()
self.table.setHorizontalHeaderItem(3, item)
item = QtWidgets.QTableWidgetItem()
self.table.setHorizontalHeaderItem(4, item)
self.verticalLayout.addWidget(self.table)
self.horizontalLayout_2 = QtWidgets.QHBoxLayout()
self.horizontalLayout_2.setObjectName("horizontalLayout_2")
self.verticalLayout.addLayout(self.horizontalLayout_2)
self.generalView = QtWidgets.QPushButton(self.centralwidget)
self.generalView.setObjectName("generalView")
self.verticalLayout.addWidget(self.generalView)
MainWindow.setCentralWidget(self.centralwidget)
self.menubar = QtWidgets.QMenuBar(MainWindow)
self.menubar.setGeometry(QtCore.QRect(0, 0, 538, 21))
self.menubar.setObjectName("menubar")
MainWindow.setMenuBar(self.menubar)
self.statusbar = QtWidgets.QStatusBar(MainWindow)
self.statusbar.setObjectName("statusbar")
MainWindow.setStatusBar(self.statusbar)
self.retranslateUi(MainWindow)
QtCore.QMetaObject.connectSlotsByName(MainWindow)
self.Select.clicked.connect(self.select)
self.Insert.clicked.connect(self.insert)
self.Delete.clicked.connect(self.delete)
self.generalView.clicked.connect(self.view)
self.Clear.clicked.connect(self.clear)
def retranslateUi(self, MainWindow):
_translate = QtCore.QCoreApplication.translate
MainWindow.setWindowTitle(_translate("MainWindow", "Student"))
self.CMS.setText(_translate("MainWindow", "CMS"))
self.Room.setText(_translate("MainWindow", "Room No."))
self.Department.setText(_translate("MainWindow", "Department"))
self.Name.setText(_translate("MainWindow", "Name"))
self.DOB.setText(_translate("MainWindow", "Date of Birth"))
self.Select.setText(_translate("MainWindow", "SELECT"))
self.Insert.setText(_translate("MainWindow", "INSERT"))
self.Delete.setText(_translate("MainWindow", "DELETE"))
self.Clear.setText(_translate("MainWindow", "CLEAR"))
item = self.table.horizontalHeaderItem(0)
item.setText(_translate("MainWindow", "CMS"))
item = self.table.horizontalHeaderItem(1)
item.setText(_translate("MainWindow", "Name"))
item = self.table.horizontalHeaderItem(2)
item.setText(_translate("MainWindow", "Department"))
item = self.table.horizontalHeaderItem(3)
item.setText(_translate("MainWindow", "Room No."))
item = self.table.horizontalHeaderItem(4)
item.setText(_translate("MainWindow", "Date of Birth"))
self.generalView.setText(_translate("MainWindow", "GENERAL VIEW"))
def select():
try:
self.table.setRowCount(0)
QCMS = self.lineCMS.text() + "%"
QDepartment = self.lineDepartment.text() + "%"
QName = self.lineName.text() + "%"
QRoom = self.lineRoom.text() + "%"
QDOB = self.lineDOB.text() + "%"
mydb = mc.connect(host="localhost",user="root",password="",database="sakila")
mycursor = mydb.cursor()
selectQuery = "SELECT * FROM Student WHERE CMS like '{}' and Department like '{}' and Name like '{}' and RoomNo like '{}' and DateOfBirth like '{}'".format(QCMS, QDepartment, QName, QRoom, QDOB)
mycursor.execute(selectQuery)
queryResult = mycursor.fetchall()
for row_number, row_data in enumerate(queryResult):
self.table.insertRow(row_number)
for column_number, data in enumerate(row_data):
self.table.setItem(row_number,column_number,QTableWidgetItem(str(data)))
except mc.Error as e:
print("Error!")
def insert():
try:
self.table.setRowCount(0)
QCMS = self.lineCMS.text() + "%"
QDepartment = self.lineDepartment.text() + "%"
QName = self.lineName.text() + "%"
QRoom = self.lineRoom.text() + "%"
QDOB = self.lineDOB.text() + "%"
mydb = mc.connect(host="localhost",user="root",password="",database="sakila")
mycursor = mydb.cursor()
insertQuery = "INSERT INTO Student Values({}, '{}', '{}', {}, '{}')".format(QCMS, QName, QDepartment, QRoom, QDOB)
triggerQuery = "SELECT * FROM Student WHERE CMS like '{}' and Department like '{}' and Name like '{}' and RoomNo like '{}' and DateOfBirth like '{}'".format(QCMS, QDepartment, QName, QRoom, QDOB)
mycursor.execute(insertQuery)
insertResult = mycursor.fetchall()
mycursor.execute(triggerQuery)
triggerResult = mycursor.fetchall()
for row_number, row_data in enumerate(triggerResult):
self.table.insertRow(row_number)
for column_number, data in enumerate(row_data):
self.table.setItem(row_number,column_number,QTableWidgetItem(str(data)))
except mc.Error as e:
print("Error!")
def delete():
try:
self.table.setRowCount(0)
QCMS = self.lineCMS.text() + "%"
QDepartment = self.lineDepartment.text() + "%"
QName = self.lineName.text() + "%"
QRoom = self.lineRoom.text() + "%"
QDOB = self.lineDOB.text() + "%"
mydb = mc.connect(host="localhost",user="root",password="",database="sakila")
mycursor = mydb.cursor()
deleteQuery = "DELETE FROM Student WHERE CMS like '{}' and Department like '{}' and Name like '{}' and RoomNo like '{}' and DateOfBirth like '{}'".format(QCMS, QDepartment, QName, QRoom, QDOB)
triggerQuery = "SELECT * FROM Student WHERE CMS like '{}' and Department like '{}' and Name like '{}' and RoomNo like '{}' and DateOfBirth like '{}'".format(QCMS, QDepartment, QName, QRoom, QDOB)
mycursor.execute(deleteQuery)
deleteResult = mycursor.fetchall()
mycursor.execute(triggerQuery)
triggerResult = mycursor.fetchall()
for row_number, row_data in enumerate(triggerResult):
self.table.insertRow(row_number)
for column_number, data in enumerate(row_data):
self.table.setItem(row_number,column_number,QTableWidgetItem(str(data)))
except mc.Error as e:
print("Error!")
def view():
try:
self.table.setRowCount(0)
mydb = mc.connect(host="localhost",user="root",password="",database="sakila")
mycursor = mydb.cursor()
query = "SELECT * FROM Student"
mycursor.execute(query)
queryResult = mycursor.fetchall()
for row_number, row_data in enumerate(queryResult):
self.table.insertRow(row_number)
for column_number, data in enumerate(row_data):
self.table.setItem(row_number,column_number,QTableWidgetItem(str(data)))
except mc.Error as e:
print("Error!")
def clear():
self.table.setRowCount(0)
if __name__ == "__main__":
import sys
app = QtWidgets.QApplication(sys.argv)
MainWindow = QtWidgets.QMainWindow()
ui = Ui_MainWindow()
ui.setupUi(MainWindow)
MainWindow.show()
sys.exit(app.exec_())
想不出任何与我现在的处境有关的事情。
1条答案
按热度按时间4nkexdtk1#
我最好的猜测是这是因为你没有在这个程序中使用任何线程。
当你点击一个按钮时,处理GUI事件(鼠标事件,窗口更新)的主事件循环被锁定,因为它正在处理你的按钮代码。这使得GUI看起来被冻结或崩溃(没有响应),因为事件循环忙碌其他事情。
使用PyQt5需要一些概念,线程、信号和插槽是两个核心概念。
线程是与主代码并行运行的代码,它们共享相同的代码空间,因此可以访问相似的变量。
信号和插槽是在主线程和其他正在运行的线程之间传递信息的一种方式。
在您的代码中,您将需要创建一个如下所示的线程类:
然后在
Ui_MainWindow
类中,让view方法启动线程,然后有一个新方法set_view,它只执行主事件循环负责更新的操作。所有这些的要点是你的事件循环只需要用它给出的数据更新表,这相对较快,但它不需要在你收集信息时冻结GUI。另一个注意,GUI小部件不能通过线程修改,所以像self.lineedit.setText(“Hello”)这样的操作在线程中不起作用,它需要由主线程完成。
注意:此代码仅作为示例,不能作为工作代码复制和粘贴。
我建议在你当前的图形用户界面中,点击一个按钮,如果图形用户界面冻结了,就等它出来,看看它最终是否会再次响应。这就是你知道你需要实现这个解决方案的方法。我希望这对你有帮助:)