Python Anwendung

Du hast eine Idee für ein Projekt?
Antworten
Kanaax
User
Beiträge: 17
Registriert: Mittwoch 5. August 2020, 09:15

Moin Leute,

ich programmiere jetzt seit einer Woche mit Python ein Programm und dazu hätte ich ein paar Fragen.

Erstmal Grundlegendes zum Programm:
Ich muss ein Programm erstellen wo ich in einer GUI Daten einlesen muss und diese dann später auf verschiedenen Seiten(reiter) anzeigen lassen möchte.
Am Ende soll das programm dann noch Pdf Datein, sprich Rechnungen Automatisch aus den Eingepflegten Daten erstellen. Dieses muss ich dann später über ein Drucker(den Code dafür muss ich allerdings in einer "C" Sprache schreiben) ausdrucken, wobei wenn ich das nicht mehr schaffe bis Weihnachten ist das nicht schlimm.

Ich habe jetzt gedacht da ich mit Tkinter nicht klar komme(Was auch daran liegen kann das ich noch nicht OOP kann), dass ich eine GUI mit HTML/Css baue, diese dann mit den passenden Python Code "ausstatte" und die benötigten Daten in einer MySQL Datenbank einlese und verwalte.

Ist dies so überhaupt möglich und ist Python dafür überhaupt geeignet?
Wenn Ja kann mir hier einer Tipps geben wie ich das mit HTML/CSS realisieren kann?
Wenn das nicht gehen sollte, gibt es was anderes als tkinter was kostenlos ist und was leicht zu lernen ist?

MySQL behersche ich zum Teil aber da habe ich jemanden der mich zu not unterstützen kann.
Da mein Englisch eingerostet ist, wenn es möglich ist bitte Deutsche Anleitungen, tutorials oder ähnliches schicken(außer es gibt die nicht auf Deutsch, dann ist Englisch auch OK).

Danke schonmal für eure Hilfe. :)
Sirius3
User
Beiträge: 17711
Registriert: Sonntag 21. Oktober 2012, 17:20

GUIs sind immer komplex und Du kommst damit nie um OOP herum.
HTML sieht auf den ersten Blick einfacher aus, kommt aber auch darauf an, wie Komplex die Eingabe sein soll. "Mehrere Seiten" machen die Sache auf jeden Fall komplizierter.
Eine Empfehlung zu geben, ohne den genauen Plan zu kennen, ist eigentlich unmöglich. Das was Du beschreibst reicht von einem einfachen Formular bis sehr komplex.

Für die Datenbankanbindung empfiehlt sich SQLAlchemy, weil man sich nicht zu eng an ein Datenbanksystem binden will und auch nicht in die Tiefen von SQL einarbeiten will.
Oder, falls Du wirklich alles auf Web ausrichten willst, dann benutze Django, das bringt alles mit, was Du brauchst und hat auch gute Tutorials. Dann mit der Datenbankanbindung von Django.

Ansonsten kannst Du mit Deinem ersten Entwurf eigentlich nur Scheitern, also frisch auf ans Werk. Halte alles so einfach wie möglich, lass alles komplexe erst einmal weg.

Wenn Du konkrete Hilfe willst, mußt Du hier auch konkreter Beschreiben, was das Programm machen soll.

Ich bezweifle, dass Du für den Drucker irgendwas in C programmieren mußt. Was ist denn das für ein besonderer Drucker?
Benutzeravatar
__blackjack__
User
Beiträge: 13004
Registriert: Samstag 2. Juni 2018, 10:21
Wohnort: 127.0.0.1
Kontaktdaten:

Falls das mit dem C daran liegt, dass es da eine C-Bibliothek für den Drucker gibt gibt: So etwas kann man auch von Python aus ansprechen. Zum Beispiel mit dem `ctypes`-Modul aus der Standardbibliothek.

Was ein GUI-Rahmenwerk angeht, da ist mein Favorit Qt. Allerdings muss man da aufpassen welche Anbindung man nimmt und unter welche Lizenz das dann den eigenen Code ”zwingt”.
“Most people find the concept of programming obvious, but the doing impossible.” — Alan J. Perlis
Kanaax
User
Beiträge: 17
Registriert: Mittwoch 5. August 2020, 09:15

