Buy Me a Coffee? Your support is much appreciated!
PayPal Me: https://www.paypal.me/jiejenn/5
Venmo: @Jie-Jenn
Source Code:
import sys from PyQt5.QtWidgets import QApplication, QWidget, QPushButton, QLabel, QLineEdit, QTableWidget, QTableWidgetItem, QHeaderView, \ QHBoxLayout, QVBoxLayout, QFrame, QDesktopWidget, QAbstractItemView from PyQt5.QtCore import Qt from PyQt5.QtGui import QIcon COLOR1 = '#962D2E' class TableWidgetItem(QTableWidgetItem): def __init__(self, text): super().__init__(text) self.setTextAlignment(Qt.AlignCenter) class Tip_Calculator(QWidget): def __init__(self): super().__init__() self.window_width, self.window_height = 1700, 1150 self.setFixedSize(self.window_width, self.window_height) self.setWindowTitle('Tip Calculator by Jay') self.setWindowIcon(QIcon(r'C:\Users\Jie\Google Drive\(YouTube Folder)\_To Upload\(PyQt5) Tip Calculator\Calculator.ico')) self.setStyleSheet(''' QLineEdit { height: 45px; } ''') self.layout = QVBoxLayout() self.setLayout(self.layout) self.subLayouts = {} self.inputFields() self.outputFields() self.insertSummaryTable() def insertSummaryTable(self): self.subLayouts['summaryTable'] = QVBoxLayout() self.layout.addLayout(self.subLayouts['summaryTable']) tiers = ( (0.05, 'Very Poor'), (0.1, 'Very Poor'), (0.13, 'Poor'), (0.15, 'Average'), (0.18, 'Average'), (0.2, 'Above Average'), (0.23, 'Good'), (0.25, 'Very Good'), (0.28, 'Excellent'), (0.3, 'Excellent'), (0.32, 'Amazing'), (0.35, 'Amazing'), (0.38, 'Amazing'), (0.4, 'Cousins'), (0.5, 'Family') ) self.summaryTable = QTableWidget(len(tiers), 6) self.summaryTable.setShowGrid(False) self.summaryTable.verticalHeader().setVisible(False) self.summaryTable.horizontalHeader().setSectionResizeMode(QHeaderView.Fixed) self.summaryTable.setAlternatingRowColors(True) self.summaryTable.setHorizontalHeaderLabels( ('Tip %', 'Tip Amount', 'Bill Amount', 'Bill Per Person', 'Tip Per Person', 'Service Scale') ) self.summaryTable.setEditTriggers(QAbstractItemView.NoEditTriggers) # allow selection, but no editing self.summaryTable.setColumnWidth(0, 180) self.summaryTable.setColumnWidth(1, 270) self.summaryTable.setColumnWidth(2, 280) self.summaryTable.setColumnWidth(3, 280) self.summaryTable.setColumnWidth(4, 270) self.summaryTable.setColumnWidth(5, 380) self.summaryTable.setStyleSheet(f''' ::section {{ background-color: {COLOR1}; color: white; border: none; }} ''') for indx, tier in enumerate(tiers): item = TableWidgetItem(str('{:.0f}%'.format(tier[0] * 100))) self.summaryTable.setItem(indx, 0, item) self.summaryTable.setItem(indx, 1, TableWidgetItem('${:.2f}'.format(0))) self.summaryTable.setItem(indx, 2, TableWidgetItem('${:.2f}'.format(0))) self.summaryTable.setItem(indx, 3, TableWidgetItem('${:.2f}'.format(0))) self.summaryTable.setItem(indx, 4, TableWidgetItem('${:.2f}'.format(0))) item = TableWidgetItem(tier[1]) self.summaryTable.setItem(indx, 5, item) self.subLayouts['summaryTable'].addWidget(self.summaryTable) def inputFields(self): self.subLayouts['inputLabels'] = QHBoxLayout() self.subLayouts['inputLabels'].setSpacing(15) self.layout.addLayout(self.subLayouts['inputLabels']) self.subLayouts['inputFields'] = QHBoxLayout() self.subLayouts['inputFields'].setSpacing(15) self.layout.addLayout(self.subLayouts['inputFields']) labels = ('Bill Amount ($)', 'Tip %', 'Number of People') for label in labels: self.subLayouts['inputLabels'].addWidget(QLabel(label + ' :')) hLine = QFrame(self) hLine.setFrameShadow(QFrame.Sunken) hLine.setFrameShape(QFrame.VLine) hLine.setGeometry(0, 135, QDesktopWidget().screenGeometry().width() + 300, 4) hLine.setStyleSheet(f'background-color: {COLOR1};') self.inputs = {} self.inputs['Bill Amount'] = QLineEdit() self.inputs['Tip Percentage'] = QLineEdit() self.inputs['Party Number'] = QLineEdit() for key, widget in self.inputs.items(): self.subLayouts['inputFields'].addWidget(widget) widget.setPlaceholderText(f'Enter {key}') widget.setObjectName(key.replace(' ', '')) #TODO (Conigure Signals) # widget.editingFinished.connect() widget.textChanged.connect(self.calculateTips) def outputFields(self): self.layout.addSpacing(40) self.subLayouts['outputLabels'] = QHBoxLayout() self.subLayouts['outputLabels'].setSpacing(15) self.layout.addLayout(self.subLayouts['outputLabels']) self.subLayouts['outputFields'] = QHBoxLayout() self.subLayouts['outputFields'].setSpacing(15) self.layout.addLayout(self.subLayouts['outputFields']) labels = ('Tip Amount', 'Total Bill Amount', 'Tip Per Person', 'Total Bill Per Person') for label in labels: self.subLayouts['outputLabels'].addWidget(QLabel(label)) self.outputs = {} self.outputs['Tip Amount'] = QLineEdit() self.outputs['Total Bill Amount'] = QLineEdit() self.outputs['Tip Per Person'] = QLineEdit() self.outputs['Total Bill Per Person'] = QLineEdit() for widget in self.outputs.values(): widget.setReadOnly(True) self.subLayouts['outputFields'].addWidget(widget) self.layout.addSpacing(15) def calculateTips(self): try: tipAmount = float(self.inputs['Bill Amount'].text()) * float(self.inputs['Tip Percentage'].text()) / 100 totalBillAmount = tipAmount + float(self.inputs['Bill Amount'].text()) tipPerPerson = '{:.2f}'.format(tipAmount / int(self.inputs['Party Number'].text())) billPerPerson = '{:.2f}'.format(totalBillAmount / int(self.inputs['Party Number'].text())) tipAmount = '{:.2f}'.format(tipAmount) totalBillAmount = '{:.2f}'.format(totalBillAmount) self.outputs['Tip Amount'].setText('$' + str(tipAmount)) self.outputs['Total Bill Amount'].setText('$' + str(totalBillAmount)) self.outputs['Tip Per Person'].setText('$' + str(tipPerPerson)) self.outputs['Total Bill Per Person'].setText('$' + str(billPerPerson)) self.updateSummaryTable() except ValueError: self.outputs['Tip Amount'].setText('') self.outputs['Total Bill Amount'].setText('') self.outputs['Tip Per Person'].setText('') self.outputs['Total Bill Per Person'].setText('') def updateSummaryTable(self): for row in range(self.summaryTable.rowCount()): tip_percentage = float(self.summaryTable.item(row, 0).text().replace('%', '')) / 100 tipAmount = float(self.inputs['Bill Amount'].text()) * tip_percentage totalBillAmount = tipAmount + float(self.inputs['Bill Amount'].text()) tipPerPerson = '{:.2f}'.format(tipAmount / int(self.inputs['Party Number'].text())) billPerPerson = '{:.2f}'.format(totalBillAmount / int(self.inputs['Party Number'].text())) tipAmount = '{:.2f}'.format(tipAmount) totalBillAmount = '{:.2f}'.format(totalBillAmount) self.summaryTable.item(row, 1).setText('$' + str(tipAmount)) self.summaryTable.item(row, 2).setText('$' + str(totalBillAmount)) self.summaryTable.item(row, 3).setText('$' + str(tipPerPerson)) self.summaryTable.item(row, 4).setText('$' + str(billPerPerson)) if __name__ == '__main__': # don't auto scale when drag app to a different monitor. # QApplication.setAttribute(Qt.HighDpiScaleFactorRoundingPolicy.PassThrough) app = QApplication(sys.argv) app.setStyleSheet(''' QWidget { font-size: 30px; } ''') myApp = Tip_Calculator() myApp.show() try: sys.exit(app.exec_()) except SystemExit: print('Closing Window...')