Seite 1 von 1

Tkinter Feld

Verfasst: Freitag 21. März 2014, 09:46
von derbozz
Hallo liebes Python Forum,
ich brauche Hilfe bei einem Schulprojekt.
Ich versuche einen Tunierplan zu erstellen mit Hilfe von Tkinter.
Zuerst wird der Benutzer über Eckdaten über das Tunier gefragt z.B. den Namen oder die Anzahl der Teams und diese Daten werden dann auch definiert und gespeichert.
Jetzt zu Tkinter und meinem Problem. Ich will die definierten Namen dann auch in ein Tkinter Feld einfügen lassen und genau das schaffe ich nicht.
Das sieht so aus:

Code: Alles auswählen

main = Tk()
main.configure(bg="blue")#hintergrundfarbe
main.title("Volleyballturnier")#name des fensters
#main.resizable(width=NO, height=NO)#das fenster kann nicht vergroesert werden

######################################################


####################container
Container1=Frame(main,height=100,width=500)#bereiche in die das fenster aufgeteilt wird
Container2=Frame(main,height=100,width=500)
Container3=Frame(main,height=100,width=500)
Container4=Frame(main,height=100,width=500)
Container5=Frame(main,height=100,width=500)


###################bestimmung was im programm ist
Eingabefeld1= Entry(Container1,                 bg='red')
    #in welches bereich kommt das eingabefeld   #hintergrundfarbe
Eingabefeld2= Entry(Container2,bg='yellow')
Eingabefeld3= Entry(Container3,bg="green")
Eingabefeld4= Entry(Container4,bg="grey")
Eingabefeld5= Entry(Container5,bg="purple")
Text1=Label(Container1,text='Turniername: ')
Text2=Label(Container2,text='Turnierdatum:')
Text3=Label(Container3,text='Startzeit:  ')
Text4=Label(Container4,text='Anzahl der Teams:  ')
Text5=Label(Container5,text='Anzahl der Felder:  ')
Knopf1=Button(Container6,text="speichern",command=speichern)

########################.pack sachen
Container1.pack(expand=YES)#expand lasst das fenster mitwachsen wenn das fenster grosser wird
Container2.pack(expand=YES)
Container3.pack(expand=YES)
Container4.pack(expand=YES)
Container5.pack(expand=YES)
Text1.pack(side=LEFT)#side = "grosschreibe" zur bestimmung wo
Eingabefeld1.pack(side=LEFT)
Text2.pack(side=LEFT)
Eingabefeld2.pack(side=LEFT)
Text3.pack(side=LEFT)
Eingabefeld3.pack(side=LEFT)
Text4.pack(side=LEFT)
Eingabefeld4.pack(side=LEFT)
Text5.pack(side=LEFT)
Eingabefeld5.pack(side=LEFT)                
Knopf1.pack()
#########################################

main.mainloop()
Währe nett wenn mir jemand helfen könnte.

Re: Tkinter Feld

Verfasst: Freitag 21. März 2014, 11:32
von BlackJack
@derbozz: Grundsätzlich ist die Frage ein wenig schwammig. Beim schauen über den Quelltext fällt auf dass es weder einen `Container6` noch eine `speichern()`-Funktion gibt. Von den fehlenden ``import``-Zeilen abgesehen, sind das die Gründe warum das so nicht läuft, sondern mit ganz sicher mit einem `NameError` aussteigen wird.

Ansonsten sind in dem Quelltext einige schlechte Ansätze.

Sternchenimporte sollte man vermeiden. Damit holt man sich *alle* Namen aus einem Modul in das importierende Modul. Das sind bei `Tkinter` um die 190 Stück. Üblicherweise importiert man das Modul und benennt es dabei in `tk` um, damit man nicht so viel Tippen muss, beim Lesen aber klar ist woher ein Wert kommt.

Wenn man anfängt Namen durchzunummerieren ist das in der Regel ein „code smell“, also ein Hinweis darauf das man etwas falsch macht. Statt dieser einzelnen Namen will man an der Stelle normalerweise eine Datenstruktur verwenden. Häufig eine Liste, manchmal auch etwas anderes.

