• Hallo Gast, du kaufst gerne günstig ein und erfährst oft vor deinen Freunden von interessanten Angeboten? Dann kannst du dein Talent als Schnäppchenjäger jetzt zu Geld machen und anderen PCGH-Lesern beim Sparen helfen! Schau einfach mal rein - beim Test der Community Deals!

[Tagebuch] Warenwirtschaftssystem für Zuhause

taks

PCGH-Community-Veteran(in)
#Vorwort

Willkommen zu meinem ersten Raspi Projekt :-)
Das Projekt ist in meinem Kopf schon länger in Planung und wird nun endlich umgesetzt. Das Ganze will ich hier in schriftlicher Form festhalten da ich zum einen gerne hier durch die Tagebücher stöbere und nun etwas zurückgeben will. Zum Anderen hoffe ich selbst die Übersicht über das Projekt ein bisschen besser behalten zu können. Da ich von Berufswegen mit Softwareentwicklung zu tun habe und als Hobby gerne an Sachen herumbastle sollte das Projekt eigentlich ohne grössere Probleme umsetzbar sein. Ob es wirklich so ist wird sich hier im Tagebuch mit der Zeit zeigen ^^

Ich wünsche euch viel Spass beim Lesen und immer her mit euren Meinungen, Ideen und Einwänden.


#Projektvorstellung

Problem & Lösung
Der Grund für das Projekt ist die momentane, unübersichtliche Verwaltung unseren Vorräte im Keller. Da wir viele Dinge auf Vorrat kaufen wenn diese reduzierte Preise haben hat unser Vorrat doch eine gewisse Grösse erreicht welche wir ohne Hilfsmittel nicht mehr übersehen. Dazu kommt, dass wir nächstes Jahr umziehen und einen grösseren Keller haben werden :ugly:
Deshalb ist mein Ziel ein Warenwirtschaftssystem zu entwickeln mit welchem wir unsere Vorräte im Überblick haben. Dazu werden die Vorräte per Strichcode eingescannt und dann auf einem Raspi mit Display verwaltet. Dazu kommen dann eventuell Erweiterungen wie das Ablaufdatum überwachen, etc. Das Projekt soll bis Weihnachten fertig, oder zumindest Einsatzfähig sein da es das Weihnachtsgeschenk für meine Freundin wird. Sie schwärmt schon längere Zeit davon einen eigenen "Laden" im Keller zu haben ^^


Hardware
Das System basiert auf einem Raspberry PI 4 als Rechner, einem 7" Touchscreen als Benutzerschnittstelle und einem Barcodescanner zum Erfassen bzw. Austragen der Produkte.

Raspberry Pi 4 4G Model B
Raspberry Pi 7" Touch Screen
Raspberry Pi Official Raspberry Pi 4 Power
Sandisk Ultra microSD A1 (microSDHC, 16GB, U1, UHS-I)
Datalogic Quickscan Lite Imager Kit

Um die Benutzung ergonomischer zu gestalten wird alles in einem Holzgehäuse untergebracht welches auch einen Halter für den Barcodescanner integriert hat. Eine ungefähre Idee dazu ist schon vorhanden, jedoch muss ich dann erstmal ein bisschen mit dem System arbeiten um zu sehen ob meine Idee auch in der Praxis besteht. Die Konstruktion soll aber möglichst simpel sein und wird aus einem angewinkelten Brett bestehen in welchen das Display eingelassen ist, sowie zwei Seitenwänden und noch ein paar Blenden um das Netzteil etc. zu Kaschieren. Dazu wird das Gehäuse am Schluss noch ansprechend lackiert.


Software (Projektname: Candy Shop)
Die Software wird durch mich in Python programmiert. Soweit zumindest der Plan. Ein paar Scripts habe ich schon mit Python geschrieben aber mit GUI und Datenbankanbindung hab ich zumindest mit Python noch keine Erfahrung. Ich bin dennoch zuversichtlich, da man für ziemlich alles ein Tutorial findet.

Die Software wird in folgende Punkte unterteilt:
- Grundfunktion: Programm Skeleton, die Grundfunktionalität zum Scannen von Strichcodes und die Datenbank-Anbindung sowie Datenbankstrukturen
- GUI: Die Benutzeroberfläche für die Vorratsverwaltung mit Steuerung über das Touchdisplay.
- Online Produktabgleich: Der gescannt Strichcode wiederspiegelt ja nur einen GS1-Code. So ist die Idee, damit wir nicht alle Produkte von Hand erfassen müssen, dass die Produktdaten via GS1-Code übers Internet gesucht werden um, falls noch nicht im System vorhanden, die Informationen ins System zu laden. (Hersteller, Produktname, Gewicht/Menge, etc.)
- Webserver mit Statistik: Um nicht jedesmal in den Keller laufen zu müssen um zu sehen welche Produkte auslaufen oder ablaufen kommt ein Webserver zum Einsatz, damit man vom Smartphone aus den Lagerbestand überprüfen kann.

Ich hab mir mittlerweile schon einige Python IDEs angeschaut und muss mich noch zwischen "Visual Studio Code" und "PyCharm" entscheiden. Wobei mir VS Code irgendwie besser gefällt. Habt ihr sonst noch Empfehlungen?


Herausforderungen
Die grösste Herausforderung wird sein, am Projekt zu Arbeiten ohne das die Freundin etwas mitbekommt :-D
Daneben das vertiefte Auseinandersetzen mit Python sowie Angewöhnung an Raspi mit Rasbian.


