Как фильтровать таблицу SQLite3 в PyQt5

Питер Торбенн

Я пытаюсь создать панель поиска для фильтрации данных в таблице, но похоже, что модель не связана со строкой Изменить таблицу работает, но я не могу фильтровать данные базы данных с ее помощью (она работает со списками) что не так ?

class Ui_MainWindow(object):
    def setupUi(self, MainWindow):
        mainLayout = QVBoxLayout()
        conn = sqlite3.connect("banco_cadastro.db.db")
        cursor = conn.cursor()
        list = (cursor.fetchall())
        model = QStandardItemModel(len(list), 5)
        model.setHorizontalHeaderLabels(['Clients'])
        for row, company in enumerate(list):
            item = QStandardItem(company)
            model.setItem(row, 0, item)
        filter_proxy_model = QSortFilterProxyModel()
        filter_proxy_model.setSourceModel(model)
        filter_proxy_model.setFilterCaseSensitivity(Qt.CaseInsensitive)
        filter_proxy_model.setFilterKeyColumn(0)
        MainWindow.setObjectName("MainWindow")
        MainWindow.resize(779, 693)
        self.centralwidget = QtWidgets.QWidget(MainWindow)
        self.centralwidget.setObjectName("centralwidget")
        self.lineEdit = QtWidgets.QLineEdit(self.centralwidget)
        self.lineEdit.textChanged.connect(filter_proxy_model.setFilterRegExp)
        mainLayout.addWidget(self.lineEdit)
        self.tableWidget = QtWidgets.QTableWidget(self.centralwidget)
        self.tableWidget.setObjectName("tableWidget")
        MainWindow.setCentralWidget(self.centralwidget)
        connection = sqlite3.connect('banco_cadastro.db')
        query = "SELECT * FROM cadastro"
        result = connection.execute(query)
        list = (cursor.fetchall())

        for row_number, row_data in enumerate(result):
            self.tableWidget.insertRow(row_number)

            for column_number, data in enumerate(row_data):
                self.tableWidget.setItem(row_number, column_number, QtWidgets.QTableWidgetItem(str(data)))

        connection.close()

    def retranslateUi(self, MainWindow):
        _translate = QtCore.QCoreApplication.translate
        MainWindow.setWindowTitle(_translate("MainWindow", "MainWindow"))

if __name__ == "__main__":
    import sys

    app = QtWidgets.QApplication(sys.argv)
    MainWindow = QtWidgets.QMainWindow()
    ui = Ui_MainWindow()
    ui.setupUi(MainWindow)
    MainWindow.show()
    sys.exit(app.exec_())
Eyllanesc

Отказ от ответственности: в этом посте я собираюсь сосредоточиться только на фоновой цели, а не на ошибках OP (например, объединение QStandardItemModel с QTableWidget или бесполезная попытка использовать QSortFilterProxyModel, который ни к чему не подключается).

Я собираюсь воспользоваться возможностью, чтобы показать различные способы фильтрации таблиц sqlite (те же концепции могут быть применены к другим базам данных) с использованием PyQt5 (это также относится к PySide2).

- Модуль QTableWidget + sqlite3

Возможное решение - перебрать строки и убедиться, что оно соответствует желаемому условию, если оно выполняется, то строка будет видимой, а в противном случае строка будет скрыта.

import sqlite3

from PyQt5 import QtCore, QtWidgets


class Widget(QtWidgets.QWidget):
    def __init__(self, parent=None):
        super().__init__(parent)

        self.edit = QtWidgets.QLineEdit()
        self.combo = QtWidgets.QComboBox()
        self.table = QtWidgets.QTableWidget()

        grid = QtWidgets.QGridLayout(self)
        grid.addWidget(self.edit, 0, 0)
        grid.addWidget(self.combo, 0, 1)
        grid.addWidget(self.table, 1, 0, 1, 2)

        self.connection = sqlite3.connect("database.db")

        self.populate_table("SELECT * FROM foo_table")
        self.edit.textChanged.connect(self.filter_table)

    def populate_table(self, query, values=None):
        cursor = self.connection.cursor()
        if values is None:
            cursor.execute(query)
        else:
            cursor.execute(query, values)

        name_of_columns = [e[0] for e in cursor.description]
        self.table.setColumnCount(len(name_of_columns))
        self.table.setRowCount(0)
        self.table.setHorizontalHeaderLabels(name_of_columns)
        self.combo.clear()
        self.combo.addItems(name_of_columns)

        for i, row_data in enumerate(cursor.fetchall()):
            self.table.insertRow(self.table.rowCount())
            for j, value in enumerate(row_data):
                item = QtWidgets.QTableWidgetItem()
                item.setData(QtCore.Qt.DisplayRole, value)
                self.table.setItem(i, j, item)

    def filter_table(self, text):
        if text:
            filter_column = self.combo.currentIndex()

            for i in range(self.table.rowCount()):
                item = self.table.item(i, filter_column)
                if self.filter_row(item, text):
                    self.table.showRow(i)
                else:
                    self.table.hideRow(i)
        else:
            for i in range(self.table.rowCount()):
                self.table.showRow(i)

    def filter_row(self, item, text):
        return text in item.text()


