Python Forum
[PyQt] [Solved]Display Search Results in QTable
Thread Rating:
  • 0 Vote(s) - 0 Average
  • 1
  • 2
  • 3
  • 4
  • 5
[PyQt] [Solved]Display Search Results in QTable
#1
Hello,

I'm trying to get my search bar working on my GUI, so when the user searches for a part, the results are shown to the screen.

Right now I have the whole inventory being displayed on startup, but I can't get it to disappear and show the search results when the user searches for something.

Right now I have an SQL statement that fetches my results and prints them to the terminal:
#----------------------------------
    #Search Function
    def SearchClicked(self):
        #Print in terminal for testing:
        print("The Search Button was clicked")
        
        userQuery = self.SearchBar.text()
        #Connect to the inventory database (inventory.db)
        connection = sqlite3.connect(MainDatabase)
        cursor = connection.cursor()
        cursor.execute("SELECT * FROM items WHERE Name LIKE'%'||?||'%'",(userQuery,))
        connection.commit()
        #Get all info from the Items Table
        result = cursor.fetchall()
        print(result)
        #Close the connection to the database
        connection.close()
#----------------------------------
So, how do I get those results to display on the table?

Thanks in advance.



Full code:
#!/usr/bin/env python3
import sys
from PyQt5 import QtWidgets
from PyQt5.QtSql import QSqlDatabase, QSqlTableModel
from PyQt5.QtWidgets import (QApplication, QWidget, QPushButton, QMainWindow, 
                                QLabel, QLineEdit, QTableWidget, QTableWidgetItem, 
                                QGridLayout, QVBoxLayout, QSizePolicy, QSpacerItem, 
                                QMessageBox,QSpinBox, QTableView,QStyledItemDelegate)
from PyQt5.QtCore import Qt, QMetaObject, QCoreApplication
from PyQt5.QtGui import QFont
import sqlite3
from AddItemScreen import Ui_AddItemMenu
from Constants import MainDatabase, Markup


