@ Markus
Vielleicht hilft dir noch folgende Hilfestellung beim Aufbau und der Optimierung deines Programmes.
In Python ist es möglich "Objektorientiert" zu programmieren. Hier im Forum gibt es einige gute Posts, die sich damit beschäftigen.
Mein Tipp wäre die Unterteilung Deiner Anwendung in sagen wir einmal mindestens zwei Klassen.
- - grafische Oberfläche
- Dateizugriffe
Der Grund - oder das Ziel - ist es, dass Du in einem Objekt u.a. auf sogenannten Klassenmethoden und -attribute zugreifen kannst, welche Dir bei der Einbindung der Button-Methoden und z.B. Färbungsmethoden sehr hilfreich sein können.
Ebenfalls erlaubt es eine klare Trennung zwischen der reinen Oberfläche und dem Datei-Pickle-Speicher, wodurch das Entwickeln und Testen für Dich um einiges leichter und durchschaubarer werden sollte.
Hier z.B: eine solche Oberflächenklasse:
Code: Alles auswählen
from Tkinter import*
# Definition der Farben durch Konstanten (Vorteil: wenn Du einmal die
# Farbe aendern moechtest, musst Du nicht alle Strings anpassen, sondern
# nur diese Konstanten.
FARBE_LABLE_NORMAL = 'white'
FARBE_LABLE_WARNUNG = 'red'
class TelefonBuch(Tk):
"""Grafische Oberflaeche und Programmlogik"""
def __init__(self):
Tk.__init__(self)
self.title('Telefonlisten Verwaltung')
frame = Frame(self, bg='PaleGreen', height=400, width=400)
frame.pack()
self.__eintrage = 0 # anstelle mit "globals" kannst Du viel effektiver die Variable so als Klassenvariable nutzen
self.__load_statische_elemente(frame)
self.__load_dynamische_elemente(frame)
self.__mein_daten_speicher = MeinDatenSpeicher('mydict.pkl') # die nachste von mir angesprochene Klasse ;)
# ....
def __load_statische_elemente(self, frame):
l_ueberschrift = Label(frame, bg='PaleGreen', font=('Arial',30,'bold'), text='Telefonliste')
l_ueberschrift.place(x=90, y=20)
# ...
def __load_dynamische_elemente(self, frame):
self.__eingabe_name = Entry(frame, width=20, font=('Arial',12,'bold'))
self.__eingabe_name.place(x=50, y=140)
self.__eingabe_nummer = Entry(frame, width=20, font=('Arial',12,'bold'))
self.__eingabe_nummer.place(x=50, y=23
#...
def __get_name_nummer(self)
"""Liefert die Werte der Felder Name und Nummer zurueck,
und faerbt bei Fehlerhaften Eingaben eventuell """
name = self.__eingabe_name.get()
nummer = self.__eingabe_nummer.get()
if not name:
self.__eingabe_name.config(bg=FARBE_LABLE_NORMAL)
else:
self.__eingabe_name.config(bg=FARBE_LABLE_WARNUNG)
if not nummer:
self.__eingabe_nummer.config(bg=FARBE_LABLE_WARNUNG)
else:
self.__eingabe_nummer.config(bg=FARBE_LABLE_NORMAL)
return name, nummer
def self.__neu(self):
"""Methode hinter dem Button 'neu'"""
name, nummer = self.__get_name_nummer()
# ...
if name in self.__mein_daten_speicher.liste_alle_namen():
# ...
if nummer in self.__mein_daten_speicher.liste_alle_nummern():
# ...
erfolgt = self.__mein_daten_speicher.schreibe_daten(name, nummer)
if erfolgt:
return True
else:
self.__faerbe_fehler(
"Konnte '%s' mit Nummber '%s' nicht eintragen." % (name, nummer))
# ...
und hier beispielhaft noch für den Zugriff auf den Datei-Pickle-Speicher:
Code: Alles auswählen
import pickle
import os
class MeinDatenSpeicher(object):
"""Datenspeicher Klasse, um auf Daten in einer Datei zuzugreifen,
bzw. letztendlich persistent zu halten"""
def __init__(self, dateipfad):
self.__datei_pfad = dateipfad
self.__datei_objekt = None
self.__speicher_inhalt = None
self.__lade_speicher()
self.__aktualisiere_speicher()
def __lade_speicher(self):
if not os.path.isfile(self.__datei_pfad):
self.__datei_objekt = open(self.__datei_pfad, 'w+')
self.__aktualisiere_speicher()
def __aktualisiere_speicher(self):
self.__speicher_inhalt = pickle.load(self.__datei)
def schreibe_daten(self, name, nummer):
self.__aktualisiere_speicher()
if name in self.__speicher_inhalt.keys():
return False
if nummer in self.__speicher_inhalts.values():
return False
return True
def liste_speicher(self):
self.__aktualisiere_speicher()
return self.__speicher_inhalt
Ein schönes Beispiel für eine solche konzeptionelle Unterteilung zwischen Darstellung mit Logik und der Datenebene, ist dieses Codesbeispiel von Gerold um [wiki=CPU_Anzeige_(win32)]CPU-Auslastung anzuzeigen[/wiki].
Weicht ein wenig alles von deiner ursprünglichen Fragestellung bezüglich des Datei-Picklens ab ... aber ... glaub mir, so hättest Du es ein wenig einfacher und überschaulicher (gerade auch in Bezug auf das Entwickeln, Testen, Nachfragen im Forum, etc. bezüglich der Pickle-Speicher-Komponente).
Gruß,
>>Masaru<<