#Projektphasen

Das Projekt habe ich in verschiedene Phasen strukturiert welche für mich Sinn ergeben und das Projekt in kleinere Häppchen unterteilt. Ob die Phasen im Verlauf des Projekts angepasst werden kann ich noch nicht sagen. aber es ist gut möglich da ich mit Sicherheit etwas übersehen habe ^^

1. Raspi in Betrieb nehmen -> Abgeschlossen
2. Python Skeleton erstellen -> Abgeschlossen
3. Scanfunktion implementieren -> Abgeschlossen
4. Datenbank einrichten -> Abgeschlossen
5. Datenbankstruktur aufbauen -> Abgeschlossen
6. Scan in Datenbank ablegen -> Abgeschlossen
7. Benutzeroberfläche für Python -> Abgeschlossen
8. Online Produktabgleich/-vorschlag -> Abgeschlossen

9. Gehäuse anfertigen -> In Arbeit
10. Webserver einrichten
11. Webseite Skeleton erstellen
12. Datenbankanbindung für Webseite
13. Webseite erweitern


#Inhaltsverzeichnis

1. Lieferung & Auspacken
2. IDE Auswahl (Kurz Update)
3. Run Raspi Run
4. Code & Scan
5. Erster GUI Entwurf (Kurz Update)
6. Programm-Skeleton (TNotebook)
7. Programm-Skeleton - Progress Incoming
8. Datenbank: Die Erste
9. GUI Refactoring: !#%?-ç(@!!
10. Gehäuse Teil 1
11. Webabfrage & weitere Funktionen
12. Gehäuse Teil 2
 
Zuletzt bearbeitet:
TE
taks

taks

PCGH-Community-Veteran(in)
1. Lieferung & Auspacken

Dann mal los mit dem ersten Beitrag :bier:

Nachdem das Paket nach einer Rundreise durch die Schweiz (schon mal ein guter Start wenn die Post nicht einmal die Postleitzahl richtig lesen kann ^^) endlich angekommen ist gehts ans auspacken =)
Paketverfolgung.png


Hier mal eine kleine Übersicht des Pakets:
IMG_20200925_115528.jpg


IMG_20200925_115751.jpg


IMG_20200925_132038.jpg


IMG_20200925_132442.jpg


IMG_20200925_132538.jpg


IMG_20200925_120616.jpg

Dann hab ich mal zu Testzwecken den Strichcodescanner am PC angeschlossen. Ich bin wirklich überrascht wie gut und schnell er Strichcodes erkennt. Hab da glaub einen guten Kauf getätigt. Jetzt muss er nur noch mit dem Raspi zusammenarbeiten ^^

Der Zusammenbau von Raspi und Display ging fix und ohne Probleme, womit ich mich direkt dem Betriebsystem widmen kann.

IMG_20200925_173229.jpg


IMG_20200925_174331.jpg


Da setze ich wie schon geschrieben auf Rasbian (oder wie es neu heisst: "Raspberry Pi OS") in der aktuellsten Version. Ich hoffe das Display wird auch direkt erkannt (was eigentlich so sein sollte). Hier gibt es jedoch schon den ersten Stolperstein. Der **** Cardreader des Laptops macht keine Anstalten die SD-Karte zu erkennen. Auch ein Treiberupdate bringt keine Besserung. Darum muss mein alter USB-Cardreader herhalten welcher jedoch nicht im Büro sondern Zuhause ist... Darum erstmal nach Hause fahren und mit dem USB-Cardreader versuchen.

Ein paar Stunden und eine Mahlzeit später:
Einstecken und die SD-Karte wird erkannt. Was will man mehr :-)
IMG_20200925_212316.jpg


Der Raspberry Pi Imager verrichtet nun fleissig seinen Dienst.
Raspi_Imager.png


Und dann wars das glaub auch schon bis am Montag. Eigentlich wollte ich den Raspi soweit haben das ich Remote auf ihn zugreifen kann um von Zuhause aus daran zu arbeiten. Aber ohne Betriebssystem geht das nicht so recht -.-
Dafür hab ich jetzt übers Wochenende Zeit mich der IDE zu widmen. Vielleicht fange ich auch schon mit den ersten Schritten der Software an. Ich halte euch auf alle Fälle auf dem Laufenden :-)
 
Zuletzt bearbeitet:
TE
taks

taks

PCGH-Community-Veteran(in)
2. IDE Auswahl (Kurz Update)


Abend zusammen

Hatte übers Wochenende doch nicht soviel Zeit wie ich dachte. Ist irgendwie auf einmal Sonntag Abend -.-

Aber ich hab mich jetzt für VS Code entschieden. Da ich sonst schon mit Visual Studio arbeite liegt es mir glaub eher als PyCharm. Und es gibt ein hübsches Dark-Theme :-)

VSCode.png


Das wars eigentlich auch schon. Ich hab mir noch ein paar Tutorials mit tkinter als GUI angeschaut, was einen recht guten Eindruck macht. Dann starte ich Morgen mit der Inbetriebnahme des Raspi und hoffe das da alles glatt läuft.

Schönen Abend
 
Zuletzt bearbeitet:
TE
taks

taks

PCGH-Community-Veteran(in)
3. Run Raspi Run