class Ui_MainDisplay(QMainWindow):
    def __init__(self, parent = None):
        super(Ui_MainDisplay, self).__init__(parent)
        self.setObjectName("MainDisplay")
        self.setGeometry(0, 0, 1123, 903)
        self.setStyleSheet("background-color: rgb(0, 170, 255);")
        self.centralwidget = QWidget(self)
        self.centralwidget.setObjectName("centralwidget")
        self.gridLayout = QGridLayout(self.centralwidget)
        self.gridLayout.setObjectName("gridLayout")
        self.verticalLayout = QVBoxLayout()
        self.verticalLayout.setContentsMargins(-1, 0, -1, 0)
        self.verticalLayout.setSpacing(6)
        self.verticalLayout.setObjectName("verticalLayout")
        self.AddItemButton = QPushButton(self.centralwidget)
        font = QFont()
        font.setPointSize(10)
        font.setBold(True)
        font.setWeight(75)
        self.AddItemButton.setFont(font)
        self.AddItemButton.setStyleSheet("background-color: rgb(85, 255, 0);\n"
"border-style: outset;\n"
"border-width: 2px;\n"
"border-radius: 15px;\n"
"border-color: black;\n"
"padding: 4px;\n"
"\n"
"")
        self.AddItemButton.setObjectName("AddItemButton")
        self.verticalLayout.addWidget(self.AddItemButton)
        self.DeleteItemButton = QPushButton(self.centralwidget)
        font = QFont()
        font.setPointSize(10)
        font.setBold(True)
        font.setWeight(75)
        self.DeleteItemButton.setFont(font)
        self.DeleteItemButton.setStyleSheet("background-color: rgb(255, 65, 68);\n"
"border-style: outset;\n"
"border-width: 2px;\n"
"border-radius: 15px;\n"
"border-color: black;\n"
"padding: 4px;\n"
"")
        self.DeleteItemButton.setObjectName("DeleteItemButton")
        self.verticalLayout.addWidget(self.DeleteItemButton)
        self.CheckoutButton = QPushButton(self.centralwidget)
        font = QFont()
        font.setPointSize(10)
        font.setBold(True)
        font.setWeight(75)
        self.CheckoutButton.setFont(font)
        self.CheckoutButton.setStyleSheet("background-color: rgb(255, 255, 0);\n"
"border-style: outset;\n"
"border-width: 2px;\n"
"border-radius: 15px;\n"
"border-color: black;\n"
"padding: 4px;\n"
"")
        self.CheckoutButton.setObjectName("CheckoutButton")
        self.verticalLayout.addWidget(self.CheckoutButton)
        self.ReturnButton = QPushButton(self.centralwidget)
        font = QFont()
        font.setPointSize(10)
        font.setBold(True)
        font.setWeight(75)
        self.ReturnButton.setFont(font)
        self.ReturnButton.setStyleSheet("background-color: rgb(255, 170, 32);\n"
"border-style: outset;\n"
"border-width: 2px;\n"
"border-radius: 15px;\n"
"border-color: black;\n"
"padding: 4px;\n"
"")
        self.ReturnButton.setObjectName("ReturnButton")
        self.verticalLayout.addWidget(self.ReturnButton)
        self.ScanBarcodeButton = QPushButton(self.centralwidget)
        font = QFont()
        font.setPointSize(10)
        font.setBold(True)
        font.setWeight(75)
        self.ScanBarcodeButton.setFont(font)
        self.ScanBarcodeButton.setStyleSheet("background-color: rgb(211, 211, 211);\n"
"border-style: outset;\n"
"border-width: 2px;\n"
"border-radius: 15px;\n"
"border-color: black;\n"
"padding: 4px;\n"
"")
        self.ScanBarcodeButton.setObjectName("ScanBarcodeButton")
        self.verticalLayout.addWidget(self.ScanBarcodeButton)
        self.SettingsButton = QPushButton(self.centralwidget)
        font = QFont()
        font.setPointSize(10)
        font.setBold(True)
        font.setWeight(75)
        self.SettingsButton.setFont(font)
        self.SettingsButton.setStyleSheet("background-color: rgb(196, 17, 255);\n"
"border-style: outset;\n"
"border-width: 2px;\n"
"border-radius: 15px;\n"
"border-color: black;\n"
"padding: 4px;")
        self.SettingsButton.setObjectName("SettingsButton")
        self.verticalLayout.addWidget(self.SettingsButton)
        self.RefreshButton = QPushButton(self.centralwidget)
        font = QFont()
        font.setPointSize(10)
        font.setBold(True)
        font.setWeight(75)
        self.RefreshButton.setFont(font)
        self.RefreshButton.setStyleSheet("background-color: rgb(0, 255, 255);\n"
"border-style: outset;\n"
"border-width: 2px;\n"
"border-radius: 15px;\n"
"border-color: black;\n"
"padding: 4px;\n"
"\n"
"")
        self.RefreshButton.setObjectName("RefreshButton")
        self.verticalLayout.addWidget(self.RefreshButton)
        spacerItem = QSpacerItem(20, 40, QSizePolicy.Policy.Minimum, QSizePolicy.Policy.Expanding)
        self.verticalLayout.addItem(spacerItem)
        self.LogoutButton = QPushButton(self.centralwidget)
        font = QFont()
        font.setPointSize(10)
        font.setBold(True)
        font.setWeight(75)
        self.LogoutButton.setFont(font)
        self.LogoutButton.setStyleSheet("background-color: rgb(255, 255, 255);\n"
"border-style: outset;\n"
"border-width: 2px;\n"
"border-radius: 15px;\n"
"border-color: black;\n"
"padding: 4px;\n"
"")
        self.LogoutButton.setObjectName("LogoutButton")
        self.verticalLayout.addWidget(self.LogoutButton)
        self.gridLayout.addLayout(self.verticalLayout, 4, 3, 1, 1)
        self.Header = QLabel(self.centralwidget)
        font = QFont()
        font.setPointSize(15)
        font.setBold(True)
        font.setWeight(75)
        self.Header.setFont(font)
        self.Header.setStyleSheet("background-color: rgb(0, 0, 0);\n"
"color: rgb(255, 255, 255);\n"
"border-style: outset;\n"
"border-width: 2px;\n"
"border-radius: 15px;\n"
"border-color: black;\n"
"padding: 4px;")
        self.Header.setAlignment(Qt.AlignmentFlag.AlignCenter)
        self.Header.setObjectName("Header")
        self.gridLayout.addWidget(self.Header, 0, 1, 1, 3)
        self.SearchButton = QPushButton(self.centralwidget)
        font = QFont()
        font.setPointSize(10)
        font.setBold(True)
        font.setWeight(75)
        self.SearchButton.setFont(font)
        self.SearchButton.setStyleSheet("background-color: rgb(211, 211, 211);\n"
"border-style: outset;\n"
"border-width: 2px;\n"
"border-radius: 15px;\n"
"border-color: black;\n"
"padding: 4px;\n"
"")
        self.SearchButton.setObjectName("SearchButton")
        self.gridLayout.addWidget(self.SearchButton, 2, 1, 1, 1)
        self.SearchBar = QLineEdit(self.centralwidget)
        self.SearchBar.setStyleSheet("background-color: rgb(255, 255, 255);")
        self.SearchBar.setObjectName("SearchBar")
        self.gridLayout.addWidget(self.SearchBar, 2, 2, 1, 1)

        self.retranslateUi(self)
        QMetaObject.connectSlotsByName(self)

