first version
BIN
img/icons8-export-xls-32.png
Normal file
After Width: | Height: | Size: 703 B |
BIN
img/icons8-garage-32.png
Normal file
After Width: | Height: | Size: 950 B |
BIN
img/icons8-information-32.png
Normal file
After Width: | Height: | Size: 699 B |
BIN
img/icons8-new-file-32.png
Normal file
After Width: | Height: | Size: 994 B |
BIN
img/icons8-opened-folder-32.png
Normal file
After Width: | Height: | Size: 774 B |
BIN
img/icons8-save-32.png
Normal file
After Width: | Height: | Size: 839 B |
BIN
img/system-shutdown.png
Normal file
After Width: | Height: | Size: 883 B |
692
main.py
Normal file
|
@ -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_())
|
334
main.ui
Normal file
|
@ -0,0 +1,334 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<ui version="4.0">
|
||||
<class>Form</class>
|
||||
<widget class="QWidget" name="Form">
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>0</x>
|
||||
<y>0</y>
|
||||
<width>604</width>
|
||||
<height>596</height>
|
||||
</rect>
|
||||
</property>
|
||||
<property name="windowTitle">
|
||||
<string>Form</string>
|
||||
</property>
|
||||
<widget class="QGroupBox" name="gbResults">
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>20</x>
|
||||
<y>440</y>
|
||||
<width>541</width>
|
||||
<height>121</height>
|
||||
</rect>
|
||||
</property>
|
||||
<property name="title">
|
||||
<string>Ergebnis</string>
|
||||
</property>
|
||||
<property name="flat">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
<widget class="QLabel" name="lblVol_Garage">
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>10</x>
|
||||
<y>20</y>
|
||||
<width>140</width>
|
||||
<height>16</height>
|
||||
</rect>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>Volumen der Garage:</string>
|
||||
</property>
|
||||
</widget>
|
||||
<widget class="QLabel" name="lblVol_Stuff">
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>10</x>
|
||||
<y>40</y>
|
||||
<width>140</width>
|
||||
<height>16</height>
|
||||
</rect>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>Volumen der Gegenstände:</string>
|
||||
</property>
|
||||
</widget>
|
||||
<widget class="QLabel" name="lblVol_Free">
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>10</x>
|
||||
<y>60</y>
|
||||
<width>140</width>
|
||||
<height>16</height>
|
||||
</rect>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>Freier Raum i. d. Garage:</string>
|
||||
</property>
|
||||
</widget>
|
||||
<widget class="QLineEdit" name="efVol_Garage">
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>174</x>
|
||||
<y>20</y>
|
||||
<width>113</width>
|
||||
<height>20</height>
|
||||
</rect>
|
||||
</property>
|
||||
<property name="alignment">
|
||||
<set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
|
||||
</property>
|
||||
<property name="readOnly">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
</widget>
|
||||
<widget class="QLineEdit" name="efVol_Stuff">
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>174</x>
|
||||
<y>40</y>
|
||||
<width>113</width>
|
||||
<height>20</height>
|
||||
</rect>
|
||||
</property>
|
||||
<property name="alignment">
|
||||
<set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
|
||||
</property>
|
||||
<property name="readOnly">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
</widget>
|
||||
<widget class="QLineEdit" name="efVol_Free">
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>174</x>
|
||||
<y>60</y>
|
||||
<width>113</width>
|
||||
<height>20</height>
|
||||
</rect>
|
||||
</property>
|
||||
<property name="alignment">
|
||||
<set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
|
||||
</property>
|
||||
<property name="readOnly">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
</widget>
|
||||
<widget class="QLabel" name="lblM3">
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>294</x>
|
||||
<y>20</y>
|
||||
<width>47</width>
|
||||
<height>13</height>
|
||||
</rect>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>m³</string>
|
||||
</property>
|
||||
</widget>
|
||||
<widget class="QLabel" name="lblM3_2">
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>294</x>
|
||||
<y>40</y>
|
||||
<width>47</width>
|
||||
<height>13</height>
|
||||
</rect>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>m³</string>
|
||||
</property>
|
||||
</widget>
|
||||
<widget class="QLabel" name="lblM3_3">
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>294</x>
|
||||
<y>60</y>
|
||||
<width>47</width>
|
||||
<height>13</height>
|
||||
</rect>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>m³</string>
|
||||
</property>
|
||||
</widget>
|
||||
<widget class="QLineEdit" name="efWeight">
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>174</x>
|
||||
<y>80</y>
|
||||
<width>113</width>
|
||||
<height>20</height>
|
||||
</rect>
|
||||
</property>
|
||||
<property name="alignment">
|
||||
<set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
|
||||
</property>
|
||||
<property name="readOnly">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
</widget>
|
||||
<widget class="QLabel" name="lblM3_4">
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>294</x>
|
||||
<y>80</y>
|
||||
<width>47</width>
|
||||
<height>13</height>
|
||||
</rect>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>kg</string>
|
||||
</property>
|
||||
</widget>
|
||||
<widget class="QLabel" name="lblVol_Free_2">
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>10</x>
|
||||
<y>80</y>
|
||||
<width>140</width>
|
||||
<height>16</height>
|
||||
</rect>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>Gesamtgewicht:</string>
|
||||
</property>
|
||||
</widget>
|
||||
</widget>
|
||||
<widget class="QGroupBox" name="gbStuff">
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>20</x>
|
||||
<y>120</y>
|
||||
<width>561</width>
|
||||
<height>301</height>
|
||||
</rect>
|
||||
</property>
|
||||
<property name="title">
|
||||
<string>Dimensionen der zu verstauenden Gegenstände</string>
|
||||
</property>
|
||||
<property name="flat">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
<layout class="QVBoxLayout" name="verticalLayout">
|
||||
<item>
|
||||
<widget class="QTableWidget" name="tableStuff">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Preferred" vsizetype="Preferred">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<property name="alternatingRowColors">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
<property name="selectionMode">
|
||||
<enum>QAbstractItemView::NoSelection</enum>
|
||||
</property>
|
||||
<column>
|
||||
<property name="text">
|
||||
<string>Gegenstand</string>
|
||||
</property>
|
||||
</column>
|
||||
<column>
|
||||
<property name="text">
|
||||
<string>Länge [m]</string>
|
||||
</property>
|
||||
</column>
|
||||
<column>
|
||||
<property name="text">
|
||||
<string>Breite [m]</string>
|
||||
</property>
|
||||
</column>
|
||||
<column>
|
||||
<property name="text">
|
||||
<string>Höhe [m]</string>
|
||||
</property>
|
||||
</column>
|
||||
<column>
|
||||
<property name="text">
|
||||
<string>Gewicht [kg]</string>
|
||||
</property>
|
||||
</column>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
<widget class="QGroupBox" name="gbGarage">
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>20</x>
|
||||
<y>20</y>
|
||||
<width>561</width>
|
||||
<height>91</height>
|
||||
</rect>
|
||||
</property>
|
||||
<property name="minimumSize">
|
||||
<size>
|
||||
<width>0</width>
|
||||
<height>91</height>
|
||||
</size>
|
||||
</property>
|
||||
<property name="title">
|
||||
<string>Dimension der Garage</string>
|
||||
</property>
|
||||
<property name="flat">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
<widget class="QTableWidget" name="tableGarage">
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>10</x>
|
||||
<y>23</y>
|
||||
<width>351</width>
|
||||
<height>58</height>
|
||||
</rect>
|
||||
</property>
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Preferred" vsizetype="Minimum">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<property name="minimumSize">
|
||||
<size>
|
||||
<width>0</width>
|
||||
<height>58</height>
|
||||
</size>
|
||||
</property>
|
||||
<row>
|
||||
<property name="text">
|
||||
<string>Garage</string>
|
||||
</property>
|
||||
</row>
|
||||
<column>
|
||||
<property name="text">
|
||||
<string>Länge [m]</string>
|
||||
</property>
|
||||
</column>
|
||||
<column>
|
||||
<property name="text">
|
||||
<string>Breite [m]</string>
|
||||
</property>
|
||||
</column>
|
||||
<column>
|
||||
<property name="text">
|
||||
<string>Höhe [m]</string>
|
||||
</property>
|
||||
</column>
|
||||
</widget>
|
||||
</widget>
|
||||
</widget>
|
||||
<tabstops>
|
||||
<tabstop>tableGarage</tabstop>
|
||||
<tabstop>tableStuff</tabstop>
|
||||
<tabstop>efVol_Garage</tabstop>
|
||||
<tabstop>efVol_Stuff</tabstop>
|
||||
<tabstop>efVol_Free</tabstop>
|
||||
<tabstop>efWeight</tabstop>
|
||||
</tabstops>
|
||||
<resources/>
|
||||
<connections/>
|
||||
</ui>
|
43
utils.py
Normal file
|
@ -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 = "<p align='center'><h1>" + qApp.applicationDisplayName() + " " + \
|
||||
"<br>" + qApp.applicationVersion() + "</h1>" + \
|
||||
"<br>" + qApp.applicationName() + "<br>" + \
|
||||
"<br>" + qApp.description + "<br>" + \
|
||||
"<br>" + "Idee von: Balazs Fabian" + "<br>" + \
|
||||
"<br>" + qApp.copyright + "<br>" \
|
||||
"<br> <a href='" + qApp.website + "'>" + qApp.website + "</a></p>"
|
||||
|
||||
text = text + "<p align='center'>Used icons: Theme 'Cute Color' from <a href='https://icons8.com/'>Icons8</a></p>"
|
||||
text = text + "<p align='center'>Python version: " + f"{sys.version_info.major}.{sys.version_info.minor}.{sys.version_info.micro} {sys.version_info.releaselevel}"
|
||||
text = text + "<br>" + f"{sys.executable}" + "<br>"
|
||||
text = text + "<br>Qt version: " + f"{QtCore.__version__}"
|
||||
|
||||
msg.setText(text)
|
||||
msg.setWindowTitle("About")
|
||||
msg.setStandardButtons(QMessageBox.Ok)
|
||||
|
||||
msg.exec_()
|