Как использовать qsortfilterproxymodel в базе данных?

У меня есть QTableWidget с данными из базы данных, и я хочу искать его содержимое в режиме реального времени (когда я набираю письмо, он показывает мне результаты)? Любая помощь приветствуется. Большое спасибо.

Это мой код:

class Filter:
    def __init__(self):
        object.__init__(self)
        self.db = QtSql.QSqlDatabase.addDatabase('QSQLITE')
        self.db.setDatabaseName("baza.db")
        self.filter_model= QSortFilterProxyModel()



    def sqlPodaci(self,okvir):
        okvir.setObjectName("Okvir aplikacije")
        okvir.resize(700,320)
        line_edit = QLineEdit(okvir)
        line_edit.setGeometry(20, 20, 205, 23)
        self.tableWidget = QtWidgets.QTableWidget(okvir)
        self.tableWidget.setGeometry(QtCore.QRect(20, 50, 620, 201))
        self.tableWidget.setAlternatingRowColors(True)
        self.tableWidget.setRowCount(3)
        self.tableWidget.horizontalHeader().setVisible(True)
        self.tableWidget.verticalHeader().setVisible(False)

        ###
        self.filter_model.setFilterKeyColumn(1)
        line_edit.textChanged.connect(self.filter_model.setFilterRegExp)
        ####
        self.Ucitavanje_podataka()

Это код для чтения данных из базы данных:

def Ucitavanje_podataka(self):

status = self.db.open()
if status == False:
    QtWidgets.QMessageBox.warning(self, "Error", self.db.lastError().text(), QtWidgets.QMessageBox.Discard)
else:
    self.tableWidget.setColumnCount(6)
    self.tableWidget.setHorizontalHeaderLabels(['Id','Ime','Prezime','Godine','Adresa','Plata'])

    row = 0
    sql = " SELECT * FROM Zaposleni"
    query = QtSql.QSqlQuery(sql)
    while query.next():
        self.tableWidget.insertRow(row)
        ID=QtWidgets.QTableWidgetItem(str(query.value(0)))
        Ime = QtWidgets.QTableWidgetItem(str(query.value(1)))
        Prezime = QtWidgets.QTableWidgetItem(str(query.value(2)))
        Godine = QtWidgets.QTableWidgetItem(str(query.value(3)))
        Adresa = QtWidgets.QTableWidgetItem(str(query.value(4)))
        Plata = QtWidgets.QTableWidgetItem(str(query.value(5)))

        self.tableWidget.setItem(row,0,ID)
        self.tableWidget.setItem(row, 1, Ime)
        self.tableWidget.setItem(row, 2, Prezime)
        self.tableWidget.setItem(row, 3, Godine)
        self.tableWidget.setItem(row, 4, Adresa)
        self.tableWidget.setItem(row, 5, Plata)
        row=row+1

если вы хотите использовать QSortFilterProxyModel, вы должны использовать QTableView, QTableWidget, чтобы облегчить его использование, имеет модель только для чтения, поэтому его нельзя будет использовать для QSortFilterProxyModel. Если вы дадите более подробную информацию о том, как вы хотите сделать фильтр, я могу дать вам решение.

eyllanesc 10.08.2018 15:09

Спасибо. Когда я заполняю таблицу данными, я хочу фильтровать результаты по столбцам. Например, в столбце 2 есть три имени eyllanesc, elena и Maximus, когда я набираю 'M'into line_edit, я вижу только Maximus, если я набираю' E ', я получаю eyllanesc, elena ...

Maximus 10.08.2018 15:25

и если бы слова были: «AB», «BA», «CA», «CB» и тип A, что должно быть показано?

eyllanesc 10.08.2018 15:27

вы хотите, чтобы он фильтровался только по началу слова

eyllanesc 10.08.2018 15:28

да, только если я наберу буквы в точном порядке. Пример: M - Maximus, Ma - Maksimus, Mx - не покажет попадание

Maximus 10.08.2018 15:32

если вам будет проще вывести все слова, содержащие заданные буквы ... Мне тоже будет хорошо

Maximus 10.08.2018 15:37

Спасибо большое. Ты такой умный. Еще раз спасибо

Maximus 11.08.2018 14:37