Bei der Schreibweise von Namen gibt es Konventionen an die man sich halten sollte, damit Leser nicht verwirrt werden, zum Beispiel durch führende Grossbuchstaben bei Werten die gar kein Datentyp sind. Ausserdem gibt es Empfehlungen zum setzen von Leerzeichen um die Lesbarkeit zu erleichtern. Das steht alles im Style Guide for Python Code.

Die Namen sind auch fast alle viel zu generisch. Ein Name soll dem Leser vermitteln was der Wert dahinter im Kontext des Programms bedeutet. `Container3` oder `Knopf1` sagt so gut wie nichts aus. Was wird in dem Container-Widget angezeigt? Was bewirkt der Knopf wenn er gedrückt wird? Aber auch: ist der Name wirklich so wichtig, dass er eindeutig sein muss? Denn einige von den Namen könnte man problemlos wiederverwenden wenn man den Quelltext anders anordnen würde. Nämlich nicht immer erst alle Objekte von einem Typ erstellen und dann immer nacheinander für all diese Objekte das selbe tun, sondern die Sachen die sinngemäss zusammen gehören auch im Quelltext zusammenfassen. Einen Container für Beschriftung und Eingabefeld erstellen, beides erzeugen und dort hinein stecken und dann den Container in das übergeordnete Widget stecken sollte nicht so weit über den Quelltext verteilt sein. Dann hat man auch die Möglichkeit das ganze durch herausziehen der gemeinsamen Struktur durch eine Funktione und/oder Schleife zu verkürzen.

Last but not least bin ich der Meinung das GUI-Programme erst angegangen werden sollten wenn man objektorientierte Programmierung halbwegs sicher anwenden kann, denn für ein ordentliches, sauberes GUI-Programm braucht man IMHO Klassen.

Re: Tkinter Feld

Verfasst: Freitag 21. März 2014, 15:15
von wuf
Hi derbozz

Hier eine mögliche Variante mit einer Klasse. Farben würde ich sparsam einsetzen :wink: :

Code: Alles auswählen

import Tkinter as tk
from functools import partial

TITLE = "Volleyballturnier"

ENTRY_PROPERTIES = (
    ('red', 'yellow', 'Turniername'),
    ('yellow', 'blue', 'Turnierdatum'),
    ('green', 'black', 'Startzeit'),
    ('grey', 'blue', 'Anzahl der Teams'),
    ('purple', 'white', 'Anzahl der Felder')
    )

MAX_LABEL_WIDTH = 18
MAX_ENTRY_WIDTH = 20

class EntryContainer(tk.Frame):
    
    def __init__(self, parent, bg, fg, entry_name, callback):
        
        tk.Frame.__init__(self, parent)
        tk.Label(self, text='{0}: '.format(entry_name), anchor='e',
            width=MAX_LABEL_WIDTH).pack(side='left')
        self.entry = tk.Entry(self, width=MAX_ENTRY_WIDTH, bg=bg,fg=fg,
            highlightthickness=0)
        self.entry.pack()
        self.entry.bind('<Return>', partial(callback, entry_name))
    
def speichern():
    print 'Speichern'

def entry_callback(entry_name, args):
    entry_value = args.widget.get()
    print entry_name, entry_value

class App(tk.Tk):
    
    def __init__(self, title):  
        tk.Tk.__init__(self)
        self.title()
        self.entries = dict()
        self.build_entries()
        self.entries['Turniername'].entry.focus_set()

    def build_entries(self):
        for bg, fg, entry_name in ENTRY_PROPERTIES:
            entry_container = EntryContainer(self, bg, fg,
                entry_name, entry_callback)
            entry_container.pack(fill='x', padx=5, pady=2)
            self.entries[entry_name] = entry_container
        
        tk.Button(self, text="speichern", command=speichern,
            highlightthickness=0).pack(pady=5)

    def run(self):
        self.mainloop()

