diff --git a/img/icons8-export-xls-32.png b/img/icons8-export-xls-32.png new file mode 100644 index 0000000..76aba0f Binary files /dev/null and b/img/icons8-export-xls-32.png differ diff --git a/img/icons8-garage-32.png b/img/icons8-garage-32.png new file mode 100644 index 0000000..6673d8c Binary files /dev/null and b/img/icons8-garage-32.png differ diff --git a/img/icons8-information-32.png b/img/icons8-information-32.png new file mode 100644 index 0000000..b37075b Binary files /dev/null and b/img/icons8-information-32.png differ diff --git a/img/icons8-new-file-32.png b/img/icons8-new-file-32.png new file mode 100644 index 0000000..943f73c Binary files /dev/null and b/img/icons8-new-file-32.png differ diff --git a/img/icons8-opened-folder-32.png b/img/icons8-opened-folder-32.png new file mode 100644 index 0000000..eb7f720 Binary files /dev/null and b/img/icons8-opened-folder-32.png differ diff --git a/img/icons8-save-32.png b/img/icons8-save-32.png new file mode 100644 index 0000000..aec207f Binary files /dev/null and b/img/icons8-save-32.png differ diff --git a/img/system-shutdown.png b/img/system-shutdown.png new file mode 100644 index 0000000..4e38373 Binary files /dev/null and b/img/system-shutdown.png differ diff --git a/main.py b/main.py new file mode 100644 index 0000000..837a227 --- /dev/null +++ b/main.py @@ -0,0 +1,692 @@ +#!/usr/bin/env python3 +""" +project: GarageCalc1 +file: main.py +summary: Calculates available size of a garage space +license: GPL +author: Paul Salajean (p.salajean[at]gmx.de) +""" + +# Standard library imports +import sys +import os +import csv + +# Third party imports +from PySide2.QtWidgets import QApplication, QMainWindow, QTableWidgetItem, QStatusBar, QAction, QFileDialog, \ + QAbstractItemView, QMenu, QMessageBox +from PySide2.QtGui import QIcon +from PySide2.QtCore import QFile, QSize, Qt +from PySide2.QtUiTools import QUiLoader + +# Local imports +from utils import show_about + +# Local globals +UI_FILE = "main.ui" +APP_NAME = "Garagenraum-Rechner" +APP_DISPNAME = "GarageCalc" +APP_VERSION = "v0.1" +APP_AUTHOR = "Paul Salajean" +APP_DESCR = "Berechnet zur Verfügung stehenden Garagenraum" +APP_COPYRIGHT = "(c) Paul Salajean 2021" +APP_WEBSITE = "https://gitlab.com/ProfP303" +APP_DESKTOPFILENAME = "GarageCalc" +APP_ICON = "./img/icons8-garage-32.png" + +ICON_NEW = "./img/icons8-new-file-32.png" +ICON_OPEN = "./img/icons8-opened-folder-32.png" +ICON_SAVE = "./img/icons8-save-32.png" +ICON_EXPORT = "./img/icons8-export-xls-32.png" +ICON_ABOUT = "./img/icons8-information-32.png" +ICON_QUIT = "./img/system-shutdown.png" + +COL_STUFF = 0 +COL_LENGTH = 1 +COL_WIDTH = 2 +COL_HEIGHT = 3 +COL_WEIGHT = 4 + +STUFF_ROW_COUNT = 50 + +class MyMainWindow(QMainWindow): + def __init__(self): + super().__init__() + self.load_ui() + self.init_ui() + self.set_defaults() + self.connect_signals() + self.create_actions() + self.create_toolbar() + self.create_statusbar() + self.statusBar.showMessage(f"{APP_NAME} {APP_VERSION} by {APP_AUTHOR}", 7000) + self.calc_voluminae() + self.ui.efWeight.setText(str("0")) + self.modified = False + self.opened_file = None + + def load_ui(self): + loader = QUiLoader() + path = os.path.join(os.path.dirname(__file__), UI_FILE) + ui_file = QFile(path) + ui_file.open(QFile.ReadOnly) + self.ui = loader.load(ui_file, self) + ui_file.close() + + # self.headers = self.ui.tableStuff.horizontalHeader() + self.headers = self.ui.tableStuff.verticalHeader() + self.headers.setContextMenuPolicy(Qt.CustomContextMenu) + self.headers.customContextMenuRequested.connect(self.show_rowheader_context_menu) + self.headers.setSelectionMode(QAbstractItemView.SingleSelection) + + def create_actions(self): + self.actionNew = QAction() + self.actionNew.setIcon(QIcon(ICON_NEW)) + self.actionNew.triggered.connect(self.file_new) + self.actionNew.setShortcut("Ctrl+N") + self.actionNew.setToolTip("Neu (Strg+N)") + + self.actionOpen = QAction() + self.actionOpen.setIcon(QIcon(ICON_OPEN)) + self.actionOpen.triggered.connect(self.file_open) + self.actionOpen.setShortcut("Ctrl+O") + self.actionOpen.setToolTip("Öffnen... (Strg+O)") + + self.actionSave = QAction() + self.actionSave.setIcon(QIcon(ICON_SAVE)) + self.actionSave.triggered.connect(self.file_save) + self.actionSave.setShortcut("Ctrl+S") + self.actionSave.setToolTip("Speichern (Strg+S)") + + self.actionExport = QAction() + self.actionExport.setIcon(QIcon(ICON_EXPORT)) + self.actionExport.triggered.connect(self.file_export) + self.actionExport.setToolTip("Export nach EXCEL...") + + self.actionAbout = QAction() + self.actionAbout.setIcon(QIcon(ICON_ABOUT)) + self.actionAbout.triggered.connect(show_about) + self.actionAbout.setToolTip("Informationen über das Programm") + + self.actionQuit = QAction() + self.actionQuit.setIcon(QIcon(ICON_QUIT)) + self.actionQuit.triggered.connect(QApplication.quit) + self.actionQuit.setShortcut("Ctrl+Q") + self.actionQuit.setToolTip("Programm beenden (Strg+Q)") + + def create_toolbar(self): + # Main Toolbar (for all pages/views) + self.toolbar = self.addToolBar('Main Toolbar') + self.toolbar.setIconSize(QSize(32, 32)) + self.toolbar.addAction(self.actionNew) + self.toolbar.addAction(self.actionOpen) + self.toolbar.addAction(self.actionSave) + self.toolbar.addSeparator() + self.toolbar.addAction(self.actionExport) + self.toolbar.addSeparator() + self.toolbar.addAction(self.actionAbout) + self.toolbar.addSeparator() + self.toolbar.addAction(self.actionQuit) + + def set_defaults(self): + tblGarage = self.ui.tableGarage + tblStuff = self.ui.tableStuff + + tblGarage.setItem(0, 0, QTableWidgetItem("6")) + tblGarage.setItem(0, 1, QTableWidgetItem("2.5")) + tblGarage.setItem(0, 2, QTableWidgetItem("2.5")) + + tblStuff.setRowCount(STUFF_ROW_COUNT) + + self.modified = False + + def create_statusbar(self): + self.statusBar = QStatusBar() + self.setStatusBar(self.statusBar) + + def connect_signals(self): + tblGarage = self.ui.tableGarage + tblStuff = self.ui.tableStuff + + tblGarage.itemChanged.connect(self.on_garage_changed) + tblStuff.itemChanged.connect(self.on_stuff_changed) + + def show_rowheader_context_menu(self, position): + tblStuff = self.ui.tableStuff + row = self.headers.logicalIndexAt(position) + print("row click", row) + + menu = QMenu() + remove_row = menu.addAction("Zeile entfernen") + insert_row = menu.addAction("Zeile einfügen") + ac = menu.exec_(tblStuff.mapToGlobal(position)) + if ac == remove_row: + tblStuff.removeRow(row) + self.calc_voluminae() + elif ac == insert_row: + tblStuff.insertRow(row) + + def init_ui(self): + tblGarage = self.ui.tableGarage + tblStuff = self.ui.tableStuff + + # clear garage + # tblGarage.clear() + tblGarage.setRowCount(0) + tblGarage.setRowCount(1) + tblGarage.setVerticalHeaderLabels(["Garage"]) + + # clear stuff + # tblStuff.clear() + tblStuff.setRowCount(0) + tblStuff.setRowCount(STUFF_ROW_COUNT) + + # clear results + self.ui.efVol_Garage.clear() + self.ui.efVol_Stuff.clear() + self.ui.efVol_Free.clear() + self.ui.efWeight.clear() + + self.opened_file = None + if self.opened_file: + self.setWindowTitle(self.opened_file) + else: + self.setWindowTitle(f"{APP_NAME} {APP_VERSION} by {APP_AUTHOR}") + + self.ui.efVol_Free.setStyleSheet("") + self.modified = False + + def file_new(self): + if self.modified: + msg = "Es wurden bereits Einträge manuell geändert. Ohne Speichern sind alle Änderungen verloren. Trotzdem fortfahren?" + reply = QMessageBox.question(self, "Fortfahren?", msg, \ + QMessageBox.Yes | QMessageBox.No, QMessageBox.Yes) + if reply == QMessageBox.No: + return False + self.init_ui() + + def file_save(self): + print("file_save() called.") + tblGarage = self.ui.tableGarage + tblStuff = self.ui.tableStuff + + fileName = self.opened_file + + if not self.opened_file: # if not file already open + options = QFileDialog.Options() + + sTxtFilesAll = "Alle Dateien" + sTxtFiles = "CSV-Datei" + + fileName, _ = QFileDialog.getSaveFileName(None, "Speichern", None, + sTxtFiles + " (*.csv);;" + sTxtFilesAll + " (*)", + options=options) + + with open(fileName, mode='w', newline='') as garagecalc_file: + writer = csv.writer(garagecalc_file, delimiter=';', quotechar='"', quoting=csv.QUOTE_MINIMAL) + + garage_length = 0 + garage_width = 0 + garage_height = 0 + + item_length = tblGarage.item(0, 0) + item_width = tblGarage.item(0, 1) + item_height = tblGarage.item(0, 2) + + # loop over table Garage + for row in range(tblGarage.rowCount()): + # get garage length + if item_length: + garage_length = item_length.text() + try: + garage_length = float(garage_length) + except ValueError: + garage_length = 0.0 + + # get garage width + if item_width: + garage_width = item_width.text() + try: + garage_width = float(garage_width) + except ValueError: + garage_width = 0.0 + + # get garage height + if item_height: + garage_height = item_height.text() + try: + garage_height = float(garage_height) + except ValueError: + garage_height = 0.0 + + if garage_length or garage_width or garage_height: + writer.writerow(["Garage", garage_length, garage_width, garage_height]) + + # loop over table Stuff + for row in range(tblStuff.rowCount()): + stuff_text = None + length = None + width = None + height = None + weight = None + + item_stuff = tblStuff.item(row, COL_STUFF) + item_length = tblStuff.item(row, COL_LENGTH) + item_width = tblStuff.item(row, COL_WIDTH) + item_height = tblStuff.item(row, COL_HEIGHT) + item_weight = tblStuff.item(row, COL_WEIGHT) + + if item_stuff: + stuff_text = item_stuff.text() + + if item_length: + try: + length = float(item_length.text()) + except ValueError: + length = None + + if item_width: + try: + width = float(item_width.text()) + except ValueError: + width = None + + if item_height: + try: + height = float(item_height.text()) + except ValueError: + height = None + + if item_weight: + try: + weight = float(item_weight.text()) + except ValueError: + weight = None + + if item_stuff or item_length or item_width or item_height or item_weight: + writer.writerow([stuff_text, length, width, height, weight]) + + self.opened_file = os.path.basename(fileName) + self.setWindowTitle(self.opened_file) + self.modified = False + + def file_open(self): + if self.modified: + msg = "Es wurden bereits Einträge manuell geändert. Ohne Speichern sind alle Änderungen verloren. Trotzdem fortfahren?" + reply = QMessageBox.question(self, "Fortfahren?", msg, \ + QMessageBox.Yes | QMessageBox.No, QMessageBox.Yes) + if reply == QMessageBox.No: + return False + + tblGarage = self.ui.tableGarage + tblStuff = self.ui.tableStuff + + options = QFileDialog.Options() + + sTxtFilesAll = "Alle Dateien" + sTxtFiles = "CSV-Datei" + + fileName, _ = QFileDialog.getOpenFileName(self, "Öffnen", None, + sTxtFiles + " (*.csv);;" + sTxtFilesAll + " (*)", + options=options) + if fileName: + self.init_ui() + + file = open(fileName, "rU") + reader = csv.reader(file, delimiter=';') + + row_idx = 0 + for row in reader: + if row_idx == 0: # first row (index=0) ist always garage dimension + try: + garage_length = row[1] + garage_width = row[2] + garage_height = row[3] + print("garage_length", garage_length) + print("garage_width", garage_width) + print("garage_height", garage_height) + + tblGarage.setItem(0, COL_LENGTH-1, QTableWidgetItem(str(garage_length))) + tblGarage.setItem(0, COL_WIDTH-1, QTableWidgetItem(str(garage_width))) + tblGarage.setItem(0, COL_HEIGHT-1, QTableWidgetItem(str(garage_height))) + + except IndexError as ex: + pass + print("") + if row_idx > 0: + try: + stuff = row[0] + stuff_length = row[1] + stuff_width = row[2] + stuff_height = row[3] + stuff_weight = row[4] + print("stuff", stuff) + print("length", stuff_length) + print("width", stuff_width) + print("height", stuff_height) + print("weight", stuff_weight) + + tblStuff.setItem(row_idx - 1, COL_STUFF, QTableWidgetItem(stuff)) + tblStuff.setItem(row_idx - 1, COL_LENGTH, QTableWidgetItem(str(stuff_length))) + tblStuff.setItem(row_idx - 1, COL_WIDTH, QTableWidgetItem(str(stuff_width))) + tblStuff.setItem(row_idx - 1, COL_HEIGHT, QTableWidgetItem(str(stuff_height))) + tblStuff.setItem(row_idx - 1, COL_WEIGHT, QTableWidgetItem(str(stuff_weight))) + + except IndexError as ex: + pass + + row_idx += 1 + + tblStuff.setRowCount(STUFF_ROW_COUNT) + + self.modified = False + self.opened_file = os.path.basename(fileName) + + if fileName: + self.setWindowTitle(self.opened_file) + else: + self.setWindowTitle(f"{APP_NAME} {APP_VERSION} by {APP_AUTHOR}") + + def file_export(self): + tblGarage = self.ui.tableGarage + tblStuff = self.ui.tableStuff + options = QFileDialog.Options() + file_name, _ = QFileDialog.getSaveFileName(None, "Exportieren", None, "Excel-Datei (*.xlsx);;Alle Dateien (*)", options=options) + if file_name: + try: + import xlsxwriter + except ModuleNotFoundError: + print(f"[{__file__}] Module 'xlsxwriter' not found!") + else: + print(f"Exporting into file -> {file_name}") + + workbook = xlsxwriter.Workbook(file_name) + worksheet = workbook.add_worksheet() + + # write col header + start_row = 0 + worksheet.write(start_row, 0, "Dimension der Garage") + + start_row = 1 + worksheet.write(start_row, COL_LENGTH, "Länge [m]") + worksheet.write(start_row, COL_WIDTH, "Breite [m]") + worksheet.write(start_row, COL_HEIGHT, "Höhe [m]") + worksheet.set_column(0, 0, 25) + worksheet.set_column(1, 3, 10) + + start_row = 2 + # loop over table Garage + for row in range(tblGarage.rowCount()): + # get garage length + garage_length = tblGarage.item(0, 0).text() + try: + garage_length = float(garage_length) + except ValueError: + garage_length = 0.0 + + # get garage width + garage_width = tblGarage.item(0, 1).text() + try: + garage_width = float(garage_width) + except ValueError: + garage_width = 0.0 + + # get garage height + garage_height = tblGarage.item(0, 2).text() + try: + garage_height = float(garage_height) + except ValueError: + garage_height = 0.0 + + worksheet.write(start_row + row, COL_LENGTH, garage_length) + worksheet.write(start_row + row, COL_WIDTH, garage_width) + worksheet.write(start_row + row, COL_HEIGHT, garage_height) + + start_row = 4 + worksheet.write(start_row, 0, "Dimensionen der zu verstaueneden Gegenstände") + + start_row = 5 + worksheet.write(start_row, COL_LENGTH, "Länge [m]") + worksheet.write(start_row, COL_WIDTH, "Breite [m]") + worksheet.write(start_row, COL_HEIGHT, "Höhe [m]") + worksheet.write(start_row, COL_WEIGHT, "Gewicht [kg]") + + start_row = 6 + # loop over table Stuff + row_idx = start_row + for row in range(tblStuff.rowCount()): + item_stuff = tblStuff.item(row, COL_STUFF) + item_length = tblStuff.item(row, COL_LENGTH) + item_width = tblStuff.item(row, COL_WIDTH) + item_height = tblStuff.item(row, COL_HEIGHT) + item_weight = tblStuff.item(row, COL_WEIGHT) + + if item_stuff: + stuff_text = item_stuff.text() + if len(stuff_text)>0: + worksheet.write(start_row + row, COL_STUFF, stuff_text) + + if item_length: + try: + length = float(item_length.text()) + if length: + worksheet.write(start_row + row, COL_LENGTH, length) + except ValueError: + pass + + if item_width: + try: + width = float(item_width.text()) + if width: + worksheet.write(start_row + row, COL_WIDTH, width) + except ValueError: + pass + + if item_height: + try: + height = float(item_height.text()) + if height: + worksheet.write(start_row + row, COL_HEIGHT, height) + except ValueError: + pass + + if item_weight: + try: + weight = float(item_weight.text()) + if weight: + worksheet.write(start_row + row, COL_WEIGHT, weight) + except ValueError: + pass + + if item_stuff or item_length or item_width or item_height or item_weight: + row_idx += 1 + + row_idx += 1 + # loop over Results + worksheet.write(row_idx, 0, "Ergebnis") + + row_idx += 1 + worksheet.write(row_idx, 0, "Volumen der Garage:") + worksheet.write(row_idx, 1, float(self.ui.efVol_Garage.text())) + + row_idx += 1 + worksheet.write(row_idx, 0, "Volumen der Gegenstände:") + worksheet.write(row_idx, 1, float(self.ui.efVol_Stuff.text())) + + row_idx += 1 + worksheet.write(row_idx, 0, "Freier Raum") + worksheet.write(row_idx, 1, float(self.ui.efVol_Free.text())) + + row_idx += 1 + worksheet.write(row_idx, 0, "Gesamtgewicht") + worksheet.write(row_idx, 1, float(self.ui.efWeight.text())) + + workbook.close() + self.statusBar.showMessage(f"Erfolgreich nach EXCEL exportiert.", 7000) + + def on_garage_changed(self): + self.modified = True + self.calc_voluminae() + + def on_stuff_changed(self): + self.modified = True + self.calc_voluminae() + self.calc_weight() + + def get_garage_vol(self): + tblGarage = self.ui.tableGarage + is_error = False + + garage_length = 0 + garage_width = 0 + garage_height = 0 + + # get garage length + if tblGarage.item(0, 0): + garage_length = tblGarage.item(0, 0).text() + if garage_length: + try: + garage_length = float(garage_length) + except ValueError: + garage_length = 0.0 + is_error = True + + # get garage width + if tblGarage.item(0, 1): + garage_width = tblGarage.item(0, 1).text() + if garage_width: + try: + garage_width = float(garage_width) + except ValueError: + garage_width = 0.0 + is_error = True + + # get garage height + if tblGarage.item(0, 2): + garage_height = tblGarage.item(0, 2).text() + if garage_height: + try: + garage_height = float(garage_height) + except ValueError: + garage_height = 0.0 + is_error = True + + if not is_error: + garage_vol = garage_length * float(garage_width) * float(garage_height) + else: + garage_vol = 0.0 + self.statusBar.showMessage("Fehler in der Garagen-Dimension. :-(", 7000) + + return garage_vol + + def get_stuff_vol(self): + tblStuff = self.ui.tableStuff + stuff_vol = 0 + length = 0 + width = 0 + height = 0 + # get number of rows + row_count = tblStuff.rowCount() + + is_error = False + + # get stuff voluminae + for row in range(row_count): + vol = 0 + length = 0 + width = 0 + height = 0 + item_length = tblStuff.item(row, COL_LENGTH) + item_width = tblStuff.item(row, COL_WIDTH) + item_height = tblStuff.item(row, COL_HEIGHT) + + if item_length: + try: + length = float(item_length.text()) + except ValueError: + length = 0 + is_error = True + + if item_width: + try: + width = float(item_width.text()) + except ValueError: + width = 0 + is_error = True + + if item_height: + try: + height = float(item_height.text()) + except ValueError: + height = 0 + is_error = True + + vol = length * width * height + + stuff_vol = stuff_vol + vol + + if is_error: + stuff_vol = 0.0 + self.statusBar.showMessage("Fehler in den Gegenstände-Dimensionen. :-(", 7000) + + return stuff_vol + + def calc_voluminae(self): + print("calc_voluminae() called.") + tblGarage = self.ui.tableGarage + + # get garage vol + garage_vol = self.get_garage_vol() + + # get stuff vol + stuff_vol = self.get_stuff_vol() + + # display results + self.ui.efVol_Garage.setText(str(garage_vol)) + self.ui.efVol_Stuff.setText(str(stuff_vol)) + self.ui.efVol_Free.setText(str(garage_vol - stuff_vol)) + + if ( garage_vol - stuff_vol ) < 0: + self.ui.efVol_Free.setStyleSheet("border: 1px solid red;") + else: + self.ui.efVol_Free.setStyleSheet("") + + def calc_weight(self): + tblStuff = self.ui.tableStuff + weight_sum = 0 + + # get number of rows + row_count = tblStuff.rowCount() + + for row in range(row_count): + weight = 0.0 + item = tblStuff.item(row, COL_WEIGHT) + if item: + try: + weight = float(item.text()) + except ValueError: + weight = 0.0 + + weight_sum = weight_sum + weight + + self.ui.efWeight.setText(str(weight_sum)) + + +if __name__ == "__main__": + qApp = QApplication([]) + + qApp.setApplicationName(APP_NAME) + qApp.setApplicationDisplayName(APP_DISPNAME) + qApp.setApplicationVersion(APP_VERSION) + qApp.description = APP_DESCR + qApp.copyright = APP_COPYRIGHT + qApp.website = APP_WEBSITE + qApp.setWindowIcon(QIcon(APP_ICON)) + qApp.setDesktopFileName(APP_DESKTOPFILENAME) + + winMain = MyMainWindow() + # winMain.resize(600, 600) + winMain.setFixedWidth(600) + winMain.setFixedHeight(620) + winMain.show() + sys.exit(qApp.exec_()) diff --git a/main.ui b/main.ui new file mode 100644 index 0000000..c8bdd36 --- /dev/null +++ b/main.ui @@ -0,0 +1,334 @@ + + + Form + + + + 0 + 0 + 604 + 596 + + + + Form + + + + + 20 + 440 + 541 + 121 + + + + Ergebnis + + + true + + + + + 10 + 20 + 140 + 16 + + + + Volumen der Garage: + + + + + + 10 + 40 + 140 + 16 + + + + Volumen der Gegenstände: + + + + + + 10 + 60 + 140 + 16 + + + + Freier Raum i. d. Garage: + + + + + + 174 + 20 + 113 + 20 + + + + Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter + + + true + + + + + + 174 + 40 + 113 + 20 + + + + Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter + + + true + + + + + + 174 + 60 + 113 + 20 + + + + Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter + + + true + + + + + + 294 + 20 + 47 + 13 + + + + + + + + + + 294 + 40 + 47 + 13 + + + + + + + + + + 294 + 60 + 47 + 13 + + + + + + + + + + 174 + 80 + 113 + 20 + + + + Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter + + + true + + + + + + 294 + 80 + 47 + 13 + + + + kg + + + + + + 10 + 80 + 140 + 16 + + + + Gesamtgewicht: + + + + + + + 20 + 120 + 561 + 301 + + + + Dimensionen der zu verstauenden Gegenstände + + + true + + + + + + + 0 + 0 + + + + true + + + QAbstractItemView::NoSelection + + + + Gegenstand + + + + + Länge [m] + + + + + Breite [m] + + + + + Höhe [m] + + + + + Gewicht [kg] + + + + + + + + + + 20 + 20 + 561 + 91 + + + + + 0 + 91 + + + + Dimension der Garage + + + true + + + + + 10 + 23 + 351 + 58 + + + + + 0 + 0 + + + + + 0 + 58 + + + + + Garage + + + + + Länge [m] + + + + + Breite [m] + + + + + Höhe [m] + + + + + + + tableGarage + tableStuff + efVol_Garage + efVol_Stuff + efVol_Free + efWeight + + + + diff --git a/utils.py b/utils.py new file mode 100644 index 0000000..f58f05f --- /dev/null +++ b/utils.py @@ -0,0 +1,43 @@ +#!/usr/bin/env python3 +""" +project: GarageCalc1 +file: utils.py +summary: helper functions +""" + +# Standard library imports +import sys +import os + +# Third party imports +from PySide2.QtWidgets import QMessageBox, QApplication, QMainWindow, QTableWidgetItem, QStatusBar, QAction +from PySide2 import QtCore +from PySide2.QtGui import QIcon, QPixmap +from PySide2.QtCore import QFile, QSize +from PySide2.QtUiTools import QUiLoader + +# local globals +APP_ICON = "icons8-garage-32.png" + +def show_about(): + msg = QMessageBox() + msg.setIconPixmap(QPixmap(APP_ICON)) + + text = "

" + qApp.applicationDisplayName() + " " + \ + "
" + qApp.applicationVersion() + "

" + \ + "
" + qApp.applicationName() + "
" + \ + "
" + qApp.description + "
" + \ + "
" + "Idee von: Balazs Fabian" + "
" + \ + "
" + qApp.copyright + "
" \ + "
" + qApp.website + "

" + + text = text + "

Used icons: Theme 'Cute Color' from Icons8

" + text = text + "

Python version: " + f"{sys.version_info.major}.{sys.version_info.minor}.{sys.version_info.micro} {sys.version_info.releaselevel}" + text = text + "
" + f"{sys.executable}" + "
" + text = text + "
Qt version: " + f"{QtCore.__version__}" + + msg.setText(text) + msg.setWindowTitle("About") + msg.setStandardButtons(QMessageBox.Ok) + + msg.exec_()