def main():
    import sys

    app = QtWidgets.QApplication(sys.argv)
    ex = Widget()
    ex.show()
    sys.exit(app.exec_())


if __name__ == "__main__":
    main()

Другое возможное решение - удалить все данные и сделать новый запрос с фильтром.

import sqlite3

from PyQt5 import QtCore, QtWidgets


class Widget(QtWidgets.QWidget):
    def __init__(self, parent=None):
        super().__init__(parent)

        self.edit = QtWidgets.QLineEdit()
        self.combo = QtWidgets.QComboBox()
        self.table = QtWidgets.QTableWidget()

        grid = QtWidgets.QGridLayout(self)
        grid.addWidget(self.edit, 0, 0)
        grid.addWidget(self.combo, 0, 1)
        grid.addWidget(self.table, 1, 0, 1, 2)

        self.connection = sqlite3.connect("database.db")

        self.populate_table("SELECT * FROM foo_table")
        self.edit.textChanged.connect(self.filter_table)

    def populate_table(self, query, values=None):
        cursor = self.connection.cursor()
        if values is None:
            cursor.execute(query)
        else:
            cursor.execute(query, values)

        name_of_columns = [e[0] for e in cursor.description]
        self.table.setColumnCount(len(name_of_columns))
        self.table.setRowCount(0)
        self.table.setHorizontalHeaderLabels(name_of_columns)
        self.combo.clear()
        self.combo.addItems(name_of_columns)

        for i, row_data in enumerate(cursor.fetchall()):
            self.table.insertRow(self.table.rowCount())
            for j, value in enumerate(row_data):
                item = QtWidgets.QTableWidgetItem()
                item.setData(QtCore.Qt.DisplayRole, value)
                self.table.setItem(i, j, item)

    def filter_table(self, text):
        if text:
            self.populate_table(
                "SELECT * FROM foo_table WHERE {} LIKE ?".format(
                    self.combo.currentText()
                ),
                ["%{}%".format(text)],
            )
        else:
            self.populate_table("SELECT * FROM foo_table")


def main():
    import sys

    app = QtWidgets.QApplication(sys.argv)
    ex = Widget()
    ex.show()
    sys.exit(app.exec_())


if __name__ == "__main__":
    main()

- Модуль QTableView + QStandardItemModel + sqlite3

Та же логика, что и выше:

import sqlite3

from PyQt5 import QtCore, QtGui, QtWidgets


class Widget(QtWidgets.QWidget):
    def __init__(self, parent=None):
        super().__init__(parent)

        self.edit = QtWidgets.QLineEdit()
        self.combo = QtWidgets.QComboBox()
        self.table = QtWidgets.QTableView()
        self.model = QtGui.QStandardItemModel()
        self.table.setModel(self.model)

        grid = QtWidgets.QGridLayout(self)
        grid.addWidget(self.edit, 0, 0)
        grid.addWidget(self.combo, 0, 1)
        grid.addWidget(self.table, 1, 0, 1, 2)

        self.connection = sqlite3.connect("database.db")

        self.populate_table("SELECT * FROM foo_table")
        self.edit.textChanged.connect(self.filter_table)

    def populate_table(self, query):
        cursor = self.connection.cursor()
        cursor.execute(query)

        name_of_columns = [e[0] for e in cursor.description]
        self.model.setColumnCount(len(name_of_columns))
        self.model.setRowCount(0)
        self.model.setHorizontalHeaderLabels(name_of_columns)
        self.combo.clear()
        self.combo.addItems(name_of_columns)

        for i, row_data in enumerate(cursor.fetchall()):
            self.model.insertRow(self.model.rowCount())
            for j, value in enumerate(row_data):
                item = QtGui.QStandardItem()
                item.setData(value, QtCore.Qt.DisplayRole)
                self.model.setItem(i, j, item)

    def filter_table(self, text):
        if text:
            filter_column = self.combo.currentIndex()

            for i in range(self.model.rowCount()):
                item = self.model.item(i, filter_column)
                if self.filter_row(item, text):
                    self.table.showRow(i)
                else:
                    self.table.hideRow(i)
        else:
            for i in range(self.model.rowCount()):
                self.table.showRow(i)

    def filter_row(self, item, text):
        return text in item.text()