App(TITLE).run()
Gruss wuf :wink:

Re: Tkinter Feld

Verfasst: Freitag 21. März 2014, 18:24
von wuf
Hier noch ein paar kleine Änderungen:

Code: Alles auswählen

from functools import partial
try:
    import Tkinter as tk
except ImportError:
    import tkinter as tk

TITLE = "Volleyballturnier"

ENTRY_PROPERTIES = (
    ('red', 'yellow', 'Turniername'),
    ('yellow', 'blue', 'Turnierdatum'),
    ('green', 'black', 'Startzeit'),
    ('grey', 'blue', 'Anzahl der Teams'),
    ('purple', 'white', 'Anzahl der Felder')
    )

MAX_LABEL_WIDTH = 18
MAX_ENTRY_WIDTH = 20

class EntryContainer(tk.Frame):
    
    def __init__(self, parent, bg, fg, entry_name, callback):
        
        tk.Frame.__init__(self, parent)
        tk.Label(self, text='{0}: '.format(entry_name), anchor='e',
            width=MAX_LABEL_WIDTH).pack(side='left')
        self.entry = tk.Entry(self, width=MAX_ENTRY_WIDTH, bg=bg,fg=fg,
            highlightthickness=0)
        self.entry.pack()
        self.entry.bind('<Return>', partial(callback, entry_name))
    
class App(tk.Tk):
    
    def __init__(self, title):  
        tk.Tk.__init__(self)
        self.title(title)
        self.entries = dict()
        self.build_entries()
        self.entries['Turniername'].entry.focus_set()

    def build_entries(self):
        for bg, fg, entry_name in ENTRY_PROPERTIES:
            entry_container = EntryContainer(self, bg, fg,
                entry_name, self.entry_callback)
            entry_container.pack(fill='x', padx=5, pady=(4,0))
            self.entries[entry_name] = entry_container
        
        tk.Button(self, text="speichern", command=self.speichern,
            highlightthickness=0).pack(pady=5)

    def speichern(self):
        print('Speichern')

    def entry_callback(self, entry_name, args):
        entry_value = args.widget.get()
        print(entry_name, entry_value)

    def run(self):
        self.mainloop()

App(TITLE).run()
wuf :wink:

Re: Tkinter Feld

Verfasst: Donnerstag 27. März 2014, 07:49
von derbozz
Danke wuf,
ich habe dein Programm mal ausprobiert und es klappt sehr gut.
Allerdings frage ich in meinem Programm am Anfang Eckdaten zum Tunier ab.
Ich versuche diese Eckdaten in dem Tkinterfeld erscheinen zu lassen.
Gruß derbozz

Re: Tkinter Feld

Verfasst: Donnerstag 27. März 2014, 08:19
von derbozz
Das ist meine Abfrage habt ihr villeicht vorschläge wie ich die obtimieren kann ?

Code: Alles auswählen

from PIL import Image

import csv
#zahlen kontrollen
def ist_zahl(s):
    try:
        float(s)
        return True
    except ValueError:
        return False
#Desing
#fenster = Tk()  
#fenster.minsize(400,300)
#photo = PhotoImage(file="vettel") 
#label = Label(image=photo)
#label.image = photo
#label.pack()
     
#Button=Button(image=photo)
#Button.image = photo
#Button.pack()
#name des turniers
name = raw_input("Wie soll das Turnier heissen?")
 
#datum
datum = raw_input("Wann soll das Turnier stattfinden?(ttmmjj)")
adatum = len(datum)
while adatum !=6 :
    print"Es werden nur Eingaben in dem Format ttmmjj akzeptiert."
    datum = raw_input("Wann soll das Turnier stattfinden?(ttmmjj)")
    adatum = len(datum)
while ist_zahl(datum) == False:
    print"Bitte nur Zahlen eingeben."
    datum = raw_input("Wann soll das Turnier stattfinden?(ttmmjj)")
adatum = int(datum)
     