Erstmal danke für eure Hilfe und der schnellen Antwort, ich versuche mal alles nach und nach zu beantworten und euch ein kleinen Einblick zu geben.
Ich weiss das ich mich früher oder später mit OOP beschäftigen muss, das ist auch nicht schlimm nur leider finde ich da noch nichts drüber was mir Hilft(Sprich OOP mit Tkinter).
Die HTML Syntax kann ich schon und daher war das eine überlegung die GUI mit HTML zu entwerfen. Ich muss sagen wir mal auf Seite 1. 4 Eingaben machen: Wohnort, PLZ, Straße und Hausnummer. Diese Daten möchte ich dann auf der Ersten Seite Ausgeben und evtl bearbeiten sprich Den Wohnort von Köln auf Berlin ändern aber die anderen Daten bleiben gleich. Wenn ich jetzt aber auch einer neuen Seite gehe zB. "Schöne Städte" möchte ich nur die Städte sehen die ich auf einer weiteren Seite ausgewählt habe(Seite 3 heisst zB. Städte ordnen) , ich möchte aber auch andere Städte auf einer anderen Seite ausgeben die dann zB. "Hässliche Städte" heisst. Kannst du damit etwas anfangen?
Per PN kann ich dir auch genau sagen worum es geht, aber ich denke das mein Programm in etwa die gleichen Funktionen haben soll.

Eine Webanwendung wollte ich nicht machen, das Programm möchte ich später zB. ein Kumpel geben der das dann auf sein Rechner normal benutzen kann(.exe Datei).

Mit den Drucker habe ich mich noch nicht Richtig beschäftigt aber er braucht irgendetwas von C/C++ oder so ähnlich, was aber erstmal uninteressant ist(wie __blackjack__ schon sagt kann man da ja etwas machen und da wird mir ein erfahrener Programmierer bei helfen).

@__blackjack__ Qt habe ich mir auch schon angeguckt aber irgendwie muss man sich da immer mit Firmen Daten usw. registrieren und ich bin nunmal eine Privat Person. Lizenz technisch werde ich keine Probleme bekommen, da dieses Programm nur für mich ist als "Beschäftigung" im Praktikum.
Sirius3
User
Beiträge: 17711
Registriert: Sonntag 21. Oktober 2012, 17:20

Wenn da eine MySQL-Datenbank dranhängen soll, dann ist das ja nichts, was man so einfach "als .exe-Datei" verteilen kann.
Hast Du denn schon das Datenmodell designed mit all seinen Operationen darauf? Also die Abfragen aufgelistet (schöne Städte, häßliche Städte), die und Updates (neue Adresse anlegen, Adresse ändern, ...)?
Zweiter Schritt wäre, dieses Datenmodell dann zu implementieren und für jede Operation eine Funktion dafür zu haben, und das ganze dann ausführlich mit Tests absichern.
Das ist die Programmlogik.

Erst dann kommt der Schritt, sich über die Ansichten Gedanken zu machen, also was soll in Formularen oder Tabellen dargestellt werden. Wenn man das hat, kann man sich umschauen, welches Framework denn alle nötigen Widgets dafür bereitstellt. Gerade TkInter ist da in mancher Hinsicht eingeschränkt.
Erst dann beginnst Du damit, eine GUI zu entwickeln, die die Oberfläche mit der Programmlogik verbindet.

Du machst den selben Fehler, wie die meisten Anfänger, nämlich von der falschen Seite anzufangen. Klar ist es beeindruckender, ein schönes Fenster vor sich zu haben. Aber man verzettelt sich auch leicht.

Qt (aka PySide2) kann man ganz normal per pip als Paket installieren.
Kanaax
User
Beiträge: 17
Registriert: Mittwoch 5. August 2020, 09:15

Ich habe mich erstmal dran gesetzt und mir die Grundlagen von Tk angeschaut und ich mache das derzeit so das ich die eingabe in einer .txt Datei abspeichere. Das gefällt mir so allerdings noch nicht, daher frage ich jetzt hier im Forum. Von dem was Tk bereitstellt war ich Anfangs überzeugt das es reicht, mitlerweile bin ich aber soweit das tkinter einfach nicht das macht was es soll und ich mich daher nach Alternativen umschaue.

Ich habe gedacht das ich erstmal das Optische mache und dann den Code für die Funktionen einbinde, um Regelmäßig zu testen ob das alles so Funktioniert(Das ist die erste GUI die ich selber Programmieren möchte bzw. soll.).

Was empfiehlst du mir wie ich am besten vorgehen kann? Soll ich es bei der .txt datei belassen und lieber mehr Arbeit in der GUI und den dazugehörigen Code stecken oder macht eine Datenbank sinn?
Sirius3
User
Beiträge: 17711
Registriert: Sonntag 21. Oktober 2012, 17:20

Das sind ja völlig verschiedene Fragen. Wie man Daten ab geschicktesten speichert, hängt erstmal nur davon ab, wie Du damit arbeiten willst, und nicht, ob oder wie die GUI aussieht.

Was willst Du denn machen, was TkInter nicht kann? Werde konkreter.

Zum Testen, ob alles funktioniert, benutzt man meist Unit-Tests, die automatisch ablaufen können. Da ist eine GUI eher hinderlich, weil die Automatisierung einer GUI ein komplexes Thema ist.
Kanaax
User
Beiträge: 17
Registriert: Mittwoch 5. August 2020, 09:15

