Как удалить выделенную строку из QTableView?
Есть QSqlQueryModel которая вытягивает данные из базы данных и передает их в QTableView. Я знаю что модель QSqlQueryModel только для чтения. Подскажите можно ли удалить выделенную строку из QTableView и обновить модель? Или на какую модель заменить мою текущую?
'''
def connect_column_calc(self):
self.temp_calculation = QSqlQueryModel()
self.temp_calculation.setQuery('SELECT id, number_invoice, inv_date, company_name, '
'(all_sum / 100.0) AS all_sum, signatory FROM calculation')
self.calculation_model = QSortFilterProxyModel()
self.calculation_model.setSourceModel(self.temp_calculation)
self.inv_tabView.setModel(self.calculation_model)
def del_pushbutton(self):
if self.inv_tabView.selectionModel().hasSelection():
for index in self.inv_tabView.selectedIndexes() or []:
print('Удаляется строка %d...' % index.row())
self.temp_calculation.setQuery('DELETE FROM calculation WHERE id = %d' % index.row())
print(self.temp_calculation.lastError().text())
else:
QMessageBox.warning(None, 'Ошибка удаления', 'Строки для удаления отсутствуют! \n'
'Выделите строку и повторите удаление.')
'''
Ответы (2 шт):
Модель QSqlQueryModel предоставляет операции только для чтения.
Если вы хотите получать и операции записи, вам необходимо
наследовать QSqlQueryModel и повторно реализовать методы setData() и flag().
Другой вариант - использовать QSqlTableModel, который доступен для чтения и записи.
Благодаря подсказкам здесь и на других форумах, публикую рабочее решение, мало ли кому пригодится.
Для начала нужно создать свою модель которая будет наследоваться от QSqlQueryModel. В своей моделе предопределяем методы setData() и flag() которые позволят редактировать модель. Далее предопределяем функцию удаления. Функции удаления я передаю значения id из БД, а не index модели т.к. значения id может отличаться от индекса модели.
Вот сам код:
class NewSqlModel(QSqlQueryModel):
def __init__(self, parent=None):
super(NewSqlModel, self).__init__()
def flags(self, index):
"""Метод возвращает набор констант для элемента /
с указанным индексом"""
f1 = QSqlQueryModel.flags(self, index)
if index.column() == 0:
f1 |= Qt.ItemIsEditable
return f1
def setData(self, index, value, role=Qt.EditRole):
"""Метод должен выполнить задачу установки данных /
и вернуть значение были ли внесены изменения."""
self.data = QSqlQueryModel.data(self, index, role)
if index.isValid():
self.data(index.row(), value)
self.dataChanged.emit(index, index, role)
return True
return False
def removeRows(self, index, count, parent=QModelIndex()):
"""Метод реализует операцию удаления записи из БД. /
В качестве индекса используется id записи из БД"""
self.beginRemoveRows(parent, index, index)
query = QSqlQuery()
query.exec_('DELETE FROM calculation WHERE id = %d' % index)
print(query.lastError().text())
self.endRemoveRows()
self.refresh()
return True
def refresh(self):
"""Функция перезапускает текущую модель"""
query = QSqlQuery()
query.exec_('SELECT id, number_invoice, inv_date, company_name, '
'(all_sum / 100.0) AS all_sum, signatory FROM calculation')
self.setQuery(query)
И подключение таблицы БД к модели и вызов функции удаления:
def connect_column_calc(self):
"""Функция подключает таблицу к моделе"""
self.calculation_model = NewSqlModel()
self.calculation_model.setQuery('SELECT id, number_invoice, inv_date, company_name, '
'(all_sum / 100.0) AS all_sum, signatory FROM calculation')
def del_pushbutton(self):
"""Функция удаляет выделенную строку из БД.
Запускается через кнопку"""
if self.inv_tabView.selectionModel().hasSelection():
for index in self.inv_tabView.selectedIndexes() or []:
print('Удаляется строка %d...' % index.row())
# Получаем id выделенной строки
id_row = self.calculation_model.data(self.calculation_model.index(
self.inv_tabView.currentIndex().row(), 0))
self.inv_tabView.model().removeRows(id_row)
else:
QMessageBox.warning(None, 'Ошибка удаления', 'Строки для удаления отсутствуют! \n'
'Выделите строку и повторите удаление.')