#----------------------------------------------------------------------------------------------------
#                                       Inventory Display
#----------------------------------------------------------------------------------------------------

        #Connect to Database
        self.db = QSqlDatabase.addDatabase('QSQLITE')
        self.db.setDatabaseName('inventory.db')
        self.model = QSqlTableModel()
        self.delrow = -1
        self.initializeModel()

        self.sbar = self.statusBar()

        self.InventoryDisplay = QTableView()
        self.InventoryDisplay.setStyleSheet("background-color: rgb(255, 255, 255);")
        self.InventoryDisplay.setModel(self.model)
        self.InventoryDisplay.clicked.connect(self.findrow)
        self.InventoryDisplay.selectionModel().selectionChanged.connect(self.getCellText)

        self.gridLayout.addWidget(self.InventoryDisplay, 4, 1, 1, 2)
        self.setCentralWidget(self.centralwidget)

        self.calculate_sellprice()

    #------------------------------------------------------------------------
    #When Price is updated automatically update SellPrice when refresh is hit
    #------------------------------------------------------------------------
    def calculate_sellprice(self):
        for row in range(self.InventoryDisplay.model().rowCount() - 1):
                sell_price = str(self.InventoryDisplay.model().index(row, 3).data())
                if sell_price:
                        sell_price = f'{float(sell_price.replace(",", ".")) * Markup:.2f}'
                        self.InventoryDisplay.model().setData(self.InventoryDisplay.model().index(row, 4), sell_price)


        #----------------------------------
        #Make Specific Columns Un-Editable/ReadOnly
        #----------------------------------
        class ReadOnlyDelegate(QStyledItemDelegate):
                def createEditor(self, parent, option, index):
                        print('This column is Read-Only')
                        return 

        delegate = ReadOnlyDelegate(self)
        self.InventoryDisplay.setItemDelegateForColumn(0, delegate) #ID
        self.InventoryDisplay.setItemDelegateForColumn(2, delegate) #Quantity
        self.InventoryDisplay.setItemDelegateForColumn(4, delegate) #SellPrice
        self.InventoryDisplay.setItemDelegateForColumn(10, delegate) #Date Added
        #----------------------------------

    def initializeModel(self):
       self.model.setTable('items')
       self.model.setEditStrategy(QSqlTableModel.OnFieldChange)
       self.model.select()
        
#----------------------------------
#       Update Inventory
#---------------------------------- 
#TODO: Have SellPrice update if Price is updated 
  
    def findrow(self, i):
        self.delrow = i.row()
 
    def getCellText(self):
        if self.InventoryDisplay.selectedIndexes():
            item = self.InventoryDisplay.selectedIndexes()[0]
            row = self.selectedRow()
            column = self.selectedColumn()
            if not item == None:
                name = item.data()
                self.sbar.showMessage(str(name))
 
    def selectedRow(self):
        if self.InventoryDisplay.selectionModel().hasSelection():
            row =  self.InventoryDisplay.selectionModel().selectedIndexes()[0].row()
            return int(row)
 
    def selectedColumn(self):
        column =  self.InventoryDisplay.selectionModel().selectedIndexes()[0].column()
        return int(column)
