我有一个问题,实际上有很多问题,但是我希望您可以帮助我解决这个问题:)
我正在尝试从数据库中过滤列,但我成功地在一个列中进行了过滤,但是如果第一个= 0的结果转到另一个,则我需要同时过滤三个列,如果第二个列的result = 0转到了第三栏...
这是我尝试过的代码: 脚本显示来自数据库的数据,但不过滤结果。我哪里错了?
代码:
from PyQt5 import QtWidgets,QtSql,QtGui,QtCore
from PyQt5.QtCore import *
def createConnection():
db = QtSql.QSqlDatabase.addDatabase("QSQLITE")
db.setDatabaseName("imenik.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 MySortFilterProxyModel(QSortFilterProxyModel):
def __init__(self, parent=None):
super(MySortFilterProxyModel, self).__init__(parent)
def filterAcceptsRow(self, sourceRow, sourceParent):
index0 = self.sourceModel().index(sourceRow, 0, sourceParent)
index1 = self.sourceModel().index(sourceRow, 1, sourceParent)
index2 = self.sourceModel().index(sourceRow, 2, sourceParent)
return ((self.filterRegExp().indexIn(self.sourceModel().data(index0)) >= 0
or self.filterRegExp().indexIn(self.sourceModel().data(index1)) >= 0
or self.filterRegExp().indexIn(self.sourceModel().data(index2)) >= 0))
class Klasa(QtWidgets.QWidget):
def __init__(self, parent=None):
super(Klasa, self).__init__(parent)
#podesavanje velicine okvira ujedno i velicine treevjuva jer se tri vjuv razvlaci do ivica Boksa
self.proxyModel = MySortFilterProxyModel(self)
self.verLW = QtWidgets.QWidget(self)
self.verLW.setGeometry(QtCore.QRect(60,120,1000,490))
#dodjeljuje tri vjuv prethodno definisanom okviru
lay = QtWidgets.QVBoxLayout(self.verLW)
#kreira liniju za unos teksta za pretragu
self.lineEdit = QtWidgets.QLineEdit(self)
self.lineEdit.setGeometry(QtCore.QRect(70, 100, 351, 20))
self.lineEdit.textChanged.connect(self.textFilterChanged)
self.tableView = QtWidgets.QTableView()
#dodjeljuje okviru self.tableView
lay.addWidget(self.tableView)
#pravi promjenjivu za pretragu baze podataka
self.model = QtSql.QSqlQueryModel()
self.model.setQuery("SELECT Lokacija,Kancelarija,Prezime,Ime,Telefon,Lokal,Fax,Oblast FROM telImenik")
#upisuje rezultate pretrage baze u self.tableView
self.tableView.setModel(self.model)
#odredjuje sirinu kolona u self.tableView-u prva kolona je 0-nulta,id nema potrebe dodavati jer ga sam odredjuje
self.tableView.setColumnWidth(0, 150)
self.tableView.setColumnWidth(1, 65)
self.tableView.setColumnWidth(2, 100)
self.tableView.setColumnWidth(3, 80)
self.tableView.setColumnWidth(4, 80)
self.tableView.setColumnWidth(5, 40)
self.tableView.setColumnWidth(6, 80)
self.tableView.setColumnWidth(7, 340)
def setSourceModel(self):
self.proxyModel.setSourceModel(self.model)
self.tableView.setModel(self.proxyModel)
def textFilterChanged(self,text):
regExp = QRegExp(self.lineEdit.text())
self.proxyModel.setFilterRegExp(regExp)
if __name__ == '__main__':
import sys
app = QtWidgets.QApplication(sys.argv)
if not createConnection():
sys.exit(-1)
w = Klasa()
w.show()
sys.exit(app.exec_())
答案 0 :(得分:1)
问题很简单:您从未使用过代理,因此永远也不会进行过滤,在下一部分中,我向您展示了一种更为优雅的解决方案:
from PyQt5 import QtCore, QtGui, QtWidgets, QtSql
def createConnection():
db = QtSql.QSqlDatabase.addDatabase("QSQLITE")
db.setDatabaseName("imenik.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 MySortFilterProxyModel(QtCore.QSortFilterProxyModel):
def filterAcceptsRow(self, sourceRow, sourceParent):
ixs = [self.sourceModel().index(sourceRow, i, sourceParent) for i in range(3)]
return any(self.filterRegExp().indexIn(ix.data()) >= 0 for ix in ixs)
class Klasa(QtWidgets.QWidget):
def __init__(self, parent=None):
super(Klasa, self).__init__(parent)
#podesavanje velicine okvira ujedno i velicine treevjuva jer se tri vjuv razvlaci do ivica Boksa
self.proxyModel = MySortFilterProxyModel(self)
#dodjeljuje tri vjuv prethodno definisanom okviru
lay = QtWidgets.QVBoxLayout(self)
#kreira liniju za unos teksta za pretragu
self.lineEdit = QtWidgets.QLineEdit()
self.lineEdit.textChanged.connect(self.textFilterChanged)
self.tableView = QtWidgets.QTableView()
#dodjeljuje okviru self.tableView
lay.addWidget(self.lineEdit)
lay.addWidget(self.tableView)
#pravi promjenjivu za pretragu baze podataka
self.model = QtSql.QSqlQueryModel()
self.model.setQuery("SELECT Lokacija,Kancelarija,Prezime,Ime,Telefon,Lokal,Fax,Oblast FROM telImenik")
#upisuje rezultate pretrage baze u self.tableView
self.proxyModel.setSourceModel(self.model)
self.tableView.setModel(self.proxyModel)
#odredjuje sirinu kolona u self.tableView-u prva kolona je 0-nulta,id nema potrebe dodavati jer ga sam odredjuje
for i, width in enumerate([150, 65, 100, 80, 90, 40, 80, 340]):
self.tableView.setColumnWidth(i, width)
def setSourceModel(self):
self.proxyModel.setSourceModel(self.model)
self.tableView.setModel(self.proxyModel)
def textFilterChanged(self,text):
regExp = QtCore.QRegExp(self.lineEdit.text(), QtCore.Qt.CaseInsensitive)
self.proxyModel.setFilterRegExp(regExp)
if __name__ == '__main__':
import sys
app = QtWidgets.QApplication(sys.argv)
if not createConnection():
sys.exit(-1)
w = Klasa()
w.show()
sys.exit(app.exec_())
或者就像我说的,最简单的方法是使用WHERE
和LIKE
进行SQL过滤:
from PyQt5 import QtCore, QtGui, QtWidgets, QtSql
def createConnection():
db = QtSql.QSqlDatabase.addDatabase("QSQLITE")
db.setDatabaseName("imenik.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 Klasa(QtWidgets.QWidget):
def __init__(self, parent=None):
super(Klasa, self).__init__(parent)
#podesavanje velicine okvira ujedno i velicine treevjuva jer se tri vjuv razvlaci do ivica Boksa
#dodjeljuje tri vjuv prethodno definisanom okviru
lay = QtWidgets.QVBoxLayout(self)
#kreira liniju za unos teksta za pretragu
self.lineEdit = QtWidgets.QLineEdit()
self.lineEdit.textChanged.connect(self.textFilterChanged)
self.tableView = QtWidgets.QTableView()
#dodjeljuje okviru self.tableView
lay.addWidget(self.lineEdit)
lay.addWidget(self.tableView)
#pravi promjenjivu za pretragu baze podataka
self.model = QtSql.QSqlQueryModel()
#upisuje rezultate pretrage baze u self.tableView
self.tableView.setModel(self.model)
#odredjuje sirinu kolona u self.tableView-u prva kolona je 0-nulta,id nema potrebe dodavati jer ga sam odredjuje
for i, width in enumerate([150, 65, 100, 80, 90, 40, 80, 340]):
self.tableView.setColumnWidth(i, width)
self.textFilterChanged("")
def setSourceModel(self):
self.proxyModel.setSourceModel(self.model)
self.tableView.setModel(self.proxyModel)
def textFilterChanged(self,text):
query = QtSql.QSqlQuery()
query.prepare("SELECT * FROM telImenik WHERE Lokacija LIKE ? OR Kancelarija LIKE ? OR Prezime LIKE ?")
query.addBindValue("{}%".format(text))
query.addBindValue("{}%".format(text))
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 = Klasa()
w.show()
sys.exit(app.exec_())