Input in Textdokument schreiben für Adressbuch

Fragen zu Tkinter.
Antworten
RpiMichi
User
Beiträge: 2
Registriert: Donnerstag 15. August 2013, 13:21

Hey,

Ich habe mir nun endlich einen Raspberry Pi gekauft und wollte gleich mal in Python einsteigen. Dazu habe ich mir als Aufgabe gesetzt, ein Adressbuch zu programmieren. Alles geht soweit, nur ich komme nicht drauf, wie ich hier einen Button zum Speichern der Labels+Entries komme. Könnt ihr mir helfen? :)

Code: Alles auswählen

#!/usr/bin/python
#-*- coding: utf-8 -*-
import sys
import tkMessageBox
from Tkinter import *
import Tkinter as tk
import Tkinter
import tkMessageBox

root=Tkinter.Tk()
root.geometry('450x450+200+200')
root.title('Adressbuch')
center=Label(text="Adressbuch für den Raspberry Pi",fg="red").pack()

def name():
    mtext=name.get()
    namelabel=Label(mGui, text=name).pack()
def adresse():
    mtext=adresse.get()
    adresselabel=Label(mGui, text=adresse).pack()
def wohnort():
    mtext=wohnort.get()
    wohnortlabel=Label(mGui, text=wohnort).pack()
def telefon():
    mtext=telefon.get()
    telefonlabel=Label(mGui, text=telefon).pack()
def geburtstag():
    mtext=geburtstag.get()
    geburtstaglabel=Label(mGui, text=geburtstag).pack()
def beenden():
    if tkMessageBox.askokcancel("Beenden", "Möchten Sie das Adressbuch wirklich schließen?"):
                                root.destroy()
                                root.mainloop()


nametext=Label(text="Namen eingeben:").place(x=0, y=20)
name=Entry(root, textvariable=name).place(x=200, y=20)

adressetext=Label(text="Adresse eingeben:").place(x=0, y=40)
adresse=Entry(root, textvariable=adresse).place(x=200, y=40)

wohnorttext=Label(text="Wohnort eingeben:").place(x=0, y=60)
wohnort=Entry(root, textvariable=wohnort).place(x=200, y=60)

telefontext=Label(text="Telefonnummer eingeben:").place(x=0, y=80)
telefon=Entry(root, textvariable=telefon).place(x=200, y=80)

geburtstagtext=Label(text="Geburtstag eingeben:").place(x=0, y=100)
geburtstag=Entry(root, textvariable=geburtstag).place(x=200, y=100)

exitbutton=Button(text="Adressbuch beenden", command=beenden).place(x=0, y=250)

root.mainloop()

und hier mal dasselbe Script fürs Terminal, wo das Speichern funktioniert ;)

Code: Alles auswählen

#!/usr/bin/python
#-*- coding: utf-8 -*-
import sys

print "Adressbuch für den Raspberry Pi"

n=raw_input("Namen eingeben:")
a=raw_input("Adresse eingeben:")
o=raw_input("Ort eingeben:")
t=raw_input("Telefonnummer eingeben:")
g=raw_input("Geburtstag eingeben:")

print " "
print "Der Kontakt wird in der Datei Adressbuch.txt gespeichert"

sys.stdout = open("Adressbuch.txt", "a")

print " "
print "Name: " + str(n) 
print "Adresse: " + str(a)
print "Wohnort: " + str(o)
print "Telefonnummer: " + str(t)
print "Geburtstag: " + str(g)
Über ein wenig Hilfe würde ich mich freuen. Schön wäre es wenn es mit wenigen Zeilen gehen würde und ohne .self oder irgendeine andere class, da ich erst am Lernen bin und nicht mit allem gleichzeitig beschäftigen kann/möchte. Vielen Dank schonmal :D
BlackJack

@RpiMichi: Das Speichern bei der Konsolenanwendung mag zwar so funktionieren, ist aber merkwürdig bis schlecht gelöst. Du öffnest doch sowieso schon eine Datei zum schreiben, warum muss dann dieser komische Umweg über das „umbiegen” von der Standardausgabe gemacht werden, statt die Methoden des Dateiobjekts zu verwenden, was irgendwie naheliegender und weniger problembehaftet ist.

Die Namen könnten deutlich besser gewählt werden als `n`, `o`, `a`, `t`, und `g`. Da weiss doch kein Mensch anhand des Namens was der Wert dahinter im Kontext des Programms bedeutet.

Man sollte auch nicht unbedingt neue Datenformate erfinden wenn es schon vorhandene gibt, die man verwenden kann. Es würde sich zum Beispiel CSV anbieten. Da gibt es das `csv`-Modul in der Standardbibliothek. Bei strukturierteren Daten böte sich JSON an. Auch da hat die Standardbibliothek ein Modul.