#----------------------------------
#----------------------------------------------------------------------------------------------------
  
    def retranslateUi(self, MainDisplay):
        _translate = QCoreApplication.translate
        self.setWindowTitle(_translate("MainDisplay", "AdminMenu"))
        self.AddItemButton.setText(_translate("MainDisplay", "Add Item"))
        self.DeleteItemButton.setText(_translate("MainDisplay", "Delete Item"))
        self.CheckoutButton.setText(_translate("MainDisplay", "Check Out"))
        self.ReturnButton.setText(_translate("MainDisplay", "Return"))
        self.ScanBarcodeButton.setText(_translate("MainDisplay", "Scan Barcode"))
        self.SettingsButton.setText(_translate("MainDisplay", "Settings"))
        self.RefreshButton.setText(_translate("MainDisplay", "Refresh"))
        self.LogoutButton.setText(_translate("MainDisplay", "Log Out"))
        self.Header.setText(_translate("MainDisplay", "Admin Menu"))
        self.SearchButton.setText(_translate("MainDisplay", "Search"))

#----------------------------------------------------------------------------------------------------
#                                      Button Actions
#----------------------------------------------------------------------------------------------------
        #------------------------------------------
                        #Logout Button
        #------------------------------------------
        #When the Logout button is clicked -> LogoutClicked Function
        LogoutButton = self.LogoutButton
        LogoutButton.clicked.connect(self.LogoutClicked)
        #------------------------------------------
        #------------------------------------------
                        #Add Item Button
        #------------------------------------------
        #When the AddItem button is clicked -> AddItem Function
        AddItemButton = self.AddItemButton
        AddItemButton.clicked.connect(self.AddItemClicked)
        #------------------------------------------
        #------------------------------------------
                     #Remove Item Button
        #------------------------------------------
        #When the RemoveItem button is clicked -> RemoveItem Function
        RemoveItemButton = self.DeleteItemButton
        RemoveItemButton.clicked.connect(self.RemoveItemClicked)
        #------------------------------------------
        #------------------------------------------
                     #Checkout Item Button
        #------------------------------------------
        #When the Checkout button is clicked -> Checkout Function
        CheckoutButton = self.CheckoutButton
        CheckoutButton.clicked.connect(self.CheckoutClicked)
        #------------------------------------------
        #------------------------------------------
                     #Return Item Button
        #------------------------------------------
        #When the Return button is clicked -> Return Function
        ReturnButton = self.ReturnButton
        ReturnButton.clicked.connect(self.ReturnClicked)
        #------------------------------------------
        #------------------------------------------
                     #Scan Barcode Button
        #------------------------------------------
        #When the Scan Barcode button is clicked -> ScanBarcode Function
        ScanBarcodeButton = self.ScanBarcodeButton
        ScanBarcodeButton.clicked.connect(self.ScanBarcodeClicked)
        #------------------------------------------
        #------------------------------------------
                     #Settings Button
        #------------------------------------------
        #When the Settings button is clicked -> Settings Function
        SettingsButton = self.SettingsButton
        SettingsButton.clicked.connect(self.SettingsClicked)
        #------------------------------------------
        #------------------------------------------
                     #Refresh Button
        #------------------------------------------
        #When the More Info button is clicked -> MoreInfo Function
        RefreshButton = self.RefreshButton
        RefreshButton.clicked.connect(self.RefreshClicked)
        #------------------------------------------
        #------------------------------------------
                     #Search Button
        #------------------------------------------
        #When the More Info button is clicked -> MoreInfo Function
        SearchButton = self.SearchButton
        SearchButton.clicked.connect(self.SearchClicked)
        #------------------------------------------
#----------------------------------
    #Logout Function
    def LogoutClicked(self):
        #Print in terminal for testing:
        print("The Logout Button was clicked")
        #Switch from this screen to the LoginScreen
        #(Import LoginScreen here to prevent circular import error)
        from LoginScreen import Ui_Loginscreen
        self.win = Ui_Loginscreen() #Define LoginScreen
        self.win.show() #Show Login Screen
        self.close() #Close this screen (AdminMenu)
#----------------------------------
#----------------------------------
    #AddItem Function
    def AddItemClicked(self):
        #Print in terminal for testing:
        print("The Add Item Button was clicked")
        #Switch from this screen to the AddItems Screen (Scene Swap):
        self.win = Ui_AddItemMenu()
        self.win.show()
        self.close()
#----------------------------------
#----------------------------------
    #RemoveItem Function
    def RemoveItemClicked(self):
        #Print in terminal for testing:
        print("The Delete Item Button was clicked")
        self.DeleteConfirmation()
    #----------------------------------
    #   Delete Item Confirmation
    #----------------------------------
    def DeleteConfirmation(self):
        msgBox = QMessageBox()
        msgBox.setIcon(QMessageBox.Warning)
        msgBox.setText("Are you sure you want to delete this item?")
        msgBox.setInformativeText("*This cannot be undone")
        msgBox.setWindowTitle("Delete Item Confirmation")
        msgBox.setStandardButtons(QMessageBox.Yes | QMessageBox.No)
  
        returnValue = msgBox.exec()
        if returnValue == QMessageBox.Yes:
                row = self.InventoryDisplay.currentIndex().row()
                self.model.removeRow(row)
                self.initializeModel()
                self.InventoryDisplay.selectRow(row)