Heute gings wie versprochen an die Inbetriebnahme des Raspi. SD-Karte rein, booten, er Läuft! :-)
Leider auf dem Kopf -.-
IMG_20200928_170502.jpg


Also den Bildschirm über die Anzeigensteuerung 180° gedreht.
IMG_20200928_171002.jpg


Sieht korrekt aus, ist es aber nicht. Die Touchsteuerung ist nicht gedreht -.- Aber mit einer kurzen Recherche ist das Problem auch gelöst. "lcd_rotate=2" in die config.txt eingeben, neustarten und alles klappt wie es soll :bier:
IMG_20200928_171059.jpg


Als Nächstes ist der Fernzugriff dran. Da ich von Zuhause aus daran Arbeiten will versuch ich es mit RDP. Dazu muss man nur einen kurzen Befehl in die Concole eingeben, installieren lassen und voila, RDP läuft. Auch der Zugriff von Zuhause über das VPN klappt problemlos.
IMG_20200928_171332.jpg


prntscrn.png


Das coole an der Geschichte, wenn ich mit RDP verbunden bin, kann ich unabhängig davon am Raspi arbeiten. Bin mir von Windows gewohnt, dass es mich abmeldet sobald ich mit RDP drauf zugreife ^^

Als letztes kommt noch die Hintergrundbeleuchtung des Displays dran. Da der Raspi über Nacht durchläuft will ich nicht, dass das Display die ganze Zeit leuchtet. Darum kurz nach dem richtigen Befehl gesucht, eingegeben und das Display wird dunkel :-)
backlight.png


Es ist fast beängstigend wenn alles so einfach klappt ^^ Aber man solls ja nicht verschreien *AufHolzKlopft* Das wars auch schon für Heute. Phase 1 ist erfolgreich abgeschlossen und ich bin zufrieden. Dann kann schon der Spass mit dem Programmieren beginnen 🎉

Schönen Abend euch allen
 
Zuletzt bearbeitet:

Edelrost-stahlfrei

Kabelverknoter(in)
Joar ... das schien schon einfach ... die Knüppel kommen vermutlich noch.
Habe mir mal deine Einkaufsliste angeschaut da ich noch an einer Möglichkeit zum Termin"Sharing" arbeite (MagicMirror war da mal eine Idee) .
Zum Hintergrund ... ich vergesse immer Termine und Aufgaben die innerhalb der Famile aufschlagen. Da wollte ich im Korridor mit einem Infoscreen Abhilfe schaffen welcher mir alle Aufgaben und Anforderungen interaktiv darstellt und Eingaben innerhalb der Domäne verarbeitet und mit Alarmen oder Ähnlichem erinnert ... bin halt vergesslich ^^
 
TE
taks

taks

PCGH-Community-Veteran(in)
Vermutlich kommen die noch ^^

Das mit dem Vergesslich sein ist eben ab einem gewissen Alter :-D
Aber MagicMirror hab ich mir auch schon angeschaut, habe nicht wirklich eine Verwendung dafür.
Aber ich würde nicht das 7" Display nehmen sondern einen gebrauchten ~17" Monitor über HDMI.
 

Edelrost-stahlfrei

Kabelverknoter(in)
Aber ich würde nicht das 7" Display nehmen sondern einen gebrauchten ~17" Monitor über HDMI.

Ich hatte auch eher an etwas noch größeres gedacht. So >=24"
Wollte eben alle Informationen des Tages anzeigen und bestimmte Services anbieten die das Leben vereinfachen. Termine vom Kindergarten und der Schule vom Großen inkl. Reminder, Arbeitszeiten der Frau, Einkaufsliste die man über die Woche befüllt und am Samstag automatisch aufs Mobiltelefon schickt, Beleuchtung und Musikwiedergabe planen ... naja, der Ganze fancy Kram eben :-]
 
TE
taks

taks

PCGH-Community-Veteran(in)
Dann ran an den Spass! :-)
Hier hats ein Tagebuch/Tutorial verlinkt welches ich recht gut fand:
 
TE
taks

taks

PCGH-Community-Veteran(in)
4. Code & Scan

Abend zusammen

Heute hab ich den Strichcodescanner am Raspi in Betrieb genommen. Nach dem Einstecken wurde er sofort erkannt und ich konnte direkt in eine Textdatei "schreiben" :-) Komischerweise funktioniert es nicht wenn ich den Scanner am Windows-PC anschliesse und per RDP am Windows-PC versuche in die Textdatei zu "schreiben". Das ist aber auch ned so tragisch da ich es später ned brauchen werde.
IMG_20200929_165936.jpg


IMG_20200929_165953.jpg


Daneben hab ich mich mit Python auseinander gesetzt und versucht den Scanner in eine Applikation ein zu binden. Gesagt getan, die Ausgabe am Bildschirm und das Schreiben in eine Datei funktioniert :hail: Ich bin sehr erleichtert das alles so klappt wie ich mir das vorgestellt habe. Hatte wirklich die Befürchtung, dass der Scanner am Raspi ned läuft und ich was anderes suchen muss.

PythonScanBarcode.png


PythonScanBarcodeTXT.png