def main():
    import sys

    app = QtWidgets.QApplication(sys.argv)
    ex = Widget()
    ex.show()
    sys.exit(app.exec_())


if __name__ == "__main__":
    main()
import sqlite3

from PyQt5 import QtCore, QtGui, QtWidgets


class Widget(QtWidgets.QWidget):
    def __init__(self, parent=None):
        super().__init__(parent)

        self.edit = QtWidgets.QLineEdit()
        self.combo = QtWidgets.QComboBox()
        self.table = QtWidgets.QTableView()
        self.model = QtGui.QStandardItemModel()
        self.table.setModel(self.model)

        grid = QtWidgets.QGridLayout(self)
        grid.addWidget(self.edit, 0, 0)
        grid.addWidget(self.combo, 0, 1)
        grid.addWidget(self.table, 1, 0, 1, 2)

        self.connection = sqlite3.connect("database.db")

        self.populate_table("SELECT * FROM foo_table")
        self.edit.textChanged.connect(self.filter_table)

    def populate_table(self, query, values=None):
        cursor = self.connection.cursor()
        if values is None:
            cursor.execute(query)
        else:
            cursor.execute(query, values)

        name_of_columns = [e[0] for e in cursor.description]
        self.model.setColumnCount(len(name_of_columns))
        self.model.setRowCount(0)
        self.model.setHorizontalHeaderLabels(name_of_columns)
        self.combo.clear()
        self.combo.addItems(name_of_columns)

        for i, row_data in enumerate(cursor.fetchall()):
            self.model.insertRow(self.model.rowCount())
            for j, value in enumerate(row_data):
                item = QtGui.QStandardItem()
                item.setData(value, QtCore.Qt.DisplayRole)
                self.model.setItem(i, j, item)

    def filter_table(self, text):
        if text:
            self.populate_table(
                "SELECT * FROM foo_table WHERE {} LIKE ?".format(
                    self.combo.currentText()
                ),
                ["%{}%".format(text)],
            )
        else:
            self.populate_table("SELECT * FROM foo_table")


def main():
    import sys

    app = QtWidgets.QApplication(sys.argv)
    ex = Widget()
    ex.show()
    sys.exit(app.exec_())


if __name__ == "__main__":
    main()

Также есть возможность использовать QSortFilterProxyModel:

import sqlite3

from PyQt5 import QtCore, QtGui, QtWidgets


class Widget(QtWidgets.QWidget):
    def __init__(self, parent=None):
        super().__init__(parent)

        self.edit = QtWidgets.QLineEdit()
        self.combo = QtWidgets.QComboBox()
        self.table = QtWidgets.QTableView()
        self.model = QtGui.QStandardItemModel()

        self.proxy = QtCore.QSortFilterProxyModel()
        self.proxy.setSourceModel(self.model)
        self.proxy.setFilterCaseSensitivity(QtCore.Qt.CaseInsensitive)
        self.table.setModel(self.proxy)

        grid = QtWidgets.QGridLayout(self)
        grid.addWidget(self.edit, 0, 0)
        grid.addWidget(self.combo, 0, 1)
        grid.addWidget(self.table, 1, 0, 1, 2)

        self.connection = sqlite3.connect("database.db")

        self.populate_table("SELECT * FROM foo_table")
        self.combo.currentIndexChanged.connect(self.proxy.setFilterKeyColumn)
        self.edit.textChanged.connect(self.proxy.setFilterRegExp)

    def populate_table(self, query, values=None):
        cursor = self.connection.cursor()
        if values is None:
            cursor.execute(query)
        else:
            cursor.execute(query, values)

        name_of_columns = [e[0] for e in cursor.description]
        self.model.setColumnCount(len(name_of_columns))
        self.model.setRowCount(0)
        self.model.setHorizontalHeaderLabels(name_of_columns)
        self.combo.clear()
        self.combo.addItems(name_of_columns)

        for i, row_data in enumerate(cursor.fetchall()):
            self.model.insertRow(self.model.rowCount())
            for j, value in enumerate(row_data):
                item = QtGui.QStandardItem()
                item.setData(value, QtCore.Qt.DisplayRole)
                self.model.setItem(i, j, item)