Можно ли использовать это для двух или более столбцов? Я пробовал но ... :(

Maximus 13.08.2018 08:36

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

eyllanesc 13.08.2018 13:23

Я знаю то же самое, но не знаю, как реализовать в вашем коде. Извините, что беспокою ... Когда у вас будет время, пожалуйста, напишите мне. Спасибо

Maximus 13.08.2018 14:11

Ваш вопрос очень общий, объясните себя, приведите мне примеры того, что вы хотите получить.

eyllanesc 13.08.2018 14:12

в этом скрипте я хочу фильтровать результаты в трех разных столбцах. self.proxy.setFilterKeyColumn (1) в этом коде я ищу один столбец (второй в моем случае), но мне нужно три столбца для поиска, еще два. Извините и спасибо

Maximus 14.08.2018 07:15
3
12
952
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

QTableWidget имеет предустановленную модель, которую нельзя заменить, поэтому использование QSortFilterProxyModel было бы невозможным, поэтому вам следует использовать QTableView, возможное решение вашей основной проблемы, связанной с фильтрацией, заключается в использовании только QSqlQueryModel и создании фильтра с помощью команды LIKE.

from PyQt5 import QtWidgets, QtSql

def createConnection():
    db = QtSql.QSqlDatabase.addDatabase("QSQLITE")
    db.setDatabaseName("baza.db")
    if not db.open():
        QtWidgets.QMessageBox.critical(None, "Cannot open database",
                    "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
    return True

class Widget(QtWidgets.QWidget):
    def __init__(self, parent=None):
        super(Widget, self).__init__(parent)
        lay = QtWidgets.QVBoxLayout(self)
        lineEdit = QtWidgets.QLineEdit()
        tableView = QtWidgets.QTableView()
        lay.addWidget(lineEdit)
        lay.addWidget(tableView)
        lineEdit.textChanged.connect(self.onTextChanged)

        self.model = QtSql.QSqlQueryModel()
        tableView.setModel(self.model)
        self.onTextChanged("")

    def onTextChanged(self, text):
        query = QtSql.QSqlQuery()
        query.prepare("SELECT * FROM Zaposleni WHERE Ime LIKE ?")
        query.addBindValue("{}%".format(text))
        query.exec_()
        self.model.setQuery(query)


if __name__ == '__main__':
    import sys

    app = QtWidgets.QApplication(sys.argv)
    if not createConnection():
        sys.exit(-1)
    w = Widget()
    w.show()
    sys.exit(app.exec_())

В предыдущем примере мы хотим, чтобы слово начиналось с текста QLineEdit, если вы хотите узнать, содержит ли оно слово, которое вы должны заменить на:

query.addBindValue("%{}%".format(text))

Если вы все еще хотите использовать QSortFilterProxyModel, вы можете увидеть следующий пример:

from PyQt5 import QtCore, QtWidgets, QtSql

def createConnection():
    db = QtSql.QSqlDatabase.addDatabase("QSQLITE")
    db.setDatabaseName("baza.db")
    if not db.open():
        QtWidgets.QMessageBox.critical(None, "Cannot open database",
                    "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
    return True

class Widget(QtWidgets.QWidget):
    def __init__(self, parent=None):
        super(Widget, self).__init__(parent)
        lay = QtWidgets.QVBoxLayout(self)
        lineEdit = QtWidgets.QLineEdit()
        tableView = QtWidgets.QTableView()
        lay.addWidget(lineEdit)
        lay.addWidget(tableView)
        lineEdit.textChanged.connect(self.onTextChanged)

        self.model = QtSql.QSqlQueryModel()
        self.model.setQuery("SELECT * FROM Zaposleni")

        self.proxy = QtCore.QSortFilterProxyModel()
        self.proxy.setSourceModel(self.model)
        self.proxy.setFilterKeyColumn(1)

        tableView.setModel(self.proxy)

    def onTextChanged(self, text):
        regex = "^{}".format(text)
        self.proxy.setFilterRegExp(QtCore.QRegExp(regex, QtCore.Qt.CaseInsensitive))


if __name__ == '__main__':
    import sys

    app = QtWidgets.QApplication(sys.argv)
    if not createConnection():
        sys.exit(-1)
    w = Widget()
    w.show()
    sys.exit(app.exec_())

В предыдущем примере мы хотим, чтобы слово начиналось с текста QLineEdit, если вы хотите узнать, содержит ли оно слово, которое вы должны заменить на:

regex = "[{}]".format(text) if text else ""

в этом скрипте я хочу фильтровать результаты в трех разных столбцах. self.proxy.setFilterKeyColumn (1) в этом коде я ищу один столбец (второй в моем случае), но мне нужно три столбца для поиска. Извините и спасибо

Maximus 13.08.2018 14:39

Не могли бы вы мне помочь?

Maximus 14.08.2018 15:23

@Maximus Если вы знаете SQL, используйте первую опцию, поскольку она предназначена только для создания запроса, который позволяет выбор. Во втором случае он включает в себя создание класса, унаследованного от QSortFilterProxyModel, и перезапись нескольких методов и создание других. Попробуйте, и если вы не можете решить эту проблему, создайте новый вопрос, показывающий вашу попытку решения, и, безусловно, кто-то из сообщества может вам помочь.

eyllanesc 14.08.2018 15:27

Другие вопросы по теме