Dazu hab ich mir noch ein paar Tutorials betreffend tkinter angesehen (zumindest Teile davon) und ich werf meine Phasenplanung glaub schonmal ein bisschen über den Haufen ^^ Anstelle getrennt eines nach dem Anderen ab zu arbeiten mach ich zuerst einen Quick&Dirty Entwurf und taste mich dann über Refactoring ans Ziel. Da ich Python noch zu wenig kenne scheint mir dieses Vorgehen irgendwie zielführender. Aber am grundlegenden Inhalt und Ablauf der Phasen ändert sich nichts. Ich widme mich zuerst dem Scanning damit ich die entsprechenden Klassen & Objekte erstellen kann, dann die Datenbank dazu um die Objekte ab zu legen und nebenläufig entsteht das GUI.

Hier noch das tkinter Tutorial was ich grad anschaue:
Recommented content - Youtube An dieser Stelle findest du externe Inhalte von Youtube. Zum Schutz deiner persönlichen Daten werden externe Einbindungen erst angezeigt, wenn du dies durch Klick auf "Alle externen Inhalte laden" bestätigst: Ich bin damit einverstanden, dass mir externe Inhalte angezeigt werden. Damit werden personenbezogene Daten an Drittplattformen übermittelt. For more information go to the privacy policy.


Gruss & einen schönen Abend
 
Zuletzt bearbeitet:

Olstyle

Moderator
Teammitglied
Hast du denn schon eine frei per Web-API ansprechbar Produktdatenbank gefunden? Da sehe ich das größte Schlagloch. Ansonsten wünsche ich viel Spaß und Erfolg.
 
TE
taks

taks

PCGH-Community-Veteran(in)
Hast du denn schon eine frei per Web-API ansprechbar Produktdatenbank gefunden? Da sehe ich das größte Schlagloch. Ansonsten wünsche ich viel Spaß und Erfolg.
Dankeschön, ich hoffe der Spass daran vergeht mir nicht ^^

Mit Vorbehalt, Ja.
Und zwar wäre das https://www.gtinsuche.de/ . Da kann man einfach in der URL die GTIN hinten Anhängen und es kommt die "Produkt-Seite" bei welcher man via HTML-Tags den Produktnamen auslesen können sollte.
Also z.B. https://www.gtinsuche.de/detail?ean=7617014129882
Ein Python-Skript um Daten aus einer Webseite aus zu lesen hab ich schon früher mal geschrieben. Darum denke ich, dass das eigentlich klappen sollte. Auch hab ich auf der Seite keine Nutzungsbeschränkung oder etwas in die Richtung gefunden.

Aber wenn jemand eine andere Idee oder einen Tipp hat bin ich gerne offen dafür :-)
 
TE
taks

taks

PCGH-Community-Veteran(in)
5. Erster GUI Entwurf (Kurz Update)

Abend zusammen

Heute hatte ich kaum Zeit für das Projekt, darum gibt es nur ein kurzes Update.

Ich habe einen ersten Entwurf (Wireframe) für die Programmoberfläche zusammengestellt. Und zwar für das "Artikel erfassen" Form. Die Oberfläche ist in 4 Panels unterteilt:
1. Panel: Sind drei Buttons am linken Rand mit welchen ich zwischen den drei Main-Forms umschalten kann. Das sind "Artikel erfassen", "Artikel austragen" und "Übersicht"
2. Panel: Ist ein Grid welches die letzten erfassten Artikel zeigt, damit man nicht die Übersicht verliert, oder schnell den letzten Eintrag korrigieren kann.
3. Panel: Beinhaltet die Eingabefelder für den Artikel.
4. Panel: Besteht aus 4 Buttons für die Steuerung des Artikels. Oben sind "Eingabe speichern" und "Eingabe verwerfen", darunter sind ein + & - Button um die Menge der erfassten Artikel zu verändern, damit man nicht 10 gleiche Artikel scannen muss.

Artikel-Erfassen-Screen.png


Wer ein gutes Programm für Wireframes sucht, ich kann euch folgendes ans Herz legen: https://balsamiq.com/wireframes/

Das wars auch schon. Wünsche einen schönen Abend
 
Zuletzt bearbeitet:
TE
taks

taks

PCGH-Community-Veteran(in)
Das sieht doch schon mal gut aus, der Thread bleibt im Abo, interessantes Projekt :daumen:
Nur den Wechsel der Biersorte empfehle ich dringend :fresse: :P
Freut mich zu hören.
Normalerweise gibts ja auch Quöllfrisch, aber von den Feldschlösschen hatte ich die GTIN im Internet gefunden ;-)

edit: grad gesehen, dass es in Deutschland auch eine Feldschlösschen Brauerei gibt. Ich mein aber die hier :-D
 
Zuletzt bearbeitet:
TE
taks

taks

PCGH-Community-Veteran(in)
6. Programm-Skeleton (TNotebook)

Hallo zusammen

Ich hatte die letzte Zeit viel um die Ohren, darum gings mit dem Projekt nicht wirklich vorwärts. Aber sollte jetzt wieder besser werden :-)

Ich hab mich die letzten Tage vor allem mit der Benutzeroberfläche (tkinter) auseinander gesetzt. Im Speziellen mit der Fenstersteuerung für meine Verwaltungsapplikation.

Die Applikation soll links drei Buttons um zwischen den einzelnen Fenster umschalten zu können besitzen. Dafür bin ich nun beim "Notebook" gelandet. Ist eigentlich nur eine simple Tab-Steuerung welche meine Bedürfnisse glaub ziemlich erfüllt. Nur kann man weder Breite noch Höhe für die Tab-Buttons festlegen, nur Padding und Margin :motz:Aber ich denke ich find schon noch eine Lösung. Oder hat einer von euch ne Idee dazu?