#----------------------------------
#----------------------------------
    #Checkout Function
    def CheckoutClicked(self):
        #Print in terminal for testing:
        print("The Checkout Button was clicked")
#----------------------------------
#----------------------------------
    #Return Function
    def ReturnClicked(self):
        #Print in terminal for testing:
        print("The Return Button was clicked")
#----------------------------------
#----------------------------------
    #ScanBarcode Function
    def ScanBarcodeClicked(self):
        #Print in terminal for testing:
        print("The Scan Barcode Button was clicked")
#----------------------------------
#----------------------------------
    #Settings Function
    def SettingsClicked(self):
        #Print in terminal for testing:
        print("The Settings Button was clicked")
#----------------------------------
#----------------------------------
    #Refresh Function
    def RefreshClicked(self):
        #Print in terminal for testing:
        print("The Refresh Button was clicked")
        #Close and reopen the app (Refresh)
        self.win = Ui_MainDisplay()
        self.win.show()
        self.close()
#----------------------------------
#----------------------------------
    #Search Function
    def SearchClicked(self):
        #Print in terminal for testing:
        print("The Search Button was clicked")
        
        userQuery = self.SearchBar.text()
        #Connect to the inventory database (inventory.db)
        connection = sqlite3.connect(MainDatabase)
        cursor = connection.cursor()
        cursor.execute("SELECT * FROM items WHERE Name LIKE'%'||?||'%'",(userQuery,))
        connection.commit()
        #Get all info from the Items Table
        result = cursor.fetchall()
        print(result)
        #Close the connection to the database
        connection.close()
#----------------------------------
#----------------------------------------------------------------------------------------------------

 
if __name__ == '__main__':
    app = QApplication(sys.argv)
    win = Ui_MainDisplay()
    win.show()

    sys.exit(app.exec_())
Reply
#2
a simple filter example

from PyQt5 import QtCore, QtGui, QtWidgets, QtSql


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

        self.setGeometry(50, 50, 800, 600)
        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("items")
        self.model.select()

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

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

    def filter_table(self, text):
        f = " {} LIKE '%{}%'".format(self.combo.currentText(), text.lower()) 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("inventory.db")
    if not db.open():
        sys.exit(-1)

    ex = Widget()
    ex.show()
    sys.exit(app.exec_())
    
if __name__ == "__main__":
    main()
Reply
#3
You can also use QTreeview with column filters.

import sys
import re
from PyQt5 import QtWidgets, QtGui, QtCore, QtSql

TRACE = True

MY_TABLE = "items"
db = QtSql.QSqlDatabase.addDatabase("QSQLITE")
db.setDatabaseName("inventory.db")

modelQuery = QtSql.QSqlQueryModel()
modelTable = QtSql.QSqlRelationalTableModel()

g_hits_count = 0
g_total_count = 0
g_selected_count = 0


def trace(message):
    if TRACE:
        print(message)


def _human_key(key):
    parts = re.split(r"(\d*\.\d+|\d+)", key)
    return tuple(
        (e.swapcase() if i % 2 == 0 else float(e)) for i, e in enumerate(parts)
    )