def main():
    import sys

    app = QtWidgets.QApplication(sys.argv)
    ex = Widget()
    ex.show()
    sys.exit(app.exec_())


if __name__ == "__main__":
    main()

- QTableView + QSqlQueryModel

В этом случае лучший вариант - сделать фильтр с помощью sql, меняя запрос:

from PyQt5 import QtCore, QtGui, QtWidgets, QtSql


class Widget(QtWidgets.QWidget):
    def __init__(self, parent=None):
        super().__init__(parent)

        self.edit = QtWidgets.QLineEdit()
        self.combo = QtWidgets.QComboBox()
        self.table = QtWidgets.QTableView()
        self.model = QtSql.QSqlQueryModel()
        self.table.setModel(self.model)

        grid = QtWidgets.QGridLayout(self)
        grid.addWidget(self.edit, 0, 0)
        grid.addWidget(self.combo, 0, 1)
        grid.addWidget(self.table, 1, 0, 1, 2)

        self.populate_table("SELECT * FROM foo_table")
        self.edit.textChanged.connect(self.filter_table)

    def populate_table(self, query, values=None):
        q = QtSql.QSqlQuery(query)
        if values is not None:
            for value in values:
                q.addBindValue(value)
                print(value)
        if not q.exec_():
            print(q.lastError().text())
        self.model.setQuery(q)
        self.combo.clear()
        for i in range(self.model.columnCount()):
            self.combo.addItem(self.model.headerData(i, QtCore.Qt.Horizontal))

    def filter_table(self, text):
        if text:
            self.populate_table(
                "SELECT * FROM foo_table WHERE {} LIKE ?".format(
                    self.combo.currentText()
                ),
                ["%{}%".format(text)],
            )
        else:
            self.populate_table("SELECT * FROM foo_table")


def main():
    import sys

    app = QtWidgets.QApplication(sys.argv)

    db = QtSql.QSqlDatabase.addDatabase("QSQLITE")
    db.setDatabaseName("database.db")
    if not db.open():
        sys.exit(-1)

    ex = Widget()
    ex.show()
    sys.exit(app.exec_())


if __name__ == "__main__":
    main()

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

- QTableView + QSqlTableModel

В этом случае следует использовать метод setFilter:

from PyQt5 import QtCore, QtGui, QtWidgets, QtSql


class Widget(QtWidgets.QWidget):
    def __init__(self, parent=None):
        super().__init__(parent)

        self.edit = QtWidgets.QLineEdit()
        self.combo = QtWidgets.QComboBox()
        self.table = QtWidgets.QTableView()
        self.model = QtSql.QSqlTableModel()
        self.table.setModel(self.model)

        grid = QtWidgets.QGridLayout(self)
        grid.addWidget(self.edit, 0, 0)
        grid.addWidget(self.combo, 0, 1)
        grid.addWidget(self.table, 1, 0, 1, 2)

        self.model.setTable("foo_table")
        self.model.select()

        self.combo.clear()
        for i in range(self.model.columnCount()):
            self.combo.addItem(self.model.headerData(i, QtCore.Qt.Horizontal))

        self.edit.textChanged.connect(self.filter_table)

    def filter_table(self, text):
        f = " {} LIKE '%{}%'".format(self.combo.currentText(), text) if text else text
        self.model.setFilter(f)
        self.model.select()


def main():
    import sys

    app = QtWidgets.QApplication(sys.argv)

    db = QtSql.QSqlDatabase.addDatabase("QSQLITE")
    db.setDatabaseName("database.db")
    if not db.open():
        sys.exit(-1)

    ex = Widget()
    ex.show()
    sys.exit(app.exec_())