#startzeit   
startzeit = raw_input("Wie spaet soll das Turnier beginnen?(hhmm)")
astartzeit = len(startzeit)
while astartzeit != 4:
    print"Es werden nur Eingaben in dem Format hhmm akzeptiert."
    startzeit = raw_input("Wie spaet soll das Turnier beginnen?(hhmm)")
    astartzeit = len(startzeit)
while ist_zahl(startzeit) == False:
    print"Bitte nur Zahlen eingebe.n"
    startzeit = raw_input("Wie spaet soll das Turnier beginnen?(hhmm)")
 
#anzahlteams  
anzahlteams = raw_input("Wie viele Teams nehmen teil?")
while ist_zahl(anzahlteams) == False:
    print"Bitte nur Zahlen eingeben."
    anzahlteams = raw_input("Wie viele Teams nehmen teil?")
anzahlteams = int(anzahlteams)
 
#anzahlfelder
anzahlfelder = raw_input("Wie viele Felder stehen zur verfuegung?")
while ist_zahl(anzahlfelder) == False:
    print"Bitte nur Zahlen eingeben."
    anzahlfelder = raw_input("Wie viele Felder stehen zur verfuegung?")
anzahlfelder = int(anzahlfelder)
 
tag = int(datum[0:2])
monat = int(datum[2:4])
jahr = int(datum[4:6])
stunde = int(startzeit[0:2])
minute = int(startzeit[2:4])
dateiname = name + "-" + datum + ".csv"
 
d={}
 
with open(dateiname,"wb") as f:
    w = csv.writer(f,delimiter=";")
    w.writerow(["Name","Datum","Startzeit","Anzahlfelder"])
    w.writerow([name, datum, startzeit, anzahlfelder])
    w.writerow([""])
    w.writerow(["Teams"])
    for i in range(anzahlteams):
        teamnr = i+1
        print"Wie heisst das",teamnr,". Team?"
        eingabe = raw_input()
        d["string{0}".format(teamnr)] = eingabe
        w.writerow([eingabe])
    print "Gespeichert unter dem Namen", dateiname


def speichern():
    s1=Eingabefeld1.get()
    s2=Eingabefeld2.get()
    s3=Eingabefeld3.get()
    s4=Eingabefeld3.get()
    s5=Eingabefeld3.get()
    dateiname=s1 + ".csv"
    with open(dateiname,"wb") as f:
        w = csv.writer(f,delimiter=";")
        w.writerow([s1,s2,s3,s4,s5])

Re: Tkinter Feld

Verfasst: Donnerstag 27. März 2014, 10:16
von BlackJack
@derbozz: Da Einrückung in Python-Code wichtig ist, verwende doch bitte Code-Tags für Quelltext im Beitrag.

Vorschläge: Unbenutzte Importe und auskommentierten Quelltext sollte man entsorgen. Genauso unbenutzen Code wie die `speichern()`-Funktion. Das ist nur unnötiger Ballast für den Leser.

Ganz generell kannst Du mal einen Blick in den Style Guide for Python Code werfen.

Namen sollen dem Leser vermitteln welche Bedeutung der Wert der daran gebunden ist, im Programm hat. Einbuchstabige Namen tun das nur selten und sollten auf Zählvariablen und wirklich kurzen, überschaubaren Kontext, beispielsweise „list comprehensions” oder Generatorausdrücke, beschränkt werden.

Wie soll man bei dem Namen `adatum` darauf kommen dass der Wert dahinter die Länge einer Zeichenkette ist? Wie bist Du auf diesen Namen gekommen? Warum bindest Du diesen Wert überhaupt an einen Namen? Der wird nur an einer Stelle verwendet, und an dieser einen Stelle könnte man auch einfach die `len()`-Funktion anwenden. Und dann wird `adatum` nach der Eingabe auch noch an etwas ganz anderes gebunden, aber überhaupt nicht mehr verwendet‽