Eine Leerzeile lässt sich visuell nicht von einer Zeile mit nur einem Leerzeichen unterscheiden, aber einfacher ausgeben, indem man einfach nur ``print`` schreibt, ohne weitere Werte.

Die GUI geht so gar nicht. Place mag funktionieren solange das nur für Deinen Raspi ist und niemals irgendwo anders gut aussehen oder in Extremfällen benutzbar sein soll.

Die Importe sind das reine Chaos. Den mit dem Sternchen sollte man überhaupt nicht machen, weil das alle 200+ Namen aus dem `Tkinter`-Modul in den Namensraum vom importierenden Modul holt. Idiomatisch wäre der ``import Tkinter as tk``, den Du zwar machst, `tk` dann aber gar nicht nutzt.

Viele der Widgets bekommen bei Dir kein Elternobjekt übergeben, das kann zu komischen Ergebnissen bei der GUI führen. `mGui` scheint nirgends definiert zu sein. Die Funktionen machen so alle keinen Sinn. Ausserdem heissen sie wie die `StringVar`-Exemplare auch heissen, die Du verwenden möchtest, aber nirgends an die Namen bindest. Du hast also kein Problem einen Speichern-`Button` einzubauen, sondern das überhaupt laufen zu lassen.

Ich denke bevor Du GUI-Programme anfängst solltest Du Dich erst mit Funktionen befassen, und dann mit objektorientierter Programmierung (OOP). Ohne sicheren Umgang mit OOP und eigene Klassen schreiben zu können, kann man keine sinvolle GUI programmieren die auch nur etwas komplexer als ein „Hello World”-Beispiel ist.

Wenn man aber sowieso schon OOP drauf hat, kann man auch erst einmal die Geschäftslogik von einem Adressbuch entsprechend modellieren, bevor man da eine GUI drauf setzt.
RpiMichi
User
Beiträge: 2
Registriert: Donnerstag 15. August 2013, 13:21

Vielen Dank für dein Antwort!

Bin zwar jetzt leicht enttäuscht, dass ich das alles falsch gemacht habe, verstehe aber was du meinst. Ich glaube ich habe mich auch ein wenig zu schnell auf das ganze gestürzt (bin auch gerade mal 15 und dachte jetzt in den Ferien beschäftige ich mich mal ein wenig mehr damit, da ich später auf jeden Fall Informatik studieren möchte). Vielleicht sollte ich erstmal klein anfangen ;)

Das mit den Namen sehe ich ein, die Variablen nur mit einem Buchstaben zu belegen ist nicht ganz so sinnvoll, das stimmt!

Txt hatte ich bewusst erstmal gewählt, damit man es einfach anschauen kann und die Daten daraus kopieren bzw übernehmen. Aber das exportieren in csv oder json wäre auch eine gute Idee :)

Danke für den Tipp mit print, wusste ich nicht... Was würdest du statt place verwenden? grid?


Alles andere, mit Import und root statt mGui hab ich in verschiedenen YouTube Videos gesehen (ich denke es ist um wirklich programmieren zu lernen wohl doch nicht das beste Portal)... Scheint mir wohl sinnvoller mir ein Buch zu kaufen oder ein PDF runterzuladen, was alles gut erklärt :D

Was meinst du mit "zum laufen bekommen"? Starten tut es und beenden kann ich es auch. Was will man mehr? (außer den Button zum speichern) :P
BlackJack

@RpiMichi: Die Alternativen zu `place()` sind `pack()` oder `grid()` jeweils auch kombinierbar mit `Frame`\s um eine GUI in kleinere Teilstücke zu zerlegen. `grid()` oder `pack()` entscheidet sich danach wie das Layout jeweils aussehen soll.

Man kann das `Tk`-Exemplar ja gerne `mGui` nennen — naja gerne eigentlich nicht weil das `m` keinen Sinn macht, `gui` zu generisch ist, und die Schreibweise sich nicht an den Style Guide for Python Code hält — aber dann muss man auch tatsächlich einen Wert an den Namen binden und ihn nicht einfach nur verwenden, beziehungsweise es versuchen.

Okay, es startet tatsächlich. Aber nur weil die Funktionen so heissen wie die an der Stelle erwarteten Argumente eigentlich heissen müssten.

Die Namen die nach den Funktionen gebunden werden, machen so alle keinen Sinn, weil die `place()`-Methode den Wert `None` zurück gibt, und nicht etwas das Widget-Objekt auf dem sie aufgerufen wurde.
Antworten