ICh möchte das ein Benutzer Daten eingibt, diese gespeichert werden, dann soll man diese Daten verändern und löschen können. Gleichzeitig sollen die Eingegebenen Daten in ein Textfeld angezeigt werden. Wenn das alles funktioniert möchte ich zum schluss noch aus diesen Daten zB. eine Rechnung erstellen(vorher noch alle sachen zusammen rechnen und dann richtig ausgeben) und ausdrucken.

Allein das Positionieren von Buttons klappt nicht richtig. Das sieht dann meistens nicht gut aus, da die Abstände nicht passen oder die Buttons nicht an der passenden Stelle erscheinen. Das ist langsam nur noch frustrierend und macht so keinen Spaß mehr(ich lerne tkinter ja gerade erst).

Ich schreibe immer ein Teil meines Codes und Debugge den dann, so haben wir es auch gelernt. Die GUI ansich funktioniert bzw. sie macht was sie soll, aber ansich das Layout zu gestalten ist eine Katastrophe :D.

Wobei der Python Code ansich das leichteste ist finde ich.
Benutzeravatar
__blackjack__
User
Beiträge: 13004
Registriert: Samstag 2. Juni 2018, 10:21
Wohnort: 127.0.0.1
Kontaktdaten:

@Kanaax: Sirius3 hat das Vorgehen, insbesondere was die Reihenfolge angeht ja eigentlich schon beschrieben. Erst macht man sich Gedanken darüber welche Daten das Programm verarbeitet, dann wie diese Verarbeitung aussieht, also welche Anfragen und welche Veränderungen gemacht werden sollen. Daraus leitet sich dann ab wie man die Daten strukturiert.

Da kann dann auch die Datenhaltung mit rein spielen. Wenn man eine relationale Datenbank dahinter stehen hat, kann das ein wenig anders aussehen als wenn man die Daten beispielsweise als JSON oder XML serialisiert und speichert.

GUI am Anfang ist gut als Prototyp und weil sich daraus die Operationen ableiten lassen die man auf den Daten durchführen können muss, was wie gesagt die Strukturierung der Daten beeinflusst.

Aber GUI ist nicht gut als Ausgangspunkt der Implementierung der Programmlogik. Und man braucht die GUI auch nicht zum testen der Programmlogik. Das ist viel zu aufwändig da immer selbst das Programm zu starten und irgendwo rum zu klicken und Eingaben vorzunehmen. Testen der Programmlogik wird automatisiert gemacht. Dafür gibt es Unit-Tests.

Das tatsächliche draufsetzen einer GUI auf die Programmlogik ist der letzte Schritt.

Das bedeutet nicht zwangsläufig, dass erst die komplette Programmlogik stehen muss bevor man mit der GUI anfangen kann, aber der jeweilige Programmlogik-Teil sollte vorher *unabhängig* von irgendeiner GUI funktionieren und bestenfalls auch getestet sein.

Wo genau liegt denn das Problem mit den Layouts bei `tkinter`? Also ausser Du verwendest `place()` und gibst Positionen und Grössen selbst, absolut an. Das macht man natürlich nicht. Da Du HTML kannst: `Tk`, `Frame`, oder `Toplevel` sind ein <div>/<table>-Dings, `pack()` kann man verwenden um da entweder Sachen unter- oder nebeneinander drin unterzubringen, `grid()` um da Sachen wie in einer Tabelle in Zellen unterzubringen.
“Most people find the concept of programming obvious, but the doing impossible.” — Alan J. Perlis
Kanaax
User
Beiträge: 17
Registriert: Mittwoch 5. August 2020, 09:15

@__blackjack__ Also das beantwortet für mich verständlich fast alle fragen von mir, danke das du (und natürlich auch Sirius3) dir die Zeit dafür genommen hast.

Ich hatte jetzt erstmal eine GUI erstellt um mit tk "warm" zu werden, da es wie gesagt meine erste GUI ist und das erste "richtige" Programm. Also im Endeffekt ein Prototyp.

Ja das mit den ständigen rum klicken hat mich tierisch genervt, aber was soll man machen wenn dir der Dozent das so beibringt? Jetzt weiss ich wie es besser geht und kann es Anwenden.

ich habe mit "grid()" angefangen und die Buttons sind überall nur noch da wo sie hin sollen, ich habe alles was ich irgendwo gelesen habe ausprobiert und wurde nie besser. Dann habe ich "pack()" verwendet und mir wurden die "label" nur noch nebeneinander und dass über das ganze Fenster angezeigt.
<
Menge = Label(root, text="Menge:")
Menge.grid(row = 1, column = 0)

