Tkinter hangs again under Windows

Hans-Joachim Widmaier hjwidmai at foxboro.com
Tue Jan 18 07:48:21 EST 2000


Peter:
> Hi Hans-Joachim,
> 
> how about posting the script or the relevant part of it?

Also it's not really long, I see the need to apologize for 200 lines
of not-so-elagant python programming. Well, you asked for it. ;-)

----- cut here -----
#!/usr/bin/env python

from Tkinter import *
from Tkconstants import *
import tkMessageBox, os, sys, string, tkFileDialog, Dialog

__version__ = "0.2"

class CDDat:
    def __init__(self):
        self.artist = ""
        self.title  = ""
        self.data   = []
    
    def append(self, dat):
        c = dat[:1]
        # Die ersten A:- und T:-Einträge extra merken
        if c == "A" and not self.artist:
            self.artist = string.strip(dat[2:])
        elif c == "T" and not self.title:
            self.title = string.strip(dat[2:])
        self.data.append(dat)
    
    def getdata(self):
        return self.data

# Fredrik Lundhs AutoScrollbar

class AutoScrollbar(Scrollbar):
    # a scrollbar that hides itself if it's not needed.  only
    # works if you use the grid geometry manager.
    def set(self, lo, hi):
        flo = float(lo)
        fhi = float(hi)
        self.ll = flo
        self.rr = fhi
        if flo <= 0.0 and fhi >= 1.0:
            # grid_remove is currently missing from Tkinter!
            self.tk.call("grid", "remove", self)
        else:
            self.grid()
        Scrollbar.set(self, lo, hi)
    def pack(self, **kw):
        raise TclError, "cannot use pack with this widget"
    def place(self, **kw):
        raise TclError, "cannot use place with this widget"