Kommentare sind dazu da dem Leser Informationen zu vermitteln die nicht schon trivial aus dem Quelltext den sie kommentieren zu ersehen ist. Dazu müssen sie sprachlich korrekt sein. Was bei ``#zahlen kontrollen`` nicht der Fall sein. Die anderen Kommentare im Programm wiederholen bis auf eine Ausnahme einfach nur den Variablennamen der in der nächsten Zeile an einen Wert gebunden wird. Welchen Sinn soll das haben? Wenn man in einem Kommentar einen Variablennamen erklärt, sollte man noch einmal über den Namen nachdenken, ob der nicht so gut sein könnte, dass man sich den Kommentar sparen kann. Statt einen Wert `name` zu nennen und zu kommentieren, dass es sich um den Namen des Turniers handelt, hätte man ihn ohne Kommentar auch einfach `turniername` nennen können.

Auf Modulebene sollte man nur Definitionen von Konstanten, Funktionen, und Klassen stehen haben und nicht Hauptprogramm direkt auf Modulebene. Üblicherweise kommt das in eine Funktion mit dem Namen `main()`. Wenn man dann auch noch Hauptprogramm und Funktionsdefinitionen vermischt, wird es schnell unübersichtlich.

Die `ist_zahl()`-Funktion müsste korrekter `ist_gleitkommazahl()` heissen. Dann fällt auch eher auf, dass sie ungeeignet ist, wo sie im Programm verwendet wird, denn dort werden überall ganze Zahlen erwartet.

Innerhalb der Eingabe eines Wertes gibt es viele Wiederholungen und der gesamte Code zur Eingabe eines Wertes wiederholt sich fast identisch im Quelltext. So etwas sollte man vermeiden. Durch geschicktere Strukturierung des Codes und durch Funktionen und/oder Schleifen wo das gemeinsame von den Unterschieden getrennt wird, so dass man den gemeinsamen Teil nur einmal schreiben muss. Eine Zeile wie ``datum = raw_input('Wann soll das Turnier stattfinden?(ttmmjj)')`` sollte nicht *drei* mal identisch in einem Quelltextabschnitt stehen, sondern nur *einmal*. Wenn man den Text ändern möchte muss man das dann zum Beispiel nur noch an einer Stelle machen und nicht an drei, mit der Gefahr dass man eine vergisst, oder nicht alle drei Stellen gleich verändert.

Diese beiden ersten Quelltextabschnitte, welche die Eingabe sowohl auf Länge als auch auf (Gleitkomma)Zahl testen sind übrigens fehlerhaft. Wenn man etwas mit der passenden Länge eingibt was aber keine Gleitkommazahl ist, dann kommt man in die zweite Schleife, die dann zwar prüft das man nur Gleitkommazahlen eingeben kann, aber die Länge der Eingabe wird überhaupt nicht mehr beachtet. Man könnte bei der Eingabe des Datums also zum Beispiel aabbcc eingeben und dann 42 und das wird dann einfach übernommen obwohl es nicht sechs Zeichen lang ist.

Man könnte eine Eingabe mit beiden Prüfungen und ohne ganze Quelltextzeilen zu wiederholen zum Beispiel so schreiben:

Code: Alles auswählen

    while True:
        datum = raw_input('Wann soll das Turnier stattfinden? (ttmmjj)')
        if len(datum) == 6 and datum.isdigit():
            break
        print 'Eingabe entspricht nicht dem erwarteten Format (ttmmjj).'
Vergleiche mit literalen `True` oder `False` sind schlechter Stil, weil in der Regel überflüssig. Wenn man auf einen gegenteiligen Wahrheitswert testen möchte, kann man ``not`` verwenden. Also anstatt ``if is_spam(value) == False:`` besser ``if not is_spam(value):``.

Die ersten beiden Eingaben sind Zeichenketten die nur aus Ziffern bestehen dürfen und eine feste Länge haben. Dafür kann man eine Funktion schreiben, und muss den Code dann nicht zweimal schreiben. Die beiden Quelltextabschnitte unterscheiden sich im Grunde ja nur durch den Inhalt des Prompts für den Benutzer und dem Muster und der Länge der korrekten Eingabe.

