python - 使用 QSqlTableModel 和 QTableView 模型和 View 布局,是否可以在我的表中有一列来隐藏行

标签 python python-3.x sqlite pyqt pyqt5

使用 QSqlTableModel 和 QTableView,我的表中是否可以有一个列(int),当我在该列的一行上输入“1”时,该行将从 TableView 中隐藏,但不会从数据库中删除。 我想要实现的是一种临时情况,其中行隐藏且尚未从数据库中删除,并且可以保留在该位置,直到(如果仍然需要)隐藏行被取消隐藏或(不需要)该行被删除从数据库中永久删除,这是一种取消删除的情况。

我查看了sqlite3,看看是否有任何方法可以标记一行,以便在qt调用时不会显示它,我也查看了qt的其他部分,但网上没有太多信息或任何新的信息最新的书籍可供学习,我问是否有人知道解决方法或已经用另一个qt函数尝试过这种方法,我不知道其中有多少函数有效。

最佳答案

一种可能的解决方案是使用 QSortFilterProxyModel隐藏行:

import random
import string
from functools import partial

from PyQt5 import QtCore, QtWidgets, QtSql


def randomString(stringLength=10):
    """Generate a random string of fixed length """
    letters = string.ascii_lowercase
    return "".join(random.sample(letters, stringLength))


def createConnection():
    db = QtSql.QSqlDatabase.addDatabase("QSQLITE")
    db.setDatabaseName(":memory:")
    if not db.open():
        QtSql.QMessageBox.critical(
            None,
            QtWidgets.qApp.tr("Cannot open database"),
            QtWidgets.qApp.tr(
                "Unable to establish a database connection.\n"
                "This example needs SQLite support. Please read "
                "the Qt SQL driver documentation for information "
                "how to build it.\n\n"
                "Click Cancel to exit."
            ),
            QtWidgets.QMessageBox.Cancel,
        )
        return False

    query = QtSql.QSqlQuery()
    query.exec_(
        """
        CREATE TABLE "mytable" (
            "id"    INTEGER PRIMARY KEY AUTOINCREMENT,
            "col1"  TEXT,
            "col2"  TEXT,
            "col3"  TEXT,
            "col4"  TEXT,
            "hide"  INTEGER
        );
    """
    )

    for _ in range(10):
        query = QtSql.QSqlQuery()
        query.prepare(
            """INSERT INTO mytable (col1, col2, col3, col4) VALUES(?, ?, ?, ?);"""
        )
        for _ in range(4):
            query.addBindValue(randomString())
        query.exec_()
    return True


FILTER_VALUE = 1


class HideProxyModel(QtCore.QSortFilterProxyModel):
    def filterAcceptsRow(self, sourceRow, sourceParent):
        col = self.sourceModel().fieldIndex("hide")
        ix = self.sourceModel().index(sourceRow, col, sourceParent)
        return ix.data() != FILTER_VALUE


class Widget(QtWidgets.QWidget):
    def __init__(self, parent=None):
        super(Widget, self).__init__(parent)
        button = QtWidgets.QPushButton("Hide", clicked=self.onClicked)
        self.m_view = QtWidgets.QTableView(
            selectionBehavior=QtWidgets.QAbstractItemView.SelectRows
        )
        self.m_model = QtSql.QSqlTableModel()
        self.m_model.setTable("mytable")
        self.m_model.select()

        self.m_proxy = HideProxyModel()
        self.m_proxy.setSourceModel(self.m_model)
        self.m_view.setModel(self.m_proxy)

        lay = QtWidgets.QVBoxLayout(self)
        lay.addWidget(button)
        lay.addWidget(self.m_view)

    @QtCore.pyqtSlot()
    def onClicked(self):
        rows = set(
            self.m_proxy.mapToSource(ix).row()
            for ix in self.m_view.selectedIndexes()
        )
        self.m_view.clearSelection()
        col = self.m_model.fieldIndex("hide")
        for row in rows:
            rec = self.m_model.record(row)
            rec.setValue(col, FILTER_VALUE)
            self.m_model.setRecord(row, rec)


if __name__ == "__main__":
    import sys

    app = QtWidgets.QApplication(sys.argv)

    if not createConnection():
        sys.exit(-1)

    w = Widget()
    w.resize(640, 480)
    w.show()

    sys.exit(app.exec_())

关于python - 使用 QSqlTableModel 和 QTableView 模型和 View 布局,是否可以在我的表中有一列来隐藏行,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/56530986/

相关文章:

python - 日期时间选择器和模式冲突 Angular ui Bootstrap

Python:如何查找数组中特定元素的索引?

database - SQLite WAL 在电源故障时有多安全?

sqlite - Xamarin Android 如何检索设备数据库

python - pyodbc 连接到 sqlite 数据库

Python tkinter窗口背景/ Canvas 不改变颜色

python - Django 以 10 为基数的 int() 的文字无效 get_prep_value

python - 正则表达式返回匹配和扩展匹配

python - 如何在 python couchdb 中过滤更改

python-3.x - 如何在 Ubuntu 16.04 上使用带有 Python 3.7 的 sqlite3 python 模块的 FTS5 扩展?