eingabe_Menge = Entry(root, bd=5, width=40)
eingabe_Menge.grid(row = 1, column = 1)
/>
So habe ich es momentan gelöst und nur so bekomme ich ein halbwegs gutes Ergebniss, wobei das bei den Buttons auch nicht klappt.
Die Grundfunktionen habe ich mir jetzt in 1,5 wochen beibringen können, aber wie gesagt irgendwie klappt das alles nicht so wie ich möchte bzw. mir erhofft habe.
Sirius3
User
Beiträge: 17711
Registriert: Sonntag 21. Oktober 2012, 17:20

Ja, so macht man das, wenn man mehrere Eingabefelder mit Labels machen möchte.
Bei komplexeren Fenstern kann es sinnvoll sein, in Frames zu untergliedern.
Nach Konvention werden Variablennamen komplett klein geschrieben: eingabe_menge. Das Label menge wird eigentlich gar nicht gebraucht.
Um die =-Zeichen bei Schlüsselwortargumenten kommen keine Leerzeichen.
Die Namen aus Tkinter werden üblicherweise über tk angesprochen:

Code: Alles auswählen

import tkinter as tk
[...]
root = tk.Tk()
tk.Label(root, text="Menge:").grid(row=1, column=0)
eingabe_menge = tk.Entry(root, bd=5, width=40)
eingabe_menge.grid(row=1, column=1)
Es kann auch sinnvoll sein, Daten und Layout noch stärker zu trennen:

Code: Alles auswählen

menge = tk.StringVar(root)