Die beiden folgenden Eingaben sind ganze Zahlen. Am besten positiv und grösser 0 würde auch Sinn machen. Auch diese Eingabe samt Tests kann man in einer Funktion kapseln.

`tag`, `monat`, `jahr`, `stunde`, und `minute` werden zwar definiert, aber nirgends verwendet. Weg damit. Genau so das Wörterbuch `d` das zwar gefüllt, aber nicht verwendet wird. Da ist mir sowieso nicht klar was der Sinn von den Schlüsseln sein soll.

Das Speichern der Daten könnte man in eine eigene Funktion auslagern, möglichst ohne Benutzerinteraktion. Das heisst die Teamnamen sollten ausserhalb der Speicherfunktion vom Benutzer erfragt werden.

Ob CSV so besonders gut geeignet ist, wage ich zu bezweifeln. Zumindest wenn man die Daten auch wieder in einem eigenen Programm einlesen möchte ist das eher für „regelmässige” Daten geeignet. Ansonsten muss man unnötige Arbeit in das auswerten und testen der Daten stecken, die man bei Formaten wie JSON beispielsweise nicht hätte, weil sich der Parser dort zumindest um das Format und die Grunddatentypen kümmert.

Ich komme als Zwischenergebnis jedenfalls auf so etwas (untetestet):

Code: Alles auswählen

#!/usr/bin/python
import csv


def ask_digit_string(prompt, pattern):
    prompt = '{0} ({1})'.format(prompt, pattern)
    while True:
        result = raw_input(prompt)
        if len(result) == len(pattern) and result.isdigit():
            return result
        print 'Eingabe entspricht nicht dem erwarteten Format', pattern


def ask_count(prompt):
    while True:
        try:
            result = int(raw_input(prompt))
        except ValueError:
            print 'Bitte eine ganze Zahl eingeben.'
        else:
            if result >= 1:
                return result
            else:
                print 'Die Anzahl muss mindestens 1 betragen.'


def main():
    turniername = raw_input('Wie soll das Turnier heissen?')
    datum = ask_digit_string('Wann soll das Turnier stattfinden?', 'ttmmjj')
    startzeit = ask_digit_string('Wie spaet soll das Turnier beginnen?', 'hhmm')
    anzahlteams = ask_count('Wie viele Teams nehmen teil?')
    anzahlfelder = ask_count('Wie viele Felder stehen zur verfuegung?')
     
    dateiname = '{0}-{1}.csv'.format(turniername, datum)
    with open(dateiname, 'wb') as out_file:
        writer = csv.writer(out_file, delimiter=';')
        writer.writerows(
            [
                ['Name', 'Datum', 'Startzeit', 'Anzahlfelder'],
                [turniername, datum, startzeit, anzahlfelder],
                [],
                ['Teams'],
            ]
        )
        for teamnr in xrange(1, anzahlteams + 1):
            teamname = raw_input('Wie heisst das {0}. Team?'.format(teamnr))
            writer.writerow([teamname])
        print 'Gespeichert unter dem Namen', dateiname


if __name__ == '__main__':
    main()
Was man als nächstes angehen könnte wären die passenden Datentypen für Datum und Zeit zu verwenden (`datetime`-Modul) und entsprechende Eingabefunktionen zu schreiben. Denn im Moment kann der Benutzer ja noch den 99 Tag im 42 Monat als Datum angeben oder 33 Uhr 90 als Uhrzeit.

Re: Tkinter Feld

Verfasst: Freitag 28. März 2014, 09:55
von derbozz
@BlackJack
[Was man als nächstes angehen könnte wären die passenden Datentypen für Datum und Zeit zu verwenden (`datetime`-Modul) und entsprechende Eingabefunktionen zu schreiben. Denn im Moment kann der Benutzer ja noch den 99 Tag im 42 Monat als Datum angeben oder 33 Uhr 90 als Uhrzeit.]