class GetProject(Frame):
    def __init__(self, master, db):
        Frame.__init__(self, master)

        self.root = master
        self.file = None
        self.data = []
        self.dbname = None
        self.rtitle = "Read Feurio! DB V " + __version__
        self.root.title(self.rtitle)
        self.root.iconname('readfdb')

        # Hauptfenster mit beiden Pfaden und den Knöpfen
        # für "Anzeigen" und "Beenden"

        # Die beiden Frames (0,0) für's Menü, (1,0) für Listbox, (2,0) für OK-Knopf
        self.menuFrame = Frame(self.root, relief=RAISED, bd=2)
        self.win       = Frame(self.root)
        self.but       = Frame(self.root)

        # Menü erstellen
        self.filebtn      = Menubutton(self.menuFrame,text ="Datei", justify=LEFT)
        self.filebtn.menu = Menu(self.filebtn)
        self.filebtn.menu.add_command(label="DB öffnen ...", command=self.openDB)
        self.filebtn.menu.add_separator()
        self.filebtn.menu.add_command(label="Beenden", command=self.quit)
        self.filebtn['menu'] = self.filebtn.menu
        self.filebtn.grid(row=0, column=0)

        # Ok-Knopf im untersten Frame
        self.but.ok = Button(self.but, text="Ok", state=DISABLED, command=self.save)
        self.but.ok.grid(row=0, column=0)

        # Frames layouten
        self.menuFrame.grid(row=0, column=0, sticky=E+W)
        self.win.grid(row=1, column=0, sticky=E+W+N+S)
        self.but.grid(row=2, column=0, sticky=E+W+N+S)

        self.win.grid_rowconfigure(0, weight=1)
        self.win.grid_columnconfigure(0, weight=1)
        self.but.grid_rowconfigure(0, weight=1)
        self.but.grid_columnconfigure(0, weight=1)
        self.menuFrame.grid_columnconfigure(3, weight=1)
        self.root.grid_rowconfigure(1, weight=1)
        self.root.grid_columnconfigure(0, weight=1)

        # Datenbank lesen
        if not db:
            db = self.askOpen()
        if db:
            self.readDB(db)
        return

    def readDB(self, dbname):
        try:
            f = open(dbname, "rt")
            self.data = []
            while 1:
                l = f.readline()
                if l == "":                     # EOF
                    break
                c = l[:1]
                if c == "#":                    # Hier beginnt ein neuer Datensatz
                    cdd = CDDat()
                elif c in "AT0123456789":       # Nur diese interessieren uns
                    cdd.append(l)
                elif c == "$":                  # Und hier endet ein Datensatz
                    self.data.append(cdd)
            f.close()
        except IOError, why:
            tkMessageBox.showwarning("Fehler",
                'Die Feurio!-Datenbank "%s" kann nicht geöffnet werden - %s' % (dbname, why[1]),
                parent=self)
            return

        self.root.title(self.rtitle + " - " + os.path.basename(dbname))
        if len(self.data) == 0:
            tkMessageBox.showwarning("Warnung",
                'Die Datei enthält keine gültigen CD-Beschreibungen',
                parent=self)
            return
        
        # Auswahlliste zusammenbasteln
        self.win.xs = AutoScrollbar(self.win, orient=HORIZONTAL)
        self.win.xs.grid(row=1, column=0, sticky=E+W)
        self.win.ys = AutoScrollbar(self.win, orient=VERTICAL)
        self.win.ys.grid(row=0, column=1, sticky=N+S)
        self.win.box = Listbox(self.win, width=60, height=20, selectmode=BROWSE,
                        yscrollcommand=self.win.ys.set, xscrollcommand=self.win.xs.set)
        self.win.xs.config(command=self.win.box.xview)
        self.win.ys.config(command=self.win.box.yview)
        self.win.box.grid(row=0, column=0, sticky=N+S+E+W)
        self.win.grid_rowconfigure(0, weight=1)
        self.win.grid_columnconfigure(0, weight=1)

        for cdd in self.data:
            self.win.box.insert(END, cdd.artist + '  "' + cdd.title + '"')
        self.win.box.insert(END, "")    # Leere Zeile am Ende
        self.win.grid(row=1, column=0, sticky=N+S+E+W)
        self.win.box.bind("<Double-Button-1>", self.save)

        # Letzten Eintrag anzeigen - er ist der "prime candidate"
        self.win.box.see(len(self.data) - 1)
        self.win.box.select_set(len(self.data) - 1)
        
        self.but.ok['state'] = NORMAL

    def save(self, event=None):
        try:
            i = string.atoi(self.win.box.curselection()[0])
            dat = self.data[i].getdata()
        except IndexError:
            tkMessageBox.showwarning("Fehler", 'Kein Projekt ausgewählt', parent=self)
            return
        file = tkFileDialog.asksaveasfilename(title="Speichern als ...",
                        initialdir=".", defaultextension=".cdb",
                        filetypes=[("Feurio!-DB", "*.cdb"), ("Alle Dateien", "*.*")])
        if not file:
            return
        try:
            f = open(file, "wt")
            for l in dat:
                f.write(l)
            f.close()
        except IOError, why:
            tkMessageBox.showwarning("Fehler",
                'Kann "%s" nicht schreiben - %s' % (file, why[1]), parent=self)

    def openDB(self):
        dbname = self.askOpen()
        if dbname:
            self.readDB(dbname)

    def askOpen(self):
        if not self.dbname:
            idir = ""
        else:
            idir = os.path.split(self.dbname)[0]
        return tkFileDialog.askopenfilename(title="Datenbank öffnen ...",
                        initialdir=idir, defaultextension=".cdb",
                        filetypes=[("Feurio!-DB", "*.cdb"), ("Alle Dateien", "*.*")])

def main():
    db = None
    if len(sys.argv) > 1:
        db = sys.argv[1]
    tk = Tk()
    GetProject(tk, db)
    tk.mainloop()

if __name__ == '__main__':
    main()

------- cut -------

[This time I'm posting through the mailing list interface; Deja is cumbersome.]
-- 
Hans-Joachim Widmaier         E-Mail:  hjwidmai at foxboro.com
Foxboro Eckardt GmbH          Telefon: +49 711 502 - 397
Pragstrasse 82                Fax:     +49 711 502 - 300
D-70376 Stuttgart 




More information about the Python-list mailing list