Как удалить выделенную строку из 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 шт):

Автор решения: S. Nick

Модель QSqlQueryModel предоставляет операции только для чтения.

Если вы хотите получать и операции записи, вам необходимо наследовать QSqlQueryModel и повторно реализовать методы setData() и flag().

Другой вариант - использовать QSqlTableModel, который доступен для чтения и записи.

→ Ссылка
Автор решения: Cookie Agent

Благодаря подсказкам здесь и на других форумах, публикую рабочее решение, мало ли кому пригодится. Для начала нужно создать свою модель которая будет наследоваться от 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'
                                                         'Выделите строку и повторите удаление.')
→ Ссылка