Das hatte ich auch als nächsten Schritt vor da unsere Lehrer viel Wert auf Fehlerprüfung legen.

Re: Tkinter Feld

Verfasst: Freitag 28. März 2014, 10:04
von derbozz
Ich habe jetzt verstanden das ich ein sehr schlechter Programmierer bin.
Aber um nochmal auf mein Problem zurückzukommen:
ich versuche die am Anfang des Programmes abgefragten Daten des Tunieres später im Tkinterfeld erscheinen zu lassen.
Bis jetzt habe ich nur so viel:

Code: Alles auswählen

from PIL import Image

import csv
#zahlen kontrollen
def ist_zahl(s):
    try:
        float(s)
        return True
    except ValueError:
        return False
#Desing
#fenster = Tk()  
#fenster.minsize(400,300)
#photo = PhotoImage(file="vettel") 
#label = Label(image=photo)
#label.image = photo
#label.pack()
     
#Button=Button(image=photo)
#Button.image = photo
#Button.pack()
#name des turniers
import csv
 
 
def ask_digit_string(prompt, pattern):
    prompt = '{0} ({1})'.format(prompt, pattern)
    while True:
        result = raw_input(prompt)
        if len(result) == len(pattern) and result.isdigit():
            return result
        print 'Eingabe entspricht nicht dem erwarteten Format', pattern
 
 
def ask_count(prompt):
    while True:
        try:
            result = int(raw_input(prompt))
        except ValueError:
            print 'Bitte eine ganze Zahl eingeben.'
        else:
            if result >= 1:
                return result
            else:
                print 'Die Anzahl muss mindestens 1 betragen.'
 
 
def main():
    turniername = raw_input('Wie soll das Turnier heissen?')
    datum = ask_digit_string('Wann soll das Turnier stattfinden?', 'ttmmjj')
    startzeit = ask_digit_string('Wie spaet soll das Turnier beginnen?', 'hhmm')
    anzahlteams = ask_count('Wie viele Teams nehmen teil?')
    anzahlfelder = ask_count('Wie viele Felder stehen zur verfuegung?')
     
    dateiname = '{0}-{1}.csv'.format(turniername, datum)
    with open(dateiname, 'wb') as out_file:
        writer = csv.writer(out_file, delimiter=';')
        writer.writerows(
            [
                ['Name', 'Datum', 'Startzeit', 'Anzahlfelder'],
                [turniername, datum, startzeit, anzahlfelder],
                [],
                ['Teams'],
            ]
        )
        for teamnr in xrange(1, anzahlteams + 1):
            teamname = raw_input('Wie heisst das {0}. Team?'.format(teamnr))
            writer.writerow([teamname])
        print 'Gespeichert unter dem Namen', dateiname
 
 
if __name__ == '__main__':
    main()


def speichern():
    s1=Eingabefeld1.get()
    s2=Eingabefeld2.get()
    s3=Eingabefeld3.get()
    s4=Eingabefeld3.get()
    s5=Eingabefeld3.get()
    dateiname=s1 + ".csv"
    with open(dateiname,"wb") as f:
        w = csv.writer(f,delimiter=";")
        w.writerow([s1,s2,s3,s4,s5])

        
from functools import partial
try:
    import Tkinter as tk
except ImportError:
    import tkinter as tk
 
TITLE = "Volleyballturnier"
 
ENTRY_PROPERTIES = (
    ('red', 'yellow', 'Turniername'),
    ('yellow', 'blue', 'Turnierdatum'),
    ('green', 'black', 'Startzeit'),
    ('grey', 'blue', 'Anzahl der Teams'),
    ('purple', 'white', 'Anzahl der Felder')
    )
 
MAX_LABEL_WIDTH = 18
MAX_ENTRY_WIDTH = 20
 
