Удаление строки из базы данных PyQt5, QTableView
Не могу понять почему не работает удаление строки по её ID из БД (при выполнении запроса программа завершается с ошибкой(скрин2))?
Также ради интереса хотелось бы узнать почему после выполнения setHeaderName не меняются имена колонок в заголовке.
Планируемая реализация функционала программы(скрин 1):
from PyQt5 import QtCore, QtGui, QtWidgets
from PyQt5.QtSql import QSqlDatabase, QSqlQuery, QSqlTableModel, QSqlQueryModel
from PyQt5.Qt import *
class Ui_MainWindow(object):
def setupUi(self, MainWindow):
MainWindow.setObjectName("MainWindow")
MainWindow.setFixedHeight(600)
MainWindow.setFixedWidth(900)
MainWindow.setStyleSheet("background:rgb(47, 150, 171)")
self.centralwidget = QtWidgets.QWidget(MainWindow)
sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Preferred, QtWidgets.QSizePolicy.Preferred)
sizePolicy.setHorizontalStretch(0)
sizePolicy.setVerticalStretch(0)
sizePolicy.setHeightForWidth(self.centralwidget.sizePolicy().hasHeightForWidth())
self.centralwidget.setSizePolicy(sizePolicy)
self.centralwidget.setObjectName("centralwidget")
self.frame = QtWidgets.QFrame(self.centralwidget)
self.frame.setEnabled(True)
self.frame.setGeometry(QtCore.QRect(0, 0, 901, 601))
self.frame.setStyleSheet("border: 4px solid \'#FFFFFF\';\n"
"border-radius: 15px;\n"
"margin: 10px;\n"
"background: #FFFFFF")
self.frame.setFrameShape(QtWidgets.QFrame.StyledPanel)
self.frame.setFrameShadow(QtWidgets.QFrame.Raised)
self.frame.setObjectName("frame")
self.horizontalLayoutWidget = QtWidgets.QWidget(self.frame)
self.horizontalLayoutWidget.setGeometry(QtCore.QRect(20, 20, 861, 71))
self.horizontalLayoutWidget.setObjectName("horizontalLayoutWidget")
self.horizontalLayout = QtWidgets.QHBoxLayout(self.horizontalLayoutWidget)
self.horizontalLayout.setContentsMargins(0, 0, 0, 0)
self.horizontalLayout.setObjectName("horizontalLayout")
self.pushButton_3 = QtWidgets.QPushButton(self.horizontalLayoutWidget)
font = QtGui.QFont()
font.setPointSize(10)
self.pushButton_3.setFont(font)
self.pushButton_3.setMouseTracking(True)
self.pushButton_3.setStyleSheet(
"border: 0;\n"
"border-radius: 15px;\n"
"background: qlineargradient(spread:pad, x1:0, y1:0, x2:1, y2:0, stop:0 rgba(45, 172, 235), stop:1 rgba(72,102,175));\n"
"color: #FFFFFF;\n"
"padding: 8px 16px;\n"
"font-size: 16px;\n"
"")
self.pushButton_3.setObjectName("pushButton_3")
self.horizontalLayout.addWidget(self.pushButton_3)
self.pushButton_2 = QtWidgets.QPushButton(self.horizontalLayoutWidget)
font = QtGui.QFont()
font.setPointSize(10)
self.pushButton_2.setFont(font)
self.pushButton_2.setStyleSheet(
"border: 0;\n"
"border-radius: 15px;\n"
"background: qlineargradient(spread:pad, x1:0, y1:0, x2:1, y2:0, stop:0 rgba(45, 172, 235), stop:1 rgba(72,102,175));\n"
"color: #FFFFFF;\n"
"padding: 8px 16px;\n"
"font-size: 16px;")
self.pushButton_2.setObjectName("pushButton_2")
self.horizontalLayout.addWidget(self.pushButton_2)
self.pushButton_4 = QtWidgets.QPushButton(self.horizontalLayoutWidget)
font = QtGui.QFont()
font.setPointSize(10)
self.pushButton_4.setFont(font)
self.pushButton_4.setStyleSheet(
"border: 0;\n"
"border-radius: 15px;\n"
"background: qlineargradient(spread:pad, x1:0, y1:0, x2:1, y2:0, stop:0 rgba(45, 172, 235), stop:1 rgba(72,102,175));\n"
"color: #FFFFFF;\n"
"padding: 8px 16px;\n"
"font-size: 16px;\n"
"")
self.pushButton_4.setObjectName("pushButton_4")
self.horizontalLayout.addWidget(self.pushButton_4)
self.pushButton = QtWidgets.QPushButton(self.horizontalLayoutWidget)
font = QtGui.QFont()
font.setPointSize(10)
self.pushButton.setFont(font)
self.pushButton.setStyleSheet(
"border: 0;\n"
"border-radius: 15px;\n"
"background: qlineargradient(spread:pad, x1:0, y1:0, x2:1, y2:0, stop:0 rgba(45, 172, 235), stop:1 rgba(72,102,175));\n"
"color: #FFFFFF;\n"
"padding: 8px 16px;\n"
"font-size: 16px;")
self.pushButton.setObjectName("pushButton")
self.horizontalLayout.addWidget(self.pushButton)
self.tableWidget = QtWidgets.QTableView(self.frame)
self.tableWidget.setGeometry(QtCore.QRect(40, 220, 830, 351))
self.tableWidget.setMinimumSize(QtCore.QSize(830, 351))
self.tableWidget.setMaximumSize(QtCore.QSize(811, 351))
self.tableWidget.setStyleSheet("border: 4px solid \'#2DACEB\';\n"
"border-radius: 15px;\n"
"margin: 10px;\n"
"background: #FFFFFF")
self.tableWidget.setObjectName("tableWidget")
MainWindow.setCentralWidget(self.centralwidget)
self.retranslateUi(MainWindow)
QtCore.QMetaObject.connectSlotsByName(MainWindow)
def retranslateUi(self, MainWindow):
_translate = QtCore.QCoreApplication.translate
MainWindow.setWindowTitle(_translate("MainWindow", "Запись к стоматологу"))
self.pushButton_3.setText(_translate("MainWindow", "Добавить запись"))
self.pushButton_2.setText(_translate("MainWindow", "Удалить запись"))
self.pushButton_4.setText(_translate("MainWindow", "Обновить"))
self.pushButton.setText(_translate("MainWindow", "Выход"))
self.pushButton.setCursor(QCursor(QtCore.Qt.PointingHandCursor))
self.pushButton_3.setCursor(QCursor(QtCore.Qt.PointingHandCursor))
self.pushButton_2.setCursor(QCursor(QtCore.Qt.PointingHandCursor))
self.pushButton_4.setCursor(QCursor(QtCore.Qt.PointingHandCursor))
class Dialog(QDialog):
def __init__(self):
super().__init__()
self.setWindowTitle('Добавление записи')
self.line_edit_name = QLineEdit()
self.line_edit_nazn = QLineEdit()
self.line_edit_data = QLineEdit()
form_layout = QFormLayout()
form_layout.addRow('ФИО:', self.line_edit_name)
form_layout.addRow('Назначения:', self.line_edit_nazn)
form_layout.addRow('Дата:', self.line_edit_data)
button_box = QDialogButtonBox(QDialogButtonBox.Ok | QDialogButtonBox.Cancel)
button_box.setStyleSheet(
"border: 0;\n"
"border-radius: 15px;\n"
"background: qlineargradient(spread:pad, x1:0, y1:0, x2:1, y2:0, stop:0 rgba(45, 172, 235), stop:1 rgba(72,102,175));\n"
"color: #FFFFFF;\n"
"padding: 8px 16px;\n"
"font-size: 16px;\n"
"")
button_box.accepted.connect(self.accept)
button_box.rejected.connect(self.reject)
main_layout = QVBoxLayout()
main_layout.addLayout(form_layout)
main_layout.addWidget(button_box)
self.setLayout(main_layout)
class Dialog2(QDialog):
def __init__(self):
super().__init__()
self.setWindowTitle('Удаление записи')
self.line_edit_id = QLineEdit()
form_layout = QFormLayout()
form_layout.addRow('Номер записи для удаления:', self.line_edit_id)
button_box = QDialogButtonBox(QDialogButtonBox.Ok | QDialogButtonBox.Cancel)
button_box.setStyleSheet(
"border: 0;\n"
"border-radius: 15px;\n"
"background: qlineargradient(spread:pad, x1:0, y1:0, x2:1, y2:0, stop:0 rgba(45, 172, 235), stop:1 rgba(72,102,175));\n"
"color: #FFFFFF;\n"
"padding: 8px 16px;\n"
"font-size: 16px;\n"
"")
button_box.accepted.connect(self.accept)
button_box.rejected.connect(self.reject)
main_layout = QVBoxLayout()
main_layout.addLayout(form_layout)
main_layout.addWidget(button_box)
self.setLayout(main_layout)
class MainWindow(QtWidgets.QMainWindow, Ui_MainWindow):
def __init__(self):
super().__init__()
self.setupUi(self)
self.setWindowFlags(Qt.FramelessWindowHint)
self.pushButton.clicked.connect(self.close)
self.pushButton_3.clicked.connect(self.add_row)
self.pushButton_2.clicked.connect(self.remove_row)
db = QSqlDatabase.addDatabase('QSQLITE')
db.setDatabaseName('Stomatolog.db')
db.open()
self.model = QSqlTableModel(self)
self.model.setTable("Records")
self.model.select()
self.tableWidget.setModel(self.model)
self.tableWidget.horizontalHeader().setStretchLastSection(True)
self.tableWidget.horizontalHeader().setSectionResizeMode(QHeaderView.Stretch)
def add_row(self):
inputDialog = Dialog()
rez = inputDialog.exec()
if not rez:
msg = QMessageBox.information(self, 'Внимание', 'Вы отменили добавление записи.')
return
name = inputDialog.line_edit_name.text()
nazn = inputDialog.line_edit_nazn.text()
data = inputDialog.line_edit_data.text()
if not name or not nazn or not data:
msg = QMessageBox.information(self, 'Внимание', 'Пожалуйста, заполните все поля.')
return
r = self.model.record()
r.setValue("FIO", name)
r.setValue("NAZN", nazn)
r.setValue("DATA", data)
self.model.insertRecord(-1, r)
self.model.select()
def remove_row(self):
inputDialog2 = Dialog2()
rez = inputDialog2.exec()
if not rez:
msg1 = QMessageBox.information(self, 'Внимание', 'Вы отменили удаление записи записи.')
return
self.model.removeRow(row=-inputDialog2.line_edit_id.text()) #????????????????????
if __name__ == "__main__":
import sys
app = QtWidgets.QApplication(sys.argv)
w = MainWindow()
w.show()
sys.exit(app.exec_())
Ответы (1 шт):
Автор решения: S. Nick
→ Ссылка
Я добавил метод удаления записи в свой ответ на ваш предыдущий вопрос.
Попробуйте так:
from PyQt5 import QtCore, QtGui, QtWidgets
from PyQt5.QtSql import QSqlDatabase, QSqlQuery, QSqlTableModel, QSqlQueryModel
from PyQt5.Qt import *
class Ui_MainWindow(object):
def setupUi(self, MainWindow):
MainWindow.setObjectName("MainWindow")
MainWindow.setFixedHeight(600)
MainWindow.setFixedWidth(900)
MainWindow.setStyleSheet("background:rgb(47, 150, 171)")
self.centralwidget = QtWidgets.QWidget(MainWindow)
sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Preferred, QtWidgets.QSizePolicy.Preferred)
sizePolicy.setHorizontalStretch(0)
sizePolicy.setVerticalStretch(0)
sizePolicy.setHeightForWidth(self.centralwidget.sizePolicy().hasHeightForWidth())
self.centralwidget.setSizePolicy(sizePolicy)
self.centralwidget.setObjectName("centralwidget")
self.frame = QtWidgets.QFrame(self.centralwidget)
self.frame.setEnabled(True)
self.frame.setGeometry(QtCore.QRect(0, 0, 901, 601))
self.frame.setStyleSheet("border: 4px solid \'#FFFFFF\';\n"
"border-radius: 15px;\n"
"margin: 10px;\n"
"background: #FFFFFF")
self.frame.setFrameShape(QtWidgets.QFrame.StyledPanel)
self.frame.setFrameShadow(QtWidgets.QFrame.Raised)
self.frame.setObjectName("frame")
self.horizontalLayoutWidget = QtWidgets.QWidget(self.frame)
self.horizontalLayoutWidget.setGeometry(QtCore.QRect(20, 20, 861, 71))
self.horizontalLayoutWidget.setObjectName("horizontalLayoutWidget")
self.horizontalLayout = QtWidgets.QHBoxLayout(self.horizontalLayoutWidget)
self.horizontalLayout.setContentsMargins(0, 0, 0, 0)
self.horizontalLayout.setObjectName("horizontalLayout")
self.pushButton_3 = QtWidgets.QPushButton(self.horizontalLayoutWidget)
font = QtGui.QFont()
font.setPointSize(10)
self.pushButton_3.setFont(font)
self.pushButton_3.setMouseTracking(True)
self.pushButton_3.setStyleSheet(
"border: 0;\n"
"border-radius: 15px;\n"
"background: qlineargradient(spread:pad, x1:0, y1:0, x2:1, y2:0, stop:0 rgba(45, 172, 235), stop:1 rgba(72,102,175));\n"
"color: #FFFFFF;\n"
"padding: 8px 16px;\n"
"font-size: 16px;\n"
"")
self.pushButton_3.setObjectName("pushButton_3")
self.horizontalLayout.addWidget(self.pushButton_3)
self.pushButton_2 = QtWidgets.QPushButton(self.horizontalLayoutWidget)
font = QtGui.QFont()
font.setPointSize(10)
self.pushButton_2.setFont(font)
self.pushButton_2.setStyleSheet(
"border: 0;\n"
"border-radius: 15px;\n"
"background: qlineargradient(spread:pad, x1:0, y1:0, x2:1, y2:0, stop:0 rgba(45, 172, 235), stop:1 rgba(72,102,175));\n"
"color: #FFFFFF;\n"
"padding: 8px 16px;\n"
"font-size: 16px;")
self.pushButton_2.setObjectName("pushButton_2")
self.horizontalLayout.addWidget(self.pushButton_2)
self.pushButton_4 = QtWidgets.QPushButton(self.horizontalLayoutWidget)
font = QtGui.QFont()
font.setPointSize(10)
self.pushButton_4.setFont(font)
self.pushButton_4.setStyleSheet(
"border: 0;\n"
"border-radius: 15px;\n"
"background: qlineargradient(spread:pad, x1:0, y1:0, x2:1, y2:0, stop:0 rgba(45, 172, 235), stop:1 rgba(72,102,175));\n"
"color: #FFFFFF;\n"
"padding: 8px 16px;\n"
"font-size: 16px;\n"
"")
self.pushButton_4.setObjectName("pushButton_4")
self.horizontalLayout.addWidget(self.pushButton_4)
self.pushButton = QtWidgets.QPushButton(self.horizontalLayoutWidget)
font = QtGui.QFont()
font.setPointSize(10)
self.pushButton.setFont(font)
self.pushButton.setStyleSheet(
"border: 0;\n"
"border-radius: 15px;\n"
"background: qlineargradient(spread:pad, x1:0, y1:0, x2:1, y2:0, stop:0 rgba(45, 172, 235), stop:1 rgba(72,102,175));\n"
"color: #FFFFFF;\n"
"padding: 8px 16px;\n"
"font-size: 16px;")
self.pushButton.setObjectName("pushButton")
self.horizontalLayout.addWidget(self.pushButton)
self.tableWidget = QtWidgets.QTableView(self.frame) # QTableView !!!
self.tableWidget.setGeometry(QtCore.QRect(40, 220, 830, 351))
self.tableWidget.setMinimumSize(QtCore.QSize(830, 351))
self.tableWidget.setMaximumSize(QtCore.QSize(811, 351))
self.tableWidget.setStyleSheet("border: 4px solid \'#2DACEB\';\n"
"border-radius: 15px;\n"
"margin: 10px;\n"
"background: #FFFFFF")
self.tableWidget.setObjectName("tableWidget")
MainWindow.setCentralWidget(self.centralwidget)
self.retranslateUi(MainWindow)
QtCore.QMetaObject.connectSlotsByName(MainWindow)
def retranslateUi(self, MainWindow):
_translate = QtCore.QCoreApplication.translate
MainWindow.setWindowTitle(_translate("MainWindow", "Запись к стоматологу"))
self.pushButton_3.setText(_translate("MainWindow", "Добавить запись"))
self.pushButton_2.setText(_translate("MainWindow", "Удалить запись"))
self.pushButton_4.setText(_translate("MainWindow", "Обновить"))
self.pushButton.setText(_translate("MainWindow", "Выход"))
self.pushButton.setCursor(QCursor(QtCore.Qt.PointingHandCursor))
self.pushButton_3.setCursor(QCursor(QtCore.Qt.PointingHandCursor))
self.pushButton_2.setCursor(QCursor(QtCore.Qt.PointingHandCursor))
self.pushButton_4.setCursor(QCursor(QtCore.Qt.PointingHandCursor))
class Dialog(QDialog):
def __init__(self):
super().__init__()
self.setWindowTitle('Input Dialog')
self.line_edit_name = QLineEdit()
self.line_edit_age = QLineEdit()
self.line_edit_gender = QLineEdit()
form_layout = QFormLayout()
form_layout.addRow('Name:', self.line_edit_name)
form_layout.addRow('Age:', self.line_edit_age)
form_layout.addRow('Gender:', self.line_edit_gender)
button_box = QDialogButtonBox(QDialogButtonBox.Ok | QDialogButtonBox.Cancel)
button_box.accepted.connect(self.accept)
button_box.rejected.connect(self.reject)
main_layout = QVBoxLayout()
main_layout.addLayout(form_layout)
main_layout.addWidget(button_box)
self.setLayout(main_layout)
class MainWindow(QtWidgets.QMainWindow, Ui_MainWindow):
def __init__(self):
super().__init__()
self.setupUi(self)
self.pushButton.clicked.connect(self.close)
self.pushButton_3.clicked.connect(self.add_row)
self.pushButton_2.clicked.connect(self.on_del_record) # Удалить запись
# 1. Создайте соединение с базой данных, вызвав метод addDatabase() класса QSqlDatabase.
# Так как вы хотите соединиться с базой данных SQLite, параметры QSQLITE передаются здесь.
db = QSqlDatabase.addDatabase('QSQLITE')
# 2. Вызовите setDatabaseName(), чтобы установить имя базы данных, которое будет использоваться.
# Вам нужно только написать путь, а имя файла заканчивается на .db
# (если база данных уже существует, используйте базу данных; если она не существует,
# будет создана новая);
db.setDatabaseName('book.db') # !!! ваша db
# 3. Вызовите метод open(), чтобы открыть базу данных.
# Если открытие прошло успешно, оно вернет True, а в случае неудачи - False.
db.open()
# Создайте модель QSqlTableModel и вызовите setTable(),
# чтобы выбрать таблицу данных для обработки.
self.model = QSqlTableModel(self)
self.model.setTable("card") # !!! тавлица в db
# вызовите метод select(), чтобы выбрать все данные в таблице, и соответствующее
# представление также отобразит все данные;
self.model.select()
self.tableWidget.setModel(self.model)
def add_row(self):
inputDialog = Dialog()
rez = inputDialog.exec()
if not rez:
msg = QMessageBox.information(self, 'Внимание', 'Диалог сброшен.')
return
name = inputDialog.line_edit_name.text()
age = inputDialog.line_edit_age.text()
gender = inputDialog.line_edit_gender.text()
if not name or not age or not gender:
msg = QMessageBox.information(self, 'Внимание', 'Заполните пожалуйста все поля.')
return
r = self.model.record()
r.setValue("name", name)
r.setValue("age", age)
r.setValue("gender", gender)
self.model.insertRecord(-1, r)
self.model.select()
# +++ vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv
# Удалить запись
def on_del_record(self):
row = self.tableWidget.currentIndex().row()
if row == -1:
msg = QMessageBox.information(self, 'Внимание', 'Выберите запись для удаления.')
return
name = self.model.record(row).value(1)
age = self.model.record(row).value(2)
gender = self.model.record(row).value(3)
inputDialog = Dialog()
inputDialog.setWindowTitle('Удалить запись ???')
inputDialog.line_edit_name.setText(name)
inputDialog.line_edit_age.setText(str(age))
inputDialog.line_edit_gender.setText(gender)
rez = inputDialog.exec()
if not rez:
msg = QMessageBox.information(self, 'Внимание', 'Диалог сброшен.')
return
self.model.removeRow(self.tableWidget.currentIndex().row()) # Удалить запись !!!
self.model.select() # Удалить запись !!!
msg = QMessageBox.information(self, 'Успех', 'Запись удалена.')
# +++ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
if __name__ == "__main__":
import sys
app = QtWidgets.QApplication(sys.argv)
w = MainWindow()
w.show()
sys.exit(app.exec_())