GUI_Beispiel.png


GUI_Beispiel2.png


Das wars eigentlich auch schon. Im Moment bin ich hauptsächlich am lesen und Tutorials anschauen weil ich mich mit Python nicht auskenne und in den Tutorials erstmal schauen muss wie man Funktionen umsetzen kann. Z.B. mit C# oder Java wäre eine Tab-Steuerung keine grosse Sache, bei Python erscheint es mir schon komplizierter ^^
Aber ich will für den Moment bei Python bleiben 🤓

Gruss
 
Zuletzt bearbeitet:
TE
taks

taks

PCGH-Community-Veteran(in)
7. Programm-Skeleton - Progress Incoming

Geht doch langsam Vorwärts. Bin heute Abend nochmals 2 Stunden dran gesessen und es nimmt doch schon die geplanten Formen an. In den TreeView hab ich mich auch langsam eingearbeitet.

GUI_Beispiel3.png


Jetzt kommt als nächstes noch die restlichen Felder und Buttons für das Form und dann wage ich mich mal an die Datenbank.

Gruss & einen schönen Abend


edit: Ich wollte eigentlich nur nochmal was zu dem Youtube-Kanal sagen welchen ich gefunden habe und ihn super finde. Und zwar ist der Kanal Codemy.com und da find ich das Zeug von John recht unterhaltsam und lehrreich. Wenn jemand ein gutes Tutorial für tkinter braucht, ich kanns nur empfehlen.

 
Zuletzt bearbeitet:
TE
taks

taks

PCGH-Community-Veteran(in)
8. Datenbank: Die Erste

Hallo Zusammen

Die Zeit vergeht viel zu schnell, bald ist schon Weihnachten und ich muss mich jetzt ran halten, damit ich auch ein Geschenk habe. Die letzte Zeit ist es bei der Arbeit ziemlich stressig und nach einem 9 Stunden Tag im Büro bin ich ziemlich platt und dem Hausbau muss auch noch ein Mass an Aufmerksamkeit geschenkt werden ^^. Aber ich hatte Montag & Dienstag Frei und darum gehts auch wieder vorwärts.

Die letzten Tag habe ich die Oberfläche noch soweit fertig gestellt damit alles nötige vorhanden ist und sie ungefähr so aussieht wie geplant.

gui_Example_3.png


Am Montag & Dienstag gings mit der Datenbank weiter. Die Entscheidung ist auf SQLite gefallen, in der Hoffnung das ich damit alles hinkriege wie geplant.

Als erstes reichen die zwei Tabellen ite_Item & boo_Booking. Item ist der Stammeintrag für die Produkte und in Booking werden die einzelnen Ein- und Ausbuchvorgänge festgehalten.

Die Tabellen sehen wie folgt aus:

ite_Item.png


boo_Booking.png


Dazu hab ich noch die entsprechenden Objektklassen und ein bisschen mehr in Python gebaut.

Booking.py
booking_Code.png


Item.py
item_Code.png


BookingListItem.py (Entität für Liste um den Tree zu füllen)
bookingListItem_Code.png


BookingList.py (Liste um den Tree zu füllen)
bookingList_Code.png


Database.py (Datenbank Objekt)
database_Code.png


Die Abfrage aus Python und das Einfüllen in einen Tree funktioniert ohne Probleme.

db_Test.png


Beim Speichern in die Datenbank hab ich aber grad noch meine Mühe ^^
Das Item speichern geht bestens, aber bei Booking muss ich für den ForeignKey die UId des Items mitgeben. Und irgendwie bekomm ich ein falsches/leeres Objekt zurück wenn ich die Item UId über die GTIN holen will. Das ganze ist natürlich nur für den Fall, dass das ITEM noch nicht vorhanden ist. Es kommt noch zusätzlicher Code falls das Item schon in der Datenbank vorhanden ist.

saveBooking_Code.png


Aber ich hatte gestern Abend keinen Nerv mehr, darum wars das auch schon. :-D

Ich klemm mich diese Woche nochmals dahinter und will das Datenbank-Zeugs abschliessen. Als nächstes kommt dann die Online-Produktabfrage per GTIN. Da freue ich mich schon drauf :-) Und ebenso klemme ich mich noch hinters Zeichenbrett für das Gehäuse. Das sollte bis Weihnachten zumindest unlackiert bereitstehen ^^

Gruss taks
 
TE
taks

taks

PCGH-Community-Veteran(in)
9. GUI Refactoring: !#%?-ç(@!!

Abend allerseits

Das im letzten Beitrag erwähnte Problem mit dem Einfügen der Datensätze konnte ich mit einem frischen Versuch auf Anhieb beheben. Manchmal ist es einfacher wenn man es am nächsten Tag nochmals versucht :-)
Soweit ist das Thema Datenbank dann auch abgeschlossen. Dachte zuerst es gibt noch mehr zu tun, aber ich baue mir die restlichen benötigten Funktionen wenn ich sie im fertigen GUI implementieren.

Und das fertige GUI ist dann auch das Thema welches ich mir für jetzt vorgenommen habe. Wieso fertiges GUI fragt ihr euch? Das GUI welches ich oben gezeigt habe steht alles schön aneinander gereiht in einem Python File. Damit es übersichtlicher wird, habe ich die einzelnen Funktionen in eigene Files/Klassen gepackt. Der Aufwand dafür war mit ~1 Stunde auch noch übersichtlich. Aber hier habe ich meine erste Knacknuss gefunden.