class EntryContainer(tk.Frame):
   
    def __init__(self, parent, bg, fg, entry_name, callback):
       
        tk.Frame.__init__(self, parent)
        tk.Label(self, text='{0}: '.format(entry_name), anchor='e',
            width=MAX_LABEL_WIDTH).pack(side='left')
        self.entry = tk.Entry(self, width=MAX_ENTRY_WIDTH, bg=bg,fg=fg,
            highlightthickness=0)
        self.entry.pack()
        self.entry.bind('<Return>', partial(callback, entry_name))
   
class App(tk.Tk):
   
    def __init__(self, title):  
        tk.Tk.__init__(self)
        self.title(title)
        self.entries = dict()
        self.build_entries()
        self.entries['Turniername'].entry.focus_set()
 
    def build_entries(self):
        for bg, fg, entry_name in ENTRY_PROPERTIES:
            entry_container = EntryContainer(self, bg, fg,
                entry_name, self.entry_callback)
            entry_container.pack(fill='x', padx=5, pady=(4,0))
            self.entries[entry_name] = entry_container
       
        tk.Button(self, text="speichern", command=self.speichern,
            highlightthickness=0).pack(pady=5)
 
    def speichern(self):
        print('Speichern')
 
    def entry_callback(self, entry_name, args):
        entry_value = args.widget.get()
        print(entry_name, entry_value)
 
    def run(self):
        self.mainloop()
 
App(TITLE).run()

Re: Tkinter Feld

Verfasst: Freitag 28. März 2014, 10:05
von derbozz
Und ich Verstehe immer noch nicht wie das mit dem Python Code geht...
Danke für eure Hilfe

Re: Tkinter Feld

Verfasst: Freitag 28. März 2014, 10:45
von derbozz
Ich habe mir grade mal überlegt, dass es viel effizienter ist die Abfrage am Anfang wegzulassen und nur in das Tkinterfeld eintragen zu lassen. Und das Tkinterfeld habe ich ja schon. :idea:
Zwei Frage habe ich noch:
Ist es auch in dem Tkinterfeld möglich eine Fehlerkontrolle einzubauen?
Wie bekomme ich das so hin, dass ich je nachdem wie viele Teams teilnehmen auch soviele Teamnamen erfragt werden, denn die sind auch sehr wichtig ?

Aber leider ist das Thema damit noch lange nicht abgeschlossen. Als nächsten Schritt benötige ich ein Programm, das aus den gespeicherten Daten vom Tkinterfeld eine Gruppenphase erstellt.
Leider habe ich da noch überhaubt keinen Ansatz oder eine Ahnung wie ich das machen soll. :cry:
Wäre schön wenn mir jemand helfen kann. :lol:

Re: Tkinter Feld

Verfasst: Samstag 29. März 2014, 12:12
von BlackJack
@derbozz: Ich denke Du hast Dich da ein wenig übernommen. Das letzte Programm war ja im Grunde nur zwei Quelltexte, die nicht von Dir waren, hintereinander in eine Datei kopiert, in der Hoffnung da kommt irgend etwas sinnvolles bei heraus, aber wahrscheinlich ohne den ganzen Quelltext verstanden zu haben. Das macht keinen Sinn.

Für eine sinnvolle GUI muss man IMHO objektorientierte Programmierung halbwegs beherrschen. Das Beispiel von wuf verwendet das ja auch. Also würde ich an Deiner Stelle das Thema GUI erst einmal hinten anstellen und die Datenstrukturen und die Programmlogik in Angriff nehmen. Du kannst das ganze ja erst einmal als Konsolenprogramm schreiben. Dabei darauf achten das Programmlogik und die Kommunikation mit dem Benutzer sauber getrennt ist, dann kann man später wenn die Programmlogik an sich funktioniert, auch darüber nachdenken eine GUI drauf zu setzen.

Re: Tkinter Feld

Verfasst: Freitag 4. April 2014, 08:53
von derbozz
ja hab ich auch aber das sind nunmal unsere Aufgaben.
Wir haben hier durchaus eine schwierige Aufgabe aber irgendwie versuche ich sie halt zu lösen