Hello,
How do I get my table display to sort the results depending on what header I click.
For ex:
If I click the "Categories" header it should display the categories in alphabetical order, if I click the "Name" header it should display the items in alphabetical order, and if I click it again, it should show them in reverse alphabetical order.
Is there a way to do this?
Thanks in advance.
Code Snippet of the Inventory Display:
How do I get my table display to sort the results depending on what header I click.
For ex:
If I click the "Categories" header it should display the categories in alphabetical order, if I click the "Name" header it should display the items in alphabetical order, and if I click it again, it should show them in reverse alphabetical order.
Is there a way to do this?
Thanks in advance.
Code Snippet of the Inventory Display:
#----------------------------------------------------------------------------------------------------
# Inventory Display
#----------------------------------------------------------------------------------------------------
#Connect to Database
self.db = QSqlDatabase.addDatabase('QSQLITE')
self.db.setDatabaseName(MainDatabase)
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)
#Only selects rows (Can still edit cells by double-clicking)
self.InventoryDisplay.setSelectionBehavior(1)
# 0 Selecting single items.
# 1 Selecting only rows.
# 2 Selecting only columns.
self.LowQuantityAlert()
#Call the function to calculate the SellPrice
self.calculate_sellprice()
#Call the functions to calculate the total inventory values
self.calculate_TotalValue_NoMarkup()
self.calculate_TotalValue_Markup()
def initializeModel(self):
self.model.setTable('items')#Table name for database
self.model.setEditStrategy(QSqlTableModel.OnFieldChange)
self.model.select()
#------------------------------------------
# Search/Filter
#------------------------------------------
#Allows the user to search for items
self.SearchFilter.clear()
for i in range(self.model.columnCount()):
self.SearchFilter.addItem(self.model.headerData(i, QtCore.Qt.Horizontal))
self.SearchFilter.setCurrentIndex(1)
self.SearchBar.textChanged.connect(self.filter_table)
def filter_table(self, text):
userQuery = " {} LIKE '%{}%'".format(self.SearchFilter.currentText(), text.lower()) if text else text
self.model.setFilter(userQuery)
self.model.select()
#------------------------------------------
#----------------------------------
# Update Inventory
#----------------------------------
def findrow(self, i):
self.delrow = i.row()
def getCellText(self):
if self.InventoryDisplay.selectedIndexes():
model = self.InventoryDisplay.model()
row = self.selectedRow()
column = 1 #Get item name (column 1)
name = model.data(model.index(row, column))
#Shows the item name on the bottom left corner of the screen
self.sbar.showMessage(str(name))
#Get the item Name from the currently selected row
global SelectedItemName
SelectedItemName = model.data(model.index(row, column))
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)
#----------------------------------
#------------------------------------------------------------------------
#When Price is Updated Automatically Update SellPrice When Refresh is Hit
#------------------------------------------------------------------------
def calculate_sellprice(self):
for row in range(self.InventoryDisplay.model().rowCount()):
sell_price = float(self.InventoryDisplay.model().index(row, 3).data())
if sell_price < 50:
Markup = 1.50
elif sell_price < 150:
Markup = 1.45
elif sell_price <= 1000:
Markup = 1.35
elif sell_price < 2000:
Markup = 1.30
elif sell_price < 3000:
Markup = 1.20
elif sell_price < 4000:
Markup = 1.15
else:
Markup = 1.10
sell_price = f'{sell_price * 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
#----------------------------------
#------------------------------------------------------------------------
# Calculate The Total Inventory Value Without Markup (Quantity*Price)
#------------------------------------------------------------------------
def calculate_TotalValue_NoMarkup(self):
global totalPriceNoMarkup
totalPrice = 0.0
for row in range(self.InventoryDisplay.model().rowCount()):
QuantityValue = float(self.InventoryDisplay.model().index(row, 2).data())
PriceValue = float(self.InventoryDisplay.model().index(row, 3).data())
QuanityPriceValue = QuantityValue*PriceValue
totalPrice += QuanityPriceValue
print("Total Price (No Markup): $", totalPrice)
totalPriceNoMarkup = str(totalPrice)
#----------------------------------
#------------------------------------------------------------------------
# Calculate The Total Inventory Value Without Markup (Quantity*Price)
#------------------------------------------------------------------------
def calculate_TotalValue_Markup(self):
global totalPriceMarkup
totalPrice = 0.0
for row in range(self.InventoryDisplay.model().rowCount()):
QuantityValue = float(self.InventoryDisplay.model().index(row, 2).data())
SellPriceValue = float(self.InventoryDisplay.model().index(row, 4).data())
QuanityPriceValue = QuantityValue*SellPriceValue
totalPrice += QuanityPriceValue
print("Total Price (With Markup): $", totalPrice)
totalPriceMarkup = str(totalPrice)
#----------------------------------
#------------------------------------------------------------------------
# Low Quantity Alert
#------------------------------------------------------------------------
def LowQuantityAlert(self):
#Connect to the Inventory database
connection = sqlite3.connect(MainDatabase)
cursor = connection.cursor()
#Get the item name, quantity, & category if it is less than the low quantity value
cursor.execute('''
SELECT I.Name as CURRENT
from Categories as C, Items as I
WHERE C.Category = I.Category
AND I.Quantity < C.Low_Quantity_Value
''')
connection.commit()
#Return the items with low quantity values
Result = cursor.fetchall()
#Close the connection
connection.close()
#Convert Results from Tuple to List
from itertools import chain
LowQuantityItemsList = list(chain.from_iterable(Result))
#Then Convert the List to a String
global LowQuantityItems
LowQuantityItems = ", ".join(str(x) for x in LowQuantityItemsList)
#If Result return an empty list Quanity is good, else call popup
if Result == []:
print("Quantity All Good")
else:
self.ex = Ui_LowQuantityAlertPopup(parent=self)
self.ex.show()
#----------------------------------
#----------------------------------------------------------------------------------------------------