Eigentlich funktioniert alles wie es soll, nur eine !#%?-ç(@!! Kleinigkeit hat mich wertvolle Zeit und Nerven gekostet. Wenn ich auf einen Button klicke werden die im "command" angegebenen Funktionen nicht ausgeführt. Und ich hab absolut keinen Plan an was das liegt. Nach etwa 3 Stunden Internet-Recherche und Programm umschreiben habe ich Gestern Abend das Handtuch geworfen. Keine Chance das Ding zum laufen zu kriegen....
Deshalb bleib ich fürs erste glaub einfach bei meiner "Ein-Datei-Lösung" und kümmer mich später drum.
Wenn jemand von euch ne Idee hat wo der Fehler liegt, bitte raus damit :hail: Hier fehlt mir auch einfach die Erfahrung mit Python. Den Programmieraufwand welchen ich bis jetzt in das Projekt gesteckt habe, würde ich auf 15-20h schätzen.

Im MainForm werden die einzelnen Elemente erstellt.
TabController enthält alles für das Notebook welches als Tab-Steuerung funktioniert.
TabBooking enthält alles für das Ein-/Austragen der Artikel. Und auch die Buttons welche eben die entsprechenden Funktionen aufrufen sollten aber dies nicht tun. Wo ich hier auch ein Problem habe: Wie rufe ich am besten aus der command Funktion der Buttons die Entry Felder auf, welche ich in einer anderen Funktion erstellt habe? Globale Variabeln? In der Version wie ihr sie hier seht, habe ich TabBooking als Klasse erstellt mit den entsprechenden Attributen. Passt das so?

Code:
## MainForm ##
--------------
import tkinter as tk
import tkinter.ttk as ttk
import TabController as tac
import TabBooking as tab               

root = tk.Tk()
root.geometry=('800x480')
root.resizable(False, False)
root.title("Candyshop")

tabController = tac.getTabController(root)

root.mainloop()

Code:
## TabController ##
-------------------
import tkinter as tk
import tkinter.ttk as ttk
import TabBooking as tab
import TabItem as tai
import TabOverview as tao

# Return Booking Frame
def createTabController(root):
    #Create and Configure Style for Notebook
    style = ttk.Style()
    style.configure('lefttab.TNotebook', tabmargins=[2, 5, 2, 0], tabposition='wn', borderwidth=0)
    style.configure('lefttab.TNotebook.Tab', padding=[10, 68], borderwidth=1, width=11, font=('Arial','11','bold'))
    tabController = ttk.Notebook(root, style='lefttab.TNotebook')
    createTabs(tabController)
    tabController.grid(row=0, column=0, sticky="nw")
    return tabController

# Return Booking Frame
def createTabs(tabController):
    tabController.add(tab.getTabBooking(tabController), text=' Hinzufügen')
    tabController.add(tai.getTabItem(tabController), text='  Artikel')
    tabController.add(tao.getTabOverview(tabController), text='  Übersicht')
    return tabController

# Return tabControl (Notebook)
def getTabController(root):
    return createTabController(root)

Code:
## TabBooking ##
----------------
import tkinter as tk
import tkinter.ttk as ttk

class Item:
    def __init__(self,tabController):
        self.tabController = tabController
        self.tabBooking = tk.Frame(self.tabController, bg='#ffffff', width=680, height=480)
        #Create Frame for TreeView
        self.frameList = tk.Frame(self.tabBooking, bg='grey', width=300, height=480)
        self.frameList.grid(row=0, column=0, sticky="nsew")
        #Create TreeView
        self.my_tree = ttk.Treeview(self.frameList, height=22)
        #Define Columns
        self.my_tree['columns'] = ("Artikel", "Menge", "Datum")
        #Format Columns
        self.my_tree.column("#0", width=0)
        self.my_tree.column("Artikel", anchor="w", width=150, minwidth=25)
        self.my_tree.column("Menge",  anchor="e", width=30)
        self.my_tree.column("Datum", anchor="e",  width=90)
        #Create headings         
        self.my_tree.heading("Artikel", text="Artikel")
        self.my_tree.heading("Menge", text="Stk.")
        self.my_tree.heading("Datum", text="Datum")
        #  Create Frame for Fields
        self.frameDetails = tk.Frame(self.tabBooking, bg='White', width=300, height=480)
        self.frameDetails.grid(row=0, column=1, sticky="nsew", padx = 10, pady=10)
        #  Create Fields
        self.lblArtikelGTIN = tk.Label(self.frameDetails, bg='White', text="GTIN", width=10, pady=20)
        self.lblArtikelGTIN.grid(row=0, column=0)
        self.entArtikelGTIN = tk.Entry(self.frameDetails, font = ('calibri', 15, 'bold'), width=18)
        self.entArtikelGTIN.grid(row=0, column=1)
        self.lblArtikelName = tk.Label(self.frameDetails, bg='White', text="Bezeichnung", width=10, pady=20)
        self.lblArtikelName.grid(row=1, column=0)
        self.entArtikelName = tk.Text(self.frameDetails, font = ('calibri', 15, 'bold'), height=4, width=18)
        self.entArtikelName.grid(row=1, column=1)
        self.lblArtikelMenge = tk.Label(self.frameDetails, bg='White', text="Stück", width=10, pady=20)
        self.lblArtikelMenge.grid(row=2, column=0)
        self.entArtikelMenge = tk.Entry(self.frameDetails, font = ('calibri', 20, 'bold'), justify='center', width=13)
        self.entArtikelMenge.grid(row=2, column=1)
        #Create Frame for Controls
        self.frameControls = tk.Frame(self.tabBooking, bg='White', width=100, height=480)
        self.frameControls.grid(row=0, column=2, sticky="nsew")
        #Create Controls
        self.btnAdd = tk.Button(self.frameControls, text ="Add", width=9, height=3, font = ('calibri', 13, 'bold'), bg='green', command = addButtonCall)
        self.btnAdd.grid(row=0, column=0, pady=20)
        self.btnRemove = tk.Button(self.frameControls, text ="Remove", width=9, height=3, font = ('calibri', 13, 'bold'), bg='orange', command = removeButtonCall)
        self.btnRemove.grid(row=1, column=0, pady=20)
        self.btnPlus = tk.Button(self.frameControls, text ="+", width=9, height=3, font = ('calibri', 13, 'bold'), bg='grey', command = plusButtonCall(self.tabBooking))
        self.btnPlus.grid(row=2, column=0, pady=20)
        self.btnMinus = tk.Button(self.frameControls, text ="-", width=9, height=3, font = ('calibri', 13, 'bold'), bg='grey', command = minusButtonCall)
        self.btnMinus.grid(row=3, column=0, pady=20)