tk.Label(root, text="Menge:").grid(row=1, column=0)
tk.Entry(root, textvariable=menge, bd=5, width=40).grid(row=1, column=1)
Du scheinst wohl auf `90-Jahre-Rahmen zu stehen.
Kanaax
User
Beiträge: 17
Registriert: Mittwoch 5. August 2020, 09:15

Ja wie gesagt das ist mein erster versuch und da habe ich Tag für Tag dazu gelernt. Das mit den Variablen weiss ich mitlerweile auch aber ich wollte es einheitlich haben und da ich eh noch keine klassen habe bzw. mich damit noch nicht beschäftigt habe, dachte es ist erstmal in ordnung. tkinter habe ich sogar als tk importiert, aber das andere vom Code werde ich morgen so ändern.

Naja es muss funktionieren, die optik ist da erstmal egal, da die firma wo ich gerade bin generell programme hat die älter aussehen^^.

Eigentlich habe ich erstmal alle "Label" zusammen gemacht, dann alle "Entry" usw. dadrunter dann dann die ".grid" und alle bereiche mit kommentaren abgetrennt, damit ich weiss was ich mache.

Wenn du mir einmal sagst wie ich die Codeblöcke machen kann, kann ich morgen mal den code posten.

Sorry für die miese rechtschreibung aber auf meiner tastatur zuhause kann ich nicht so gut schreiben :D.
Sirius3
User
Beiträge: 17711
Registriert: Sonntag 21. Oktober 2012, 17:20

Im "Vollständigen Editor" gibt es den </>-Knopf.
Kanaax
User
Beiträge: 17
Registriert: Mittwoch 5. August 2020, 09:15

Code: Alles auswählen

from tkinter import *
import tkinter as tk
from tkinter import messagebox 
import tkinter.ttk as ttk
import sys

#---------------------------------------------------------------------------------------------------------------------
#Liste zum Speichern
neuer_artikel = []

#---------------------------------------------------------------------------------------------------------------------
#Fenster layout
root = Tk()
root.title(" Auktionshaus xyz " + "    " + " Artikel einpflegen ")
root.geometry("900x500")

#Icon oben Links 
#root.iconbitmap("HOMEME2.png")

#Bild anlegen und positionieren
image1 = PhotoImage(file="HOMEME2.png")
panel1 = Label(root, image = image1)
panel1.grid(row=0, column=5, columnspan=2, rowspan=2, sticky= E + N, padx=3, pady=3)     

#----------------------------------------------------------------------------------------------------------------------
#Funktionen

#Neues fenster für Verkaufte Artikel
def Verkaufte_Artikel_Li():
    Vk_Art_Window = tk.Toplevel()
    labelExample = tk.Label(Vk_Art_Window, text = " Verkaufte Artikel ")
    Vk_Art_Window.title("Auktionshaus xyz" + "    " + " Verkaufte Artikel ")
    Vk_Art_Window.geometry("720x720")
    panel2 = Label(Vk_Art_Window, image = image1)
    panel2.grid(row=0, column=3, columnspan=2, rowspan=2, sticky= E + N, padx=3, pady=3)

#Neues fenster für Versteigerungs Liste
def Versteigerungs_Li():
    Window2 = tk.Toplevel(root)
    labelExample = tk.Label(Window2, text = " Versteigerungsliste ")
    Window2.title("Auktionshaus xyz" + "    " + " Versteigerungsliste ")
    Window2.geometry("1000x500")
    panel3 = Label(Window2, image = image1)
    panel3.grid(row=0, column=3, columnspan=2, rowspan=2, sticky= E + N, padx=3, pady=3)
    Test1 = tk.Listbox(Window2, width = 250)
    Test1.insert("end", *neuer_artikel)
    Test1.grid()


#Neues fenster für Aktuelle Versteigerung
def Versteigerung():
    Versteigerung_Window = tk.Toplevel()
    labelExample = tk.Label(  Versteigerung_Window, text = " Aktuelle Versteigerung ")
    Versteigerung_Window.title("Auktionshaus xyz" + "    " + " Aktuelle Versteigerung ")
    Versteigerung_Window.geometry("720x720")
    panel4 = Label(Versteigerung_Window, image = image1)
    panel4.grid(row=0, column=3, columnspan=2, rowspan=2, sticky= E + N, padx=3, pady=3)

#Neues fenster für Unter Vorbehalt Liste
def Unter_Vorbehalt():
    Unter_Vorbehalt_Window = tk.Toplevel()
    labelExample = tk.Label(   Unter_Vorbehalt_Window, text = " Unter Vorbehalt ")
    Unter_Vorbehalt_Window.title("Auktionshaus xyz" + "    " + " Unter Vorbehalt ")
    Unter_Vorbehalt_Window.geometry("720x720")
    panel5 = Label(Unter_Vorbehalt_Window, image = image1)
    panel5.grid(row=0, column=3, columnspan=2, rowspan=2, sticky= E + N, padx=3, pady=3)

#Neues fenster für nicht Verkaufte Artikel
def Nicht_Verkaufte_Artikel():
    Nicht_Verkaufte_Artikel_Window = tk.Toplevel()
    labelExample = tk.Label(   Nicht_Verkaufte_Artikel_Window, text = " Nicht Verkaufte Artikel ")
    Nicht_Verkaufte_Artikel_Window.title("Auktionshaus xyz" + "    " + " Nicht Verkaufte Artikel ")
    Nicht_Verkaufte_Artikel_Window.geometry("720x720")
    panel6 = Label(Nicht_Verkaufte_Artikel_Window, image = image1)
    panel6.grid(row=0, column=3, columnspan=2, rowspan=2, sticky= E + N, padx=3, pady=3)

#Exit Fenster 
def Button_Abbruch():
    result = tk.messagebox.askyesno("Warnung!",
        "Soll das Programm wirklich geschlossen werden?")
    if result == True:
        root.destroy()

#Speichern
def getInput():
    Button_Speichern.bind("<Enter-Keypress-1>")
    result1 = tk.messagebox.askyesno("Speichern",
        "Möchten sie die Daten wirklich Speichern?")
    if result1 == True:
        a = eingabe_Art_Num.get()
        b = eingabe_Menge.get()
        c = eingabe_Art.get()
        d = eingabe_Preis.get()
        e = eingabe_Bietername_nummer.get()
        artikel_liste = ["Artikel Nummer: ", a, "Menge: ", b, "Artikel Beschreibung: ", c, "Mindestpreis: ", d, "Bieternummer oder Bietername:", e]
        neuer_artikel.append(artikel_liste)
        L = [neuer_artikel]
        datei = open ('eins.txt', "w")
        datei.write(', '.join((map(str, L))))
        datei.close()
        print (L)

#---------------------------------------------------------------------------------------------------------------------
#Menue 1
menu = Menu(root)
root.config(menu=menu)
filemenu = Menu(menu)
menu.add_cascade(label="Menü", menu=filemenu)

filemenu.add_command(label="Unter Vorbehalt Liste", command=Unter_Vorbehalt) 
filemenu.add_command(label="Versteigerungsliste", command=Versteigerungs_Li)
filemenu.add_command(label="Aktuelle Versteigerung", command=Versteigerung)
filemenu.add_command(label="Verkaufte Artikel", command=Verkaufte_Artikel_Li)
filemenu.add_command(label="Nicht Verkaufte Artikel", command=Nicht_Verkaufte_Artikel)

#-------------------------------------------------------------------------------------------------------------------------------------------
#Vor Eingabefeld
Art_Num = Label(root, text="Artikelnummer:")
Menge = Label(root, text="Menge:")
Art = Label(root, text="Artikelbeschreibung:")
Preis = Label(root, text="Mindestpreis:")
Schrift_Preis = Label(root, text="Schriftliches Gebot:")
Bietername_nummer = Label(root, text="Bietername oder Bieternummer:")

# Eingabefelder
eingabe_Art_Num = Entry(root, bd=5, width=40)
eingabe_Menge = Entry(root, bd=5, width=40)
eingabe_Art = Entry(root, bd=5, width=40)
eingabe_Preis = Entry(root, bd=5, width=40)
eingabe_Bietername_nummer = Entry(root, bd=5, width=40)

#fenster einfügen
Art_Num.grid(row = 0, column = 0)
Menge.grid(row = 1, column = 0)
Art.grid(row = 2, column = 0)
Preis.grid(row = 3, column = 0)
Bietername_nummer.grid(row = 4, column = 0)

#Eingabe Felder
eingabe_Art_Num.grid(row = 0, column = 1)
eingabe_Menge.grid(row = 1, column = 1)
eingabe_Art.grid(row = 2, column = 1)
eingabe_Preis.grid(row = 3, column = 1)
eingabe_Bietername_nummer.grid(row = 4, column = 1)
 
#------------------------------------------------------------------------------------------------------------------------------------------------
#Buttons
Button_Speichern = Button(root, text="Speichern", bg="#DF5651", command = getInput)
Button_Speichern.grid(row=6, column=1, padx=60, pady=0)

Button_Abbruch = Button(master=root, text="Beenden", bg="#DF5651", command=Button_Abbruch)
Button_Abbruch.grid(row=8, column=1, padx=60, pady=10)



root.mainloop()
Hier einmal der Code und ja ich weiss der ist nicht besonderlich gut geschrieben und unübersichtlich. Ich weiss das ich einiges besser machen kann aber für meine erste GUI und zum üben finde ich den noch in Ordnung.
Sirius3
User
Beiträge: 17711
Registriert: Sonntag 21. Oktober 2012, 17:20

Programme werden durch Funktionen gegliedert, nicht durch Kommentarzeilen mit vielen Minusen. Benutze keine *-Importe, weil die unkontrolliert Namen in den eigenen Namensraum schaufeln.
Globale Variablen sind schlecht, weil sie den Programmablauf undurchsichtig machen.
Variablennamen und Funktionen schreibt man nach Konvention komplett klein.
Benutze keine Abkürzungen. Vk_Art, welche Art ist das?
In `Versteigerungs_Li` wird wahrscheinlich Lithium versteigert. Warum hat Window2 eine 2 und Panel 3 eine 3?
In `Button_Abbruch` wird mit einem Wahrheitswert explizit verglichen. Das braucht man nicht, es reicht ein `if result:`.
In `getInput` benutzt Du einbuchstabige Variablen, die sind eigentlich immer schlecht, weil sie nichts aussagen.
Dieses `L` ist sehr komisch, da ist ein Element in der Liste, das wiederum eine Liste von Listen ist?
Die Stringrepräsentation einer Liste ist auch nicht dazu gedacht, dass man sie dauerhaft speichert, sondern dient nur zum Debugging.
Dateien öffnet man innerhalb des with-Statements, damit sie auch sicher wieder geschlossen wird.
`neuer_artikel` hört sich wie Einzahl an, ist aber eine Liste von Artikeln, das ist auch verwirrend.

Alles auf oberster Ebene (also die ersten paar Zeilen nach dem Input und alles ab `menu`) gehört in eine Funktion, die üblicherweise `main` genannt wird.
Das verhindert auch, dass man aus Versehen Variablen als globale Variablen benutzt.

Die Kommentare sind alle nicht hilfreich, weil sie nur beschreiben, was eh im Code steht. Kommentare sollten das "Warum" enthalten.

Dass Labels von den Eingabefeldern getrennt erstellt werden, macht das Lesen sehr unübersichtlich, weil logisch zusammengehörende Widgets nicht beieinander stehen.
Button_Abbruch gibt es einmal als Button und als Funktion.
Kanaax
User
Beiträge: 17
Registriert: Mittwoch 5. August 2020, 09:15

Die Kommentare sind auch nur für mich als Hilfe gedacht damit ich verstehe, was da überhaupt passiert. Die Striche sind ebenfalls nur für mich gedacht als kleine Hilfe.
Mit den Import weiss ich schon und werde ich auch sobald ich wieder im Büro bin ändern.
Das man alles klein schreibt habe ich auch "erfahren" als es zu spät war und dementsprechend habe ich es so weiter geführt(der Code ist nur zum tkinter lernen und verstehen gedacht).
Die Abkürzungen verstehe ich und das reicht ja erstmal daher auch solche bennungen(Vk_Art= Verkaufte Artikel)
Sirius3
User
Beiträge: 17711
Registriert: Sonntag 21. Oktober 2012, 17:20

@Kanaax: heute verstehst Du die Abkürzungen vielleicht noch, nächste Woche nicht mehr.
Kanaax
User
Beiträge: 17
Registriert: Mittwoch 5. August 2020, 09:15

Sorry ich musste los, aber ich antworte mal weiter.
Die "versteigerungs_Li" ist die Liste und "Window2" hat die 2 damit ich für mich weiss das es sozusagen das 2. Fenster ist(nur für mein Verständnis).
Ok das wusste ich nicht und werde ich ab sofort beachten.
Die Buchstaben habe ich auch nur verwendet, da ich weiss das ich sie nur eine Zeile weiter drunter brauche und somit immer genau weiss wofür sie sind.
Das "L" habe ich so aus ein Tutorial übernommen, ich war einfach froh das es entlich geklappt hat und ist im Endeffekt unnötig.
Ok das mit den Stringrepräsentation in einer Liste wusste ich auch nicht und werde ich in Zukunft lassen.
Das mit den Dateien öffnen werde ich in Zukunft auch ändern.
Ja wie gesagt ich wollte erstmal die Grundlagen lernen und somit gucken wie "tkinter" funktioniert.

Ich sehe schon das ich noch einiges im richtigen Programm um ändern muss, wobei ich dann auch OOP möchte.
Vieles habe ich einfach falsch gelernt und weiss es jetzt besser dank der Community hier(hauptsächlich durch dich).

So jetzt zu der neuen Nachricht. Ich habe mir zu allen Abkürzungen Notizen gemacht damit ich immer weiss was die Bedeuten. Klar ist es nicht schön und sollte anders gemacht werden aber es ist immer noch zum lernen von tkinter und um mein Wissen rund um Python zu vertiefen. Ich werde morgen denke ich mal anfangen, das Programm neu zu schreiben und diesesmal berücksichtige ich eure Ratschläge.
Kanaax
User
Beiträge: 17
Registriert: Mittwoch 5. August 2020, 09:15

Code: Alles auswählen

from tkinter import *
import tkinter as tk
from tkinter import messagebox 
import tkinter.ttk as ttk
import sys

#---------------------------------------------------------------------------------------------------------------------
#Liste zum Speichern
neue_artikel = []

#---------------------------------------------------------------------------------------------------------------------
#Fenster layout
root = Tk()
root.title(" Auktionshaus xyz " + "    " + " Artikel einpflegen ")
root.geometry("900x500")

#Icon oben Links 
root.iconbitmap("HOMEME2.png")

#Bild anlegen und positionieren
image1 = PhotoImage(file="HOMEME2.png")
panel1 = Label(root, image = image1)
panel1.grid(row=0, column=5, columnspan=2, rowspan=2, sticky= E + N, padx=3, pady=3)     

#----------------------------------------------------------------------------------------------------------------------
#Funktionen
#Neues fenster für Verkaufte Artikel
def verkaufte_artikel_liste():
    verkaufte_art_window = tk.Toplevel()
    #Layout
    labelExample = tk.Label(verkaufte_art_window, text = " Verkaufte Artikel ")
    verkaufte_art_window.title("Auktionshaus xyz" + "    " + " Verkaufte Artikel ")
    verkaufte_art_window.geometry("720x720")
    panel2 = Label(verkaufte_art_window, image = image1)
    panel2.grid(row=0, column=3, columnspan=2, rowspan=2, sticky= E + N, padx=3, pady=3)

#Neues fenster für Versteigerungs Liste
def versteigerungs_liste():
    versteigerungs_liste_window = tk.Toplevel(root)
    labelExample = tk.Label(versteigerungs_liste_window, text = " Versteigerungsliste ")
    versteigerungs_liste_window.title("Auktionshaus xyz" + "    " + " Versteigerungsliste ")
    versteigerungs_liste_window.geometry("1000x500")
    panel3 = Label(versteigerungs_liste_window, image = image1)
    panel3.grid(row=0, column=3, columnspan=2, rowspan=2, sticky= E + N, padx=3, pady=3)
    Test1 = tk.Listbox(versteigerungs_liste_window, width = 250)
    Test1.insert("end", *neue_artikel)
    Test1.grid()


#Neues fenster für Aktuelle Versteigerung
def versteigerung():
    versteigerung_window = tk.Toplevel()
    labelExample = tk.Label(  versteigerung_window, text = " Aktuelle Versteigerung ")
    versteigerung_window.title("Auktionshaus xyz" + "    " + " Aktuelle Versteigerung ")
    versteigerung_window.geometry("720x720")
    panel4 = Label(versteigerung_window, image = image1)
    panel4.grid(row=0, column=3, columnspan=2, rowspan=2, sticky= E + N, padx=3, pady=3)

#Neues fenster für Unter Vorbehalt Liste
def unter_vorbehalt():
    unter_vorbehalt_window = tk.Toplevel()
    labelExample = tk.Label(unter_vorbehalt_window, text = " Unter Vorbehalt ")
    unter_vorbehalt_window.title("Auktionshaus xyz" + "    " + " Unter Vorbehalt ")
    unter_vorbehalt_window.geometry("720x720")
    panel5 = Label(unter_vorbehalt_window, image = image1)
    panel5.grid(row=0, column=3, columnspan=2, rowspan=2, sticky= E + N, padx=3, pady=3)

#Neues fenster für nicht Verkaufte Artikel
def nicht_verkaufte_artikel():
    nicht_verkaufte_artikel_window = tk.Toplevel()
    labelExample = tk.Label(nicht_verkaufte_artikel_window, text = " Nicht Verkaufte Artikel ")
    nicht_verkaufte_artikel_window.title("Auktionshaus xyz" + "    " + " Nicht Verkaufte Artikel ")
    nicht_verkaufte_artikel_window.geometry("720x720")
    panel6 = Label(nicht_verkaufte_artikel_window, image = image1)
    panel6.grid(row=0, column=3, columnspan=2, rowspan=2, sticky= E + N, padx=3, pady=3)

#Exit Fenster 
def button_abbruch():
    result = tk.messagebox.askyesno("Warnung!",
        "Soll das Programm wirklich geschlossen werden?")
    if result:
        root.destroy()

#Speichern
def getInput():
    button_speichern.bind("<Enter-Keypress-1>")
    result1 = tk.messagebox.askyesno("Speichern",
        "Möchten sie die Daten wirklich Speichern?")
    if result1 == True:
        a = artikelnummer.get()
        b = menge.get()
        c = artikel_beschreibung.get()
        d = mindest_preis.get()
        e = bieter_ident.get()
        f = schriftliches_gebot.get()
        artikel_liste = ["Artikel Nummer: ", a, "Menge: ", b, "Artikel Beschreibung: ", c, "Mindestpreis: ", d, "Bieternummer oder Bietername:", e, "Höhe des Gebots:", f]
        neue_artikel.append(artikel_liste)
        L = [neue_artikel]
        datei = open ('eins.txt', "w")
        datei.write(', '.join((map(str, L))))
        datei.close()
        print (L)

#---------------------------------------------------------------------------------------------------------------------
#Menue 1
menu = Menu()
root.config(menu=menu)
filemenu = Menu(menu)
menu.add_cascade(label="Menü", menu=filemenu)

filemenu.add_command(label="Unter Vorbehalt Liste", command=unter_vorbehalt) 
filemenu.add_command(label="Versteigerungsliste", command=versteigerungs_liste)
filemenu.add_command(label="Aktuelle Versteigerung", command=versteigerung)
filemenu.add_command(label="Verkaufte Artikel", command=verkaufte_artikel_liste)
filemenu.add_command(label="Nicht Verkaufte Artikel", command=nicht_verkaufte_artikel)

#-------------------------------------------------------------------------------------------------------------------------------------------
artikelnummer = tk.StringVar(root)
menge = tk.StringVar(root)
artikel_beschreibung = tk.StringVar(root)
mindest_preis = tk.StringVar(root)
schriftliches_gebot = tk.StringVar(root)
bieter_ident = tk.StringVar(root)


tk.Label(root, text="Artikelnummer:").grid(row=1, column=0)
tk.Entry(root, textvariable=artikelnummer, bd=5, width=40).grid(row=1, column=1)

tk.Label(root, text="Menge:").grid(row=2, column=0)
tk.Entry(root, textvariable=menge, bd=5, width=40).grid(row=2, column=1)

tk.Label(root, text="Artikelbeschreibung:").grid(row=3, column=0)
tk.Entry(root, textvariable=artikel_beschreibung, bd=5, width=40).grid(row=3, column=1)

tk.Label(root, text="Mindestpreis").grid(row=4, column=0)
tk.Entry(root, textvariable=mindest_preis, bd=5, width=40).grid(row=4, column=1)

tk.Label(root, text="Höhe des Gebot").grid(row=6, column=0)
tk.Entry(root, textvariable=schriftliches_gebot, bd=5, width=40).grid(row=6, column=1)

tk.Label(root, text="Bietername oder Nummer:").grid(row=7, column=0)
tk.Entry(root, textvariable=bieter_ident, bd=5, width=40).grid(row=7, column=1)
 
#------------------------------------------------------------------------------------------------------------------------------------------------
#Buttons
button_speichern = Button(root, text="Speichern", bg="#DF5651", command = getInput)
button_speichern.grid(row=8, column=2, padx=60, pady=0)

button_abbruch_layout = Button(master=root, text="Beenden", bg="#DF5651", command=button_abbruch)
button_abbruch_layout.grid(row=8, column=1, padx=60, pady=10)



root.mainloop()
Ich habe meinen Code mal etwas angepasst. Den * import, die Kommentare und das L ändere ich als nächstes.
Antworten