Различное поведение QSqlQueryModel для обновления данных после добавления и обновления записи - PullRequest
0 голосов
/ 13 апреля 2020

У меня есть QTableView с меню для добавления и редактирования записей. Модель подготовлена ​​с помощью QSqlQueryModel, так как она показывает также связанные данные (суммы суммы) для записей.

После выполнения действий я хочу обновить sh таблицу. Я не понимаю, почему для действия редактирования достаточно сделать model.query().exec_(), чтобы увидеть обновление, но для нового действия мне нужно дополнительно сделать model.setQuery(model.query()), чтобы увидеть вновь вставленные строки.

    def build_model(self):
        self.model = QSqlQueryModel()
        self.model.setQuery("SELECT b.id, b.name, SUM(coalesce(s.amount, 0.00)) as amount\
                            FROM budget AS b\
                                LEFT OUTER JOIN transaction_split as s ON s.id_budget = b.id\
                            GROUP BY b.id\
                            ORDER BY name")
        self.table.setModel(self.model)


    def act_new(self):
        dlg = BudgetEd()
        dlg.dialog.exec()

        self.model.query().exec_()
        self.model.setQuery(self.model.query()) # Why I need to this? to refresh the view

    def act_ed(self):
        # ... retrieve id_
        dlg = BudgetEd(id_)
        dlg.dialog.exec()
        self.model.query().exec_() # or why this works without setting the query in the model again?

1 Ответ

0 голосов
/ 17 апреля 2020

Наконец, я решил не использовать QSqlQueryModel (), поскольку это конфликтовало с запросами sqlalchemy на Windows (windows блокирует файлы для чтения). Я реализовал свою собственную TableModel (QAbstractTableModel), так как это была действительно простая задача:

class TableModel(QAbstractTableModel):
    sql: text

    def __init__(self):
        super().__init__()
        self._data = []
        self.sql = None

    def set_sql(self, sql: str):
        self.sql = text(sql)

    def load_data(self):
        sess: session = Session()
        self._data = sess.execute(self.sql).fetchall()
        self.layoutChanged.emit()

    def set_data(self, data):
        self._data = data

    def data(self, index: PySide2.QtCore.QModelIndex, role: int = ...) -> typing.Any:
        if role == Qt.DisplayRole:
            value = self._data[index.row()][index.column()]
            return value
        if role == Qt.UserRole:
            return self._data[index.row()][index.column()]
        if role == Qt.TextAlignmentRole:
            value = self._data[index.row()][index.column()]
            if isinstance(value, int) or isinstance(value, float):
                return int(Qt.AlignRight | Qt.AlignVCenter)


    def rowCount(self, parent: PySide2.QtCore.QModelIndex = ...) -> int:
        return len(self._data)

    def columnCount(self, parent: PySide2.QtCore.QModelIndex = ...) -> int:
        return len(self._data[0])

# ...
    def act_new(self):
        dlg = AssetEd()
        dlg.dialog.exec()
        self.model.load_data()
...