Die erste Version des Notizbuches diente als kleines Einstiegsprojekt, war und ist bis
auf weiteres voll funktionsfähig, weißt jedoch einige Unzulänglichkeiten auf, die in Projekten von Python-Neulingen
häufig zu finden sind. So enthält die erste Version globale Variablen, die ein gestandener Programmierer eigentlich
nicht verwenden sollte, da diese vor allem bei etwas umfangreicheren Scripts die Fehlersuche erschweren können.
Die zweite Version enthält nur noch eine Konstante "FONT" außerhalb der Hilfsfunktion "liefere_datum" und der
Klasse "Notizbuch" und im Gegensatz zu sonstigen globalen Variablen, deren Werte sich im weiteren Programmablauf
mehrfach verändern könnten, werden Konstanten mit einem Wert initialisiert, der im weiteren Programmablauf nicht
mehr verändert werden sollte.
In Version 2.0 sind darüber hinausgehend noch weitere Änderungen enthalten. So wurde der Code der neueren Version
mehr an den Leitfaden für Python-Code (PEP 8) angelehnt, z.B. in Bezug auf die camel_case Schreibweise bei den
Namen der Methoden. Was hingegen nicht streng eingehalten wurde, ist der Abstand vor und hinter Gleichheitszeichen.
Innerhalb von Funktionsköpfen und deren Aufrufe, sollten eigentlich innerhalb von (Klammern) keine Leerzeichen
vor und hinter Gleichheitszeichen notiert werden, woran wir uns nur bei .pack, nicht aber bei den Optionen von
Frames, Labels und Buttons hielten. Da alle Optionen jedoch untereinander und nicht nebeneinander aufgelistet
wurden, erschien uns diese Schreibweise ein wenig gefälliger.
Dennoch sei jedem Einsteiger angeraten, sich wenigsten einmal mit der PEP 8 zu beschäftigen und das möglichst
bevor er eine Frage zu seinem Code in einem Python-Forum stellt oder ein Script veröffentlichen und anbieten möchte.
Ansicht des Notizbuches bei 520 x 360 Pixel mit einem 'Lorem ipsum'-Platzhaltertext.
Wie aus dem Script ersichtlich, wurde für das Speichern von neuen Notizen für "open" der Modus "a" gewählt wurde.
In diesem Modus wird, falls noch keine Datei vorhanden sein sollte, eine neue Datei bei einem Klick auf dem Button
"Neue speichern" unter dem Dateinamen des aktuellen Monats mit zugehöriger Jahreszahl angelegt.
"notizen-im-[aktueller Monat]-[aktuelle Jahreszahl].txt"
Besteht diese Datei bereits, was immer dann der Fall sein sollte, wenn bereits Einträge nach dem Ersten eines
Monats erfolgten, wird bei jedem weiteren Eintrag lediglich der interne Dateizeiger nicht an den Anfang platziert,
sondern bis zum Ende der bestehenden Datei vorgerückt. Die bestehende Datei wird dadurch um neuere Einträge erweitert.
Zusätzlich können jedoch bestehende Einträge geöffnet werden, um diese zu editieren oder unter einem anderen Dateinamen
zu speichern und selbstverständlich können neue Dateien ebenfalls unter einem beliebigen Namen mit dem Button
"Speichern unter ..." abgelegt werden.
Code des kleinen Tage- oder Notizbuches – Version 2.0:
#!/usr/local/bin/python # -*- coding: utf-8 -*- # --------------------------------------------------------------------- # Description: Ein universelles Notizbuch, als Tagebuch nutzbar. # Autor: Horst Müller # Version: 2.0 # Datum: 14. September 2017 # Lizenz: GPLv3, einsehbar unter http://www.gnu.org/licenses/ # --------------------------------------------------------------------- from tkinter import (Tk, Frame, Button, Label, Text, PhotoImage, Scrollbar, END) from tkinter.filedialog import askopenfilename, asksaveasfile import time import os FONT = "cambria" # Deutsche Monatsnamen fürs Datum und dem monatlichen Dateinamen benutzen. # Beispiel Dateiname: notizen-im-september-2017.txt def liefere_datum(auswahl): deutsche = { "01" : "Januar", "02" : "Februar", "03" : "Maerz", "04" : "April", "05" : "Mai", "06" : "Juni", "07" : "Juli", "08" : "August", "09" : "September", "10" : "Oktober", "11" : "November", "12" : "Dezember" } wochentag = time.strftime("%d") # Wochentage 01 bis 31 monatsname = time.strftime("%m") # monatsname 01 bis 12 jahreszahl = time.strftime("%Y") # das Jahr allgemein # Ein aktuelles Datum für die Übernahme ins Textfeld erstellen. if auswahl == "dmY": return "{0:s}. {1:s} {2:s}".format( wochentag, deutsche[monatsname], jahreszahl) # Verwendung für einen monatlichen Dateinamen, wobei eine Anpassung # auf andere Zeiträume möglich ist. elif auswahl == "mY": return "notizen-im-{0:s}-{1:s}.txt".format( deutsche[monatsname].lower(), jahreszahl) class Notizbuch: """ Eine Klasse für ein universelles Tage- oder Notizbuch. """ def __init__(self): self.fenster = Tk() self.fraktal = PhotoImage(file="tagebuch.gif") self.dateiname = None self.textfeld = None # Den kompletten Pfad mit dem Name des Verzeichnisses und der Datei # für die Speicherung der Notizen liefern. def liefere_pfad(self): verzeichnis = "reminder" datei_name = liefere_datum("mY") # Mit kompletten Pfad pfad = os.path.abspath(".") self.dateiname = os.path.join(pfad, verzeichnis, datei_name) # Datei anlegen (falls noch nicht vorhanden) und neue Notizen # speichern. def speichere_neue(self): self.liefere_pfad() with open(self.dateiname, "a") as datei: datei.write(self.textfeld.get(1.0, END)) self.textfeld.delete(1.0, END) self.textfeld.insert(END, "Eintrag erfolgreich!") # Funktion für das Einfügen eines Datums als Option. def setze_datum(self): self.textfeld.insert( END, "Notizen vom {0:s}\n\n".format(liefere_datum("dmY"))) # Bestehende Datei zum Lesen oder zum Editieren öffnen. def oeffne_notizen(self): self.dateiname = askopenfilename( filetypes = [("Text Datei", "*.txt")]) # Esventuell vorhandener Inhalt aus dem Textfeld löschen. self.textfeld.delete(1.0, END) # Inhalt einer geöffneten Datei zum Lesen und Editieren oder # bei Abbruch einen Hinweis ins Textfeld einfügen. if self.dateiname: with open(self.dateiname, "r") as datei: self.textfeld.insert(END, datei.read()) else: self.textfeld.insert(END, "Es wurde keine Datei geöffnet!") # Die alte Datei wird bei Mode "w" nach dem Editieren überschrieben. # Wurde "oeffne_notizen()" nicht genutzt, bleibt self.dateiname bei # None und bei Abbruch von "oeffne_notizen()" liefert # askopenfilename einen leeren "" String. def speicher_notizen(self): if self.dateiname: with open(self.dateiname, "w") as datei: datei.write(self.textfeld.get(1.0, END)) self.textfeld.delete(1.0, END) self.textfeld.insert(END, "Änderung erfolgreich!") self.dateiname = None # Falls keine Datei zum Editieren geöffnet wurde. elif self.dateiname is None or self.dateiname == "": self.waehle_pfadname() # Manuelle Wahl des Speicherortes und des Dateinamens. def waehle_pfadname(self): datei = asksaveasfile(mode = "a", filetypes = [("Text Datei", "*.txt")]) if datei: datei.write(self.textfeld.get(1.0, END)) datei.close() self.textfeld.delete(1.0, END) self.textfeld.insert(END, "Gespeichert!") # Ein self.fenster erzeugen, einen Fenstertitel plus Icon # hinzufügen, sowie die Größe und Aufteilung festlegen. def layout(self): self.fenster.title("Mein Notizbuch") self.fenster.wm_iconbitmap("logo.ico") self.fenster.geometry("640x424") self.fenster.maxsize(width = 680, height = 464) self.fenster.config(bg = "#d9cda3") # Aufteilung in linken und rechten Frame frame_sidebar = Frame(self.fenster, bg = "#d9cda3") frame_textfeld = Frame(self.fenster, bg = "#a2a2a2") # Sidebar (linke Seite) packen frame_sidebar.pack(side = "left") # Label für Sidebar (linke Seite oben) Label( frame_sidebar, text = "Notizen", bg = "#d9cda3", fg = "#904b00", font = (FONT, 12, "bold"), pady = 8).pack() # Datei anlegen (falls noch nicht vorhanden) und neue Notizen # speichern. Button( frame_sidebar, text = "Neue speichern", font = (FONT, 10), bg = "#6f6352", fg = "#ffe9b3", activebackground = "#806840", command = self.speichere_neue).pack(fill="x", padx=8) # Button für das Einfügen eines Datums als nutzbare Option. Button( frame_sidebar, text = "Datum einfügen", font = (FONT, 10), bg = "#6f6352", fg = "#ffe9b3", activebackground = "#806840", command = self.setze_datum).pack(fill="x", padx=8) # Label für linke Seite (Ältere Notizen) wurde mittig anordnet. Label( frame_sidebar, text = "Ältere Notizen", font = (FONT, 9, "bold"), bg = "#d9cda3", fg = "#904b00", pady = 8).pack(fill="x", padx=8) # Bei mehr als 2 Buttons in Folge bietet sich eine Schleife an. button_labels = ("Öffnen", "Speichern", "Speichern unter ...") button_commands = (self.oeffne_notizen, self.speicher_notizen, self.waehle_pfadname) for i in range(3): Button( frame_sidebar, text = button_labels[i], font = (FONT, 10), bg = "#6f6352", fg = "#ffe9b3", activebackground = "#806840", command = button_commands[i] ).pack(fill="x", padx=8) # Label für linke Seite unten mit einem Image als Designergänzung. Label( frame_sidebar, bg = "#d9cda3", image = self.fraktal).pack(pady=24) # Ein Textfeld mit Scrollbar erstellen und formatieren. self.textfeld = Text( frame_textfeld, pady = 10, padx = 10, wrap = "word") scrollbar = Scrollbar(frame_textfeld) scrollbar.config(command = self.textfeld.yview) self.textfeld.config(yscrollcommand = scrollbar.set) # Rechte Seite packen frame_textfeld.pack(side="left", pady=3) scrollbar.pack(side="right", fill="y") self.textfeld.pack(pady=2, padx=2) def main(self): self.layout() self.fenster.mainloop() if __name__ == "__main__": Notizbuch().main()
Wie bereits die erste Version, so wurde auch diese Version des kleinen Tage- oder Notizbuches
mit Python 3.6 unter Windows 10 getestet. Um es unter Windows nutzen zu können, müssen Sie eine neuere Python Version
auf Ihrem Computer installieren, falls noch nicht vorhanden sein sollte. Weiterhin muss in dem Verzeichnis, in
dem sie dieses Script ablegen möchten, ein Verzeichnis mit der Bezeichnung "reminder" angelegt werden oder Sie
müssen den der Variablen "verzeichnis" zugewiesenen Verzeichnisnamen entsprechend anpassen, um einen korrekten Pfad
zu erhalten.
Abschließend sei noch erwähnt, dass wir keine Gewähr für die Fehlerfreiheit des Scripts übernehmen können.
Die erste Version ist zwar noch einsehbar, wir empfehlen jedoch die Verwendung der neueren Version.
Einstieg in Python
OOP mit Python
Codes & Tutorials
Kleines Projekt