# Button Call Functions
def plusButtonCall(self):
    value = self.entArtikelMenge.get()
    #print (sNumber)
    #result = 0
    #result = int(value) + 1
    #entArtikelMenge.insert (0, str(5))
    print(value)
    print ("Callback!")

def minusButtonCall():
   print ("Callback!")

def addButtonCall():
   print ("Callback!")

def removeButtonCall():
   print ("Callback!")
 
Zuletzt bearbeitet:

DOcean

PCGHX-HWbot-Member (m/w)
Such mal nach Data Binding, ich vermute/hoffe sowas gibt es auch für dein Framework...

Grundsätzlich macht es Sinn GUI und Daten zu trennen, das sorgt dafür das Änderungen an der GUI nichts kaputt machen...

Wahrscheinlich ist für deinen Zweck am einfachsten eine globale Var. die alle Daten hält, die anderen Elemente schreiben/lesen dann nur noch dieses Element.

Wenn du da weiter lesen willst MVVM MVC sind Design Pattern für sowas was du machst...
 
TE
taks

taks

PCGH-Community-Veteran(in)
Such mal nach Data Binding, ich vermute/hoffe sowas gibt es auch für dein Framework...

Grundsätzlich macht es Sinn GUI und Daten zu trennen, das sorgt dafür das Änderungen an der GUI nichts kaputt machen...

Wahrscheinlich ist für deinen Zweck am einfachsten eine globale Var. die alle Daten hält, die anderen Elemente schreiben/lesen dann nur noch dieses Element.

Wenn du da weiter lesen willst MVVM MVC sind Design Pattern für sowas was du machst...
Ja, ich muss mich da mal schlau machen was es in die Richtung für Python gibt. Aber kurzfristig (bis Weihnachten) liegt es leider ned mehr drin und ich muss schauen, dass ich die Grundfunktionen drin habe. Auch wenn die Software bis dahin natürlich noch nicht ausgereift sein muss.
Aber langsam wirds schwierig das Projekt vor meiner Freundin geheim zu halten. Auch für das Gehäuse welches ich heute angefangen habe musste ich die ganze Woche warten bis sie mal nicht Zuhause war. Dank Corona kann man ja fast nichts mehr unternehmen und sitzt Zuhause -.-


10. Gehäuse Teil 1

Nachdem mein Plan im Kopf schon recht klar war, hab ich ihn noch schnell zu Papier gebracht um zu sehen ob mir nichts entgangen ist. Es ging alles so auf wie ich wollte und nachdem ich das entsprechende Holz aus meinem Lager geholt hatte gings los :bier:

Ein ganz simpler Plan und im Hintergrund noch die Specs für das Display wegen dem Ausschnitt.
IMG_20201218_165346.jpg


Da meine Tischkreissäge im Winter zu kalt hat und den Dienst verweigert, kam meine neu erworbene Stichsäge (Makita 4329) zum Einsatz :-) Bin sehr zufrieden mit ihr, jedoch sind Gehrungsschnitte mit ner Stichsäge nicht so einfach wie mit der Tischkreissäge ^^ Für die drei Blenden und die Gehäuseseiten gingen stolze 1.5 Stunden drauf.
IMG_20201218_182605.jpg

Wie hier zu sehen ist wurden die Schnitte halbwegs wie gewünscht und es passt was ich gesehen habe auch recht gut zusammen. Ein bisschen Spachtel wirds aber brauchen :ugly:
IMG_20201218_182620.jpg


Beim Gehäuse gehts am Montag weiter, werd ein bisschen früher Feierabend machen und noch die letzte Blende, den Boden und die zwei Winkel an den Seitenwänden zusägen. Zusammengehalten wird dann alles mit 8mm Dübeln und Holzleim.

Übers Wochenende sollte dann auch die Software soweit sein, dass ich einen funktionieren Prototypen habe :-)


Danke fürs lesen & ein geruhsames Wochenende
 
