68. Ein fast nützliches Programm III

Wir müssen jetzt noch Editor-Methoden schreiben, die die wirkliche Arbeit tun:

  def openFile(self, fname=None):
    if not fname:
      fname = tkFileDialog.askopenfilename(
        parent=self, title="Open File...")
    if not fname: return
    try:
      tx = open(fname).read()
    except IOError:
      tkMessageBox.showerror(title="Error",
        message= "Couldn’t open %s"%fname,
        parent=self)
    else:
      self.text.setText(tx)

  def saveFile(self):
    fname = tkFileDialog.asksaveasfilename(
      parent=self, title="Save As...")
    if not fname: return
    try:
      f = open(fname, "w")
      f.write(self.text.getText())
      f.close()
    except IOError:
      tkMessageBox.showerror(title="Error",
        message="Write on %s failed"%fname,
        parent=self)

Anmerkungen:

  • Tkinter kommt mit einigen nützlichen Modulen, die Dialoge vordefinieren, die man häufig braucht. Einer davon ist die Dateiauswahlbox, die im Modul tkFileDialog liegt. Eine einfache Möglichkeit, mit der Dateiauswahlbox zu kommunizieren, sind die Funktionen askopenfilename, die den Namen einer lesbaren Datei zurückgibt, die die Benutzerin ausgewählt hat, und asksaveasfilename, die etwa noch überprüft, ob der gewählte Name noch „frei” ist (es also noch keine Datei gleichen Namens gibt) und beim Benutzer rückfragt, wenn das nicht so ist. Beide Funktionen lassen sich über unzählige Optionen steuern und geben ggf. den gewünschten Dateinamen zurück. Das parent=self sollte dafür sorgen, dass die Dateiauswahlbox über dem Anwendungsfenster erscheint. Ob das wirklich so ist, hängt vom verwendeten Window Manager ab.
  • Ein weiteres nützliches Modul ist tkMessageBox. Wir verwenden daraus hier showerror, um eine Fehlermeldung anzuzeigen.

Schließlich definieren wir uns noch eine Spaßmethode zum Verwürfeln von Texten:

  def permute(self):
    import random
    tx = self.text.getText()
    parts = tx.split(" ")
    random.shuffle(parts)
    self.text.setText(" ".join(parts))

und können dann noch etwas Code hinzufügen, um das ganze zu einem Programm zu machen:

  import sys
  if len(sys.argv)>1:
    e = Editor(sys.argv[1])
  else:
    e = Editor()
  e.mainloop()

Auch wenn das Programm in der Tat schon ziemlich viel kann, bliebe natürlich noch etliches an der Benutzbarkeit zu feilen. So könnten wir uns z.B. den Namen der Datei, die wir gerade editieren, merken und einen Save-Menüpunkt einführen. Wenn ein Zeichen geschrieben werden soll, das im gewählten Encoding nicht darstellbar ist, wirft das Programm im Augenblick noch eine Exception. Es wäre viel besser, wenn die abgefangen würde und zu einer ordentlichen Fehlermeldung auf der GUI führen würde.

Es wäre auch gut, das Menü tastaturbedienbar zu machen („Accelerator Keys”). Gute GUI-Programme merken sich auch z.B. ihre Geometrie oder erlauben, ein bevorzugtes Encoding voreinzustellen. Und wenn man schon Konfigurationsdateien hat, warum dann nicht auch die unterstützten Encodings wählbar machen? Schließlich gäbs noch Kleinigkeiten, etwa einen vernünftigen Namen in der Titelzeile.

Wer also in den Ferien noch nichts vorhat


Markus Demleitner

Copyright Notice