if __name__ == "__main__":
    main()

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

Эта статья взята из Интернета, укажите источник при перепечатке.

Если есть какие-либо нарушения, пожалуйста, свяжитесь с[email protected] Удалить.

Отредактировано в
0

я говорю два предложения

0обзор
Войти в системуУчаствуйте в комментариях

Статьи по теме

Как получить информацию от диалога сзади в TreeView pyqt5 питон 3

Правильно установите sqlite3 с поддержкой FTS5

How to install PyQt5 in Python 3 (Ubuntu 14.04)

Как установить PyQt5 в Python 3 (Ubuntu 14.04)

PyQt5 + Python 3: передача списков, диктовок в качестве аргументов сигналов по потокам

PyQt5 поддерживает Qt3D?

python и sqlite3, проверьте, могу ли я использовать расширение fts5?

Последние версии Python 3 и PyQt5 работают в 32-битной Windows XP.

pyqt5 зацикленный mp3 файл

Python3 PyQt5 setEnabled из QAction, вызывающего сбои

Содержимое 3D-окно в PyQt5

Как изменить поведение клавиши пробела в PyQt5, Python3

Автоматическое изменение индекса Stacked Widget через 3 секунды в PyQt5

Включить sqlite3 FTS5 для PHP

Как показать данные из sqlite3 с помощью electronic5 и angular8

Вставьте изображение blob в QPixMap из sqlite db в QTextBrowser в PyQt5

Rails 5, sqlite3 с использованием массива как столбца / атрибута

Python 3 PyQt5 QtPrintSupport Quick Print (без отображения диалога)

PyQt5: загрузка расширения в sqlite

Метод keyPressEvent () не работает для PyQt5 / Python 3+

Rails 5 и MongoDB: указан sqlite3 для адаптера базы данных, но гем не загружен

генератор лямбда uuid для модели id в rails5 с sqlite3

как добавить pyplot matplotlib 3d в конструктор python qt или pyqt5

Команды Python3 Numpy не работают с PyQt5 LineEdit

Переменная с плавающей запятой Python3 PyQT5 для LineEdit

sqlite3: предоставлено неверное количество привязок. В текущем операторе используется 1, а предоставлено 5

Как правильно передать целочисленную переменную из одной функции в другую в Python3 и PyQt5?

В чем разница между pip install pyqt5 и sudo apt-get install python3-pyqt5? [здесь сам pyQt5 - это скорее заполнитель, чем что-либо еще]

SQLITE and PYQT5 stopping to respond on sql execution

TOP список

  1. 1

    Распределение Рэлея Curve_fit на Python

  2. 2

    How to click an array of links in puppeteer?

  3. 3

    В типе Observable <unknown> отсутствуют следующие свойства из типа Promise <any>.

  4. 4

    Как добавить Swagger в веб-API с поддержкой OData, работающий на ASP.NET Core 3.1

  5. 5

    Нарисуйте диаграмму с помощью highchart.js

  6. 6

    无法通过Vue在传单中加载pixiOverlay

  7. 7

    Отчеты Fabric Debug Craslytic: регистрация, отсутствует идентификатор сборки, применить плагин: io.fabric

  8. 8

    Статус HTTP 403 - ожидаемый токен CSRF не найден

  9. 9

    TypeError: store.getState não é uma função. (Em 'store.getState ()', 'store.getState' é indefinido, como posso resolver esse problema?

  10. 10

    ContentDialog.showAsync в универсальном оконном приложении Win 10

  11. 11

    В UICollectionView порядок меняется автоматически

  12. 12

    Merging legends in plotly subplot

  13. 13

    Elasticsearch - Нечеткий поиск не дает предложения

  14. 14

    Bogue étrange datetime.utcnow()

  15. 15

    Объединение таблиц в листе Google - полное соединение

  16. 16

    Single legend for Plotly subplot for line plots created from two data frames in R

  17. 17

    как я могу удалить vue cli 2?

  18. 18

    ViewPager2 мигает / перезагружается при смахивании

  19. 19

    Компилятор не знает о предоставленных методах Trait

  20. 20

    JDBI - В чем разница между @define и @bind в JDBI?

  21. 21

    проблемы с AVG и LIMIT SQL

популярныйтег

файл