TE
taks

taks

PCGH-Community-Veteran(in)
11. Webabfrage & weitere Funktionen

Abend zusammen

Heute gings weiter mit der Webabfrage der GTIN-Nummer. Wie weiter oben geschrieben benutze ich dafür die Webseite https://www.gtinsuche.de/ um den Produktnamen zur entsprechenden GTIN zu erhalten. Kurz und knapp zusammengefasst:
Es lebt! :-)
Ich hatte nur meine Mühe BeautifulSoup installiert zu bekommen weil PIP nicht so wollte wie ich ^^
Der Code kann noch ein Refactoring vertragen, aber es läuft fürs Erste. Muss die restlichen drei Tage die mir bleiben noch für was anderes als hübschen Code verwenden :-D

Code:
import urllib3
import certifi
from bs4 import BeautifulSoup

class GtinWebInfo: 
    # Class to get numbers from webpage and return them
    @classmethod
    def getGTIN(self, Attr2):
        numbers = []
        url =('https://www.gtinsuche.de/detail?ean=' + Attr2)
        http_pool = urllib3.connection_from_url(url, cert_reqs='CERT_REQUIRED', ca_certs=certifi.where())   
        r = http_pool.urlopen('GET',url)
            
        soup = BeautifulSoup(r.data, 'html.parser')     
        for tag in soup.find_all('h4'):
            print(tag.string)
            #print("hoi")
            numbers.append(tag.string)
        #for tag in soup.find_all("li", class_="new lucky-star"):
            #print(tag.string)
            #numbers.append(tag.string)
        #for x in numbers:
            #print("Zahl: " + x)
        return numbers

Zwischendurch gabs zur Stärkung Weihnachtskekse von Mutti :-X Sie hat mir soviele mitgegeben, ich kann glaub noch bis Februar davon essen ^^
IMG_20201220_173214.jpg


Daneben habe ich auch die Funktionen zum Hinzufügen von neuen Artikeln, Buchungen etc. mit dem GUI verknüpft und es läuft auch alles. War ein wirklich produktiver 4. Advent :bier:
Zu den oben erwähnten Funktionen kommt im nächsten Tagebucheintrag noch mehr. Der Code ist noch ein ziemliches durcheinander und noch ned 100% fertig. Für heute reichts mir aber mit programmieren und darum ist auch Schluss.

Gruss taks
 
TE
taks

taks

PCGH-Community-Veteran(in)
Hallo zusammen

Eigentlich wollte ich heute meinen nächsten Beitrag schreiben, aber ich hatte einfach keine Zeit. Der ausführliche Beitrag folgt die kommenden Tage.

Darum gibts nur ein kurzes Video. Die Produktnamen werden übers Internet abgefragt. Geiler Scheiss :-D

Recommented content - Youtube An dieser Stelle findest du externe Inhalte von Youtube. Zum Schutz deiner persönlichen Daten werden externe Einbindungen erst angezeigt, wenn du dies durch Klick auf "Alle externen Inhalte laden" bestätigst: Ich bin damit einverstanden, dass mir externe Inhalte angezeigt werden. Damit werden personenbezogene Daten an Drittplattformen übermittelt. For more information go to the privacy policy.

Liebe Grüsse & nen schönen Heiligabend
 
TE
taks

taks

PCGH-Community-Veteran(in)
12. Gehäuse Teil 2

Schon lange versprochen, nun kommt endlich der nächste Beitrag.

Wie im Video zu sehen ist, funktioniert der Code soweit wunderbar. Bei der Bedienung gibt es noch ein paar Stellen die noch ein bisschen "hackelig" sind welche ich mir demnächst vornehme.

Das Gehäuse ist da eine ganz andere Liga.
Zuerst hab ich die Teile wie weiter oben schon erwähnt mit meiner Stichsäge zugeschnitten, Da ich bei der Arbeit jedoch mehr zu tun hatte als gehofft, konnte ich das ganze erst am Dienstag Abend vor Weihnachten angehen.
Also nach 10 Stunden Arbeit um ~17:00 Uhr die Sachen gepackt und frisch ans Werk.

Mit einer Dübelschablone ging es auch recht gut voran. Ganz praktisch das Ding.

IMG_20201223_165102.jpg

IMG_20201223_170722.jpg


Ging alles ganz flott und das Ergebniss konnte sich auch sehen lassen.

IMG_20201223_170828.jpg

IMG_20201223_171300.jpg


Jedoch war die Konzentration nach 10 Stunden arbeiten nicht mehr sooo gut. Wer findet den Fehler? ^^

IMG_20201223_171542.jpg


Auf alle Fälle hatte ich danach eine Pechsträhne und es wollte nichts mehr klappen. Nachdem ich wie oben zu sehen ist die Löcher auf die falsche Seite gebohrt hatte (Gehrung zeigt auf die falsche Seite) habe ich den selben Fehler bei einem weiteren Teil gemacht. Danach brach mir noch der Rahmen/Halterung für das Display.
Mit einem riesen Anschiss hab ich dann einfach alles ohne Dübel verleimt und beschlossen später in Ruhe ein neues Gehäuse zu bauen.

IMG_20210214_164631.jpg


Als nächstes kümmere ich mich wieder um die Software. Dabei steht Refactoring und die saubere Implementierung von Data-Bindings an.

Gruss & einen schönen Sonntag
taks
 
Oben Unten