class FilterHeader(QtWidgets.QHeaderView):
    filterActivated = QtCore.pyqtSignal()

    def __init__(self, parent):
        super().__init__(QtCore.Qt.Horizontal, parent)
        self._editors = []
        self._padding = 4
        self.setStretchLastSection(True)
        self.setDefaultAlignment(QtCore.Qt.AlignLeft | QtCore.Qt.AlignVCenter)
        self.setSortIndicatorShown(False)
        self.sectionResized.connect(self.adjustPositions)
        parent.horizontalScrollBar().valueChanged.connect(self.adjustPositions)

    def setFilterBoxes(self, count):
        while self._editors:
            editor = self._editors.pop()
            editor.deleteLater()
        for index in range(count):
            editor = QtWidgets.QLineEdit(self.parent())
            editor.setPlaceholderText("Filter")
            editor.setClearButtonEnabled(True)
            editor.textChanged.connect(self.textChanged)

            self._editors.append(editor)
        self.adjustPositions()

    def textChanged(self):
        self.filterActivated.emit()

    def sizeHint(self):
        size = super().sizeHint()
        if self._editors:
            height = self._editors[0].sizeHint().height()
            size.setHeight(size.height() + height + self._padding)
        return size

    def updateGeometries(self):
        if self._editors:
            height = self._editors[0].sizeHint().height()
            self.setViewportMargins(0, 0, 0, height + self._padding)
        else:
            self.setViewportMargins(0, 0, 0, 0)
        super().updateGeometries()
        self.adjustPositions()

    def adjustPositions(self):
        for index, editor in enumerate(self._editors):
            height = editor.sizeHint().height()
            editor.move(
                self.sectionPosition(index) - self.offset() + 2,
                height + (self._padding // 2),
            )
            editor.resize(self.sectionSize(index), height)

    def filterText(self, index):
        if 0 <= index < len(self._editors):
            return self._editors[index].text()
        return ""

    def setFilterText(self, index, text):
        if 0 <= index < len(self._editors):
            self._editors[index].setText(text)

    def clearFilters(self):
        for editor in self._editors:
            editor.clear()


class HumanProxyModel(QtCore.QSortFilterProxyModel):
    def lessThan(self, source_left, source_right):
        data_left = source_left.data()
        data_right = source_right.data()
        return True
        if type(data_left) == type(data_right) == str:
            return _human_key(data_left) < _human_key(data_right)
        return super(HumanProxyModel, self).lessThan(source_left, source_right)

    @property
    def filters(self):
        if not hasattr(self, "_filters"):
            self._filters = []
        return self._filters

    @filters.setter
    def filters(self, filters):
        self._filters = filters
        self.invalidateFilter()

        global g_hits_count
        g_hits_count = self.rowCount()

    def filterAcceptsRow(self, sourceRow, sourceParent):
        for i, text in self.filters:
            if 0 <= i < self.sourceModel().columnCount():
                ix = self.sourceModel().index(sourceRow, i, sourceParent)
                data = ix.data()
                if text not in data.lower():
                    return False

        return True


class winMain(QtWidgets.QMainWindow):
    cur_row = -1
    row_id = -1

    def __init__(self, parent=None):
        super().__init__(parent)
        self.setWindowTitle("Music List")
        self.setupUi()
        self.setGeometry(0, 0, 900, 800)

        self.show()

    def closeEvent(self, event):
        self.deleteLater()


    def handleFilterActivated(self):
        header = self.treeView.header()
        filters = []
        for i in range(header.count()):
            text = header.filterText(i)
            if text:
                filters.append((i, text))
        proxy = self.treeView.model()
        proxy.filters = filters

        self.updateStatus()
        self.treeView.setCurrentIndex(self.treeView.model().index(0, 0))


    def keyReleaseEvent(self, eventQKeyEvent):
        key = eventQKeyEvent.key()
        modifiers = QtWidgets.QApplication.keyboardModifiers()
        if modifiers == QtCore.Qt.ShiftModifier and key == QtCore.Qt.Key_Escape:
            self.clear_all_filters()

    def keyPressEvent(self, event):
        key = event.key()

        modifiers = QtWidgets.QApplication.keyboardModifiers()

        if modifiers != QtCore.Qt.ShiftModifier:
            focus_obj = self.focusWidget()

            if key == QtCore.Qt.Key_Return:
                if isinstance(focus_obj, QtWidgets.QTreeView):
                    self.edit_record(self.treeView.currentIndex())

            elif key == QtCore.Qt.Key_Escape:
                if isinstance(focus_obj, QtWidgets.QLineEdit):
                    focus_obj.clear()

    def clear_all_filters(self):
        # clear all inputs of type QLineEdit
        lineEdits = self.findChildren(QtWidgets.QLineEdit)
        for lineEdit in lineEdits:
            lineEdit.clear()
        
    def setupUi(self):
        self.setWindowIcon(QtGui.QIcon.fromTheme("applications-multimedia"))
        self.centralwidget = QtWidgets.QWidget(self)
        hBox = QtWidgets.QHBoxLayout(self.centralwidget)
        
        self.treeView = QtWidgets.QTreeView(self.centralwidget)
        self.treeView.setSelectionBehavior(1)
        self.treeView.setRootIsDecorated(False)
        self.treeView.setSortingEnabled(True)
        self.treeView.setAlternatingRowColors(True)
        self.treeView.setEditTriggers(QtWidgets.QAbstractItemView.DoubleClicked)
        self.treeView.setSelectionMode(1)
        self.treeView.header().setStretchLastSection(True)

        hBox.addWidget(self.treeView)
        self.setCentralWidget(self.centralwidget)

        header = FilterHeader(self.treeView)
        self.treeView.setHeader(header)

        # StatusBar
        self.statusBar = self.statusBar()
        self.setStatusBar(self.statusBar)
        
        modelTable.setTable(MY_TABLE)

        modelTable.setEditStrategy(QtSql.QSqlTableModel.OnFieldChange)

        self.treeView.setModel(modelTable)
        while modelTable.canFetchMore():
            modelTable.fetchMore()
        if not TRACE:
            self.treeView.setColumnHidden(0, True)

        # enable human sorting
        proxy = HumanProxyModel(self)
        
        proxy.setSourceModel(modelTable)
        self.treeView.setModel(proxy)

        # enable filtering
        header.setFilterBoxes(modelTable.columnCount())
        header.filterActivated.connect(self.handleFilterActivated)

        # update counters
        global g_total_count, g_hits_count
        g_total_count = modelTable.rowCount()
        g_hits_count = g_total_count
        self.treeView.setColumnWidth(0, 200)
        self.treeView.setColumnWidth(1, 300)
        self.treeView.hideColumn(3)
        
        self.setWindowTitle(f"Inventory - {str(g_total_count)} Items")


if __name__ == "__main__":
    app = QtWidgets.QApplication(sys.argv)
    window = winMain()
    sys.exit(app.exec_())
Reply
#4
Thanks for the help.
I replaced my SearchButton with a comboBox so it can be used as the filter like you showed in your first example.
I like that one much better. It's more straightforward and easy for the user to use.
Reply
#5
hi, I am trying this right now, based on something I saw in another discussion on this group, but don't know the syntax for that last line. It doesn't like just "row" in the append; The fetchall is returning a tuple.!

mapquest driving directions
Reply
#6
(Jun-28-2022, 06:50 AM)ryderbellamy Wrote: hi, I am trying this right now, based on something I saw in another discussion on this group, but don't know the syntax for that last line. It doesn't like just "row" in the append; The fetchall is returning a tuple.!

If it returns a Tuple and you need it as a string you can always convert the tuple to a string using str.join()
https://www.delftstack.com/howto/python/...ng-python/
Reply


Possibly Related Threads…
Thread Author Replies Views Last Post
  [Tkinter] Search data in treeview without search button TomasSanchexx 3 1,526 Aug-12-2023, 03:17 AM
Last Post: deanhystad
  [PyQt] [solved] How to display a pdf-file in a PyQt6 widget BigMan 13 15,674 May-06-2023, 09:27 AM
Last Post: Axel_Erfurt
  [PyQt] [Solved]Display PyQtTable results from A->Z & Z->A Extra 2 1,142 Jul-18-2022, 04:04 PM
Last Post: Extra
  [PyQt] [Solved]Help Adding Sql Results in ComboBox Extra 2 1,216 Jul-07-2022, 09:46 PM
Last Post: Extra
  [PyQt] [Solved]Help Adding results from for loop Extra 2 1,416 Jun-24-2022, 05:01 PM
Last Post: Extra
  How to display results from terminal window onto tkinter. buttercup 0 3,602 Jul-21-2020, 04:41 AM
Last Post: buttercup
  [Tkinter] add search bar = search for input in all computer directory francisco_neves2020 15 10,762 Apr-14-2019, 07:29 PM
Last Post: francisco_neves2020
  Display and update the label text which display the serial value jenkins43 5 8,990 Feb-04-2019, 04:36 AM
Last Post: Larz60+
  Display more than one button in GUI to display MPU6000 Sensor readings barry76 4 3,834 Jan-05-2019, 01:48 PM
Last Post: wuf
  [PyQt] I am unable to connect Qtable widget in another tab? aditech 1 2,431 Sep-13-2018, 04:44 PM
Last Post: Axel_Erfurt

Forum Jump:

User Panel Messages

Announcements
Announcement #1 8/1/2020
Announcement #2 8/2/2020
Announcement #3 8/6/2020