Hallo,
vielen Dank für Deine Hilfe
jetzt habe ich einen Thread
Code: Alles auswählen
def countTime(self):
thr = start_new_thread(self.countSecond, ())
def countSecond(self):
self.active = True
while self.active:
time.sleep(1)
self.seconds += 1
self.timeCountLbl["text"] = self.seconds
wend
Die Schleife sollte solange laufen, wie self.active == True ist. Wenn ich das Fenster schließe, wird der Thread nicht automatisch mit unterbrochen. Wie kann ich das Ereignis "fensterschließtsich" behandeln?
gruß
Tobias
ähm, ich poste mal das Progrämmchen hier rein. Beim ausführen wird das Problem vielleicht klarer. Wenn ich irgendwas anders gemacht habe, als es in Python üblich ist, wären Verbesserungsvorschläge auch cool!
Code: Alles auswählen
from Tkinter import *
#from Tix import *
from tkFileDialog import *
from tkFont import Font
from thread import start_new_thread
import time
class TipperUI(Canvas):
"""
UI Hauptklasse der Anwendung
mal gucken, wie tk klappt ;-)
"""
def __init__(self, master=None):
Canvas.__init__(self, master)
self.pack({"fill": "both", "expand": True})
self.createWidgets()
self.pointer = [1, 1]
self.seconds = 0
self.loc = 0.0
self.thr = None
self.shiftPressed = False
self.altLPressed = False
self.altRPressed = False
self.keyCount = 0
self.errorCount = 0
self.active = False
self.startTime = 0
def createWidgets(self):
"""
Komponenten erzeugen (Widgets)
"""
# Fonts
self.bigFont = Font(family="Arial", size=25)
self.mediumFont = Font(family="Arial", size=12)
# centerCan
self.centerCan = Canvas(self)
self.centerCan.pack({"side": "left", "fill": "both", "expand": True})
# eastCan
self.eastCan = Canvas(self)
self.eastCan.pack({"side": "right", "fill": "y"})
# outputTxt
self.outputTxt = Text(self.centerCan)
self.outputTxt["height"] = 5
self.outputTxt["font"] = self.mediumFont
self.outputTxt.pack({"anchor": "nw", "fill": "both", "expand": 1})
self.outputTxt.tag_config("ok", background="yellow", foreground="red");
self.outputTxt.tag_config("nok", background="red", foreground="black");
#self.outputTxt["state"] = "disabled"
self.outputTxt["background"] = "lightgrey"
# newsCan
self.newsCan = Canvas(self.centerCan)
self.newsCan.pack({"in": self.centerCan, "anchor": "center", "fill": "both"})
#self.newsCan.config({"bg": "red"})
# currLetterLblfr
self.currLetterLblfr = LabelFrame(self.newsCan)
self.currLetterLblfr["text"] = "nächster Buchstabe"
self.currLetterLblfr.pack({"in": self.newsCan, "side": "left"})
# currLetterLbl
self.currLetterLbl = Label(self.currLetterLblfr)
self.currLetterLbl["font"] = self.bigFont
self.currLetterLbl["text"] = ""
self.currLetterLbl.pack({"anchor": "center", "fill": "both"})
# mistakesLblfr
self.mistakesLblfr = LabelFrame(self.newsCan)
self.mistakesLblfr["text"] = "Fehler"
self.mistakesLblfr.pack({"in": self.newsCan, "after": self.currLetterLblfr, "side": "left", "anchor": "w"})
# mistakesLbl
self.mistakesLbl = Label(self.mistakesLblfr)
self.mistakesLbl["font"] = self.bigFont
self.mistakesLbl["text"] = "0"
self.mistakesLbl.pack({"anchor": "center", "fill": "both"})
# countTypingLblfr
self.countTypingLblfr = LabelFrame(self.newsCan)
self.countTypingLblfr["text"] = "Anschläge"
self.countTypingLblfr.pack({"in": self.newsCan, "after": self.mistakesLblfr, "side": "left", "anchor": "w"})
# countTypingLbl
self.countTypingLbl = Label(self.countTypingLblfr)
self.countTypingLbl["font"] = self.bigFont
self.countTypingLbl["text"] = 0
self.countTypingLbl.pack({"anchor": "center", "fill": "both"})
# timeCountLblfr
self.timeCountLblfr = LabelFrame(self.newsCan)
self.timeCountLblfr["text"] = "Zeit"
self.timeCountLblfr.pack({"in": self.newsCan, "after": self.countTypingLblfr, "side": "left", "anchor": "w"})
# timeCountLbl
self.timeCountLbl = Label(self.timeCountLblfr)
self.timeCountLbl["font"] = self.bigFont
self.timeCountLbl["text"] = 0
self.timeCountLbl.pack({"anchor": "center", "fill": "both"})
# typesPerMinuteLblfr
self.typesPerMinuteLblfr = LabelFrame(self.newsCan)
self.typesPerMinuteLblfr["text"] = "Anschläge / Minute"
self.typesPerMinuteLblfr.pack({"in": self.newsCan, "after": self.timeCountLblfr, "side": "left", "anchor": "w"})
# typesPerMinuteLbl
self.typesPerMinuteLbl = Label(self.typesPerMinuteLblfr)
self.typesPerMinuteLbl["font"] = self.bigFont
self.typesPerMinuteLbl["text"] = "-"
self.typesPerMinuteLbl.pack({"anchor": "center", "fill": "both"})
# inputTxt
self.inputTxt = Text(self.centerCan)
self.inputTxt["height"] = 5
self.inputTxt["font"] = self.mediumFont
self.inputTxt.pack({"anchor": "sw", "fill": "both", "expand": 1})
self.inputTxt.bind("<KeyPress>", self.inputTxt_keyPressed)
self.inputTxt.bind("<KeyRelease>", self.inputTxt_keyReleased);
# optionLblfr
self.optionLblfr = LabelFrame(self.eastCan)
self.optionLblfr["text"] = "Optionen"
self.optionLblfr.pack({"side": "right", "fill": "both"})
# openBtn
self.openBtn = Button(self.optionLblfr)
self.openBtn["text"] = "Öffnen.."
self.openBtn["command"] = self.openFile
self.openBtn.pack({"side": "top"})
# resetBtn
self.resetBtn = Button(self.optionLblfr)
self.resetBtn["text"] = "Reset"
self.resetBtn["command"] = self.reset
self.resetBtn.pack({"side": "left"})
# quitBtn
self.quitBtn = Button(self.optionLblfr)
self.quitBtn["text"] = "Ende"
self.quitBtn["command"] = self.quit
self.quitBtn.pack({"side": "bottom"})
def reset(self):
self.active = False
self.timeCountLbl["text"] = 0
self.seconds = 0
self.inputTxt.delete(0.0, 100.100)
self.outputTxt.tag_delete("nok", "ok" )
def inputTxt_keyPressed(self, event):
"""
Callbackfunktion, wird aufgerufen wenn im inputTxt
ein Key gedrückt wurde.
"""
# Timer starten
if self.active == False:
self.countTime();
"""
self.startTime = int(time.clock())
self.active = True
now = int(time.clock())
# Zeit anzeigen
self.timeCountLbl["text"] = now - self.startTime
print "%i - %i" % (now ,self.startTime)
"""
if event.keysym == "Shift_L":
self.shiftPressed = True
return
if event.keysym == "Shift_R":
self.shiftPressed = True
return
if event.keysym == "Alt_R":
self.altRPressed = True
return
if event.keysym == "Alt_L":
self.altLPressed = True
return
if event.keysym == "Control_L":
return ;# ignorieren
# keyCount incrementieren
self.keyCount += 1
self.countTypingLbl["text"] = self.keyCount
key = self.keysym2String(event.keysym)
pos = self.tipper.getPos()
if self.tipper.checkKey(key):
# richtig
self.loc = "%i.%i" % (pos["y"], pos["x"])
self.outputTxt.tag_add("ok", 1.0, self.loc )
else:
# falsch
nloc = "%i.%i" % (pos["y"], pos["x"])
self.outputTxt.tag_add("nok", self.loc, nloc )
# errorCount incrementieren
self.errorCount += 1
self.mistakesLbl["text"] = self.errorCount
# Text ausrichten
self.outputTxt.see("%i.%i" % (pos["y"]+1, pos["x"]))
# nächsten Buchstaben anzeigen
key = self.tipper.getNextChar()
if key == "":
# Ende
self.stop()
else:
self.currLetterLbl["text"] = self.char2Key(key);
def stop(self):
self.active = False
def inputTxt_keyReleased(self, event):
"""
Callbackfunktion, wird aufgerufen wenn im inputTxt
ein Key losgelassen wurde.
"""
if event.keysym == "Shift_L":
self.shiftPressed = False
return
if event.keysym == "Shift_R":
self.shiftPressed = False
return
if event.keysym == "Alt_L":
self.altLPressed = False
return
if event.keysym == "Alt_R":
self.altRPressed = False
return
def countTime(self):
self.thr = start_new_thread(self.countSecond, ())
def countSecond(self):
self.active = True
while self.active:
time.sleep(1)
self.seconds += 1
#if self.timeCountLbl == None:
# self.active = False
# break
try:
self.timeCountLbl["text"] = self.seconds
minutes = int(self.seconds/60)
seconds = int(self.seconds - minutes*60.0)
self.timeCountLbl["text"] = ('%02d:%02d' % (minutes, seconds))
except Exception:
self.active = False
self.thr.exit()
break
print "Ende Schleife"
def keysym2String(self, key):
"""
wandelt die keys in chars um
z.b. 'Return' wird zu '\n'
"""
if self.shiftPressed:
# in grossbuchstaben wandeln!
key = key.upper()
if self.altLPressed:
pass
if self.altRPressed:
if key == "2": return "²"
if key == "3": return "³"
if key == "7": return "{"
if key == "8": return "["
if key == "9": return "]"
if key == "0": return "}"
if key == "ß": return "\\"
if key == "<": return "|"
if key == "numbersign": return "#"
if key == "space": return " "
if key == "Return": return "\n"
if key == "Tab": return "\t"
if key == "period": return "."
if key == "EQUAL": return "="
if key == "QUESTION": return "?"
if key == "PARENLEFT": return "("
if key == "PARENRIGHT": return ")"
if key == "EXCLAM": return "!"
if key == "QUOTEDBL": return "\""
if key == "SECTION": return "§"
if key == "DOLLAR": return "$"
if key == "PERCENT": return "%"
if key == "AMPERSAND": return "&"
if key == "SLASH": return "/"
if key == "ASTERISK": return "*"
if key == "QUOTERIGHT": return "'"
if key == "UNDERSCORE": return "_"
if key == "minus": return "-"
if key == "plus": return "+"
if key == "less": return "<"
if key == "GREATER": return ">"
if key == "COLON": return ":"
if key == "comma": return ","
if key == "SEMICOLON": return ";"
if key == "Multi_key": return "´"
if key == "MULTI_KEY": return "`"
# ansonsten den ursprünglichen key
# zurückgeben
return key
def char2Key(self, char):
if char == " ": return "leer"
if char == "\n": return "Return"
return char
def openFile(self):
"""
liest ein File ein und stellt dessen Inhalt
im outputTxt dar
"""
print "openFile"
# Start off with UTF-8
enc = "utf-8"
import sys
"""
# See whether CODESET is defined
try:
import locale
locale.setlocale(locale.LC_ALL,'')
enc = locale.nl_langinfo(locale.CODESET)
except (ImportError, AttributeError):
pass
"""
openfilename=askopenfilename(filetypes=[("all files", "*")])
try:
fp=open(openfilename,"r")
fp.close()
except:
print "Could not open File: "
print sys.exc_info()[1]
#print "open", openfilename.encode(enc)
# Datei einlesen
#f = open(openfilename.encode(enc))
f = open(openfilename)
self.tipper = Tipper(f.read())
self.outputTxt.insert(1.0, self.tipper.getText())
# nächsten Buchstaben anzeigen
char = self.tipper.getNextChar();
if char == None:
# ende
self.reset()
else:
self.currLetterLbl["text"] = self.tipper.getNextChar();
class Tipper:
def __init__(self, text):
self.text = text
self.pos = {"x": 0, "y": 1}
self.pointer = 0
print self.text
def getPos(self):
return self.pos
def checkKey(self, key):
print "TEST: "+self.text[self.pointer:self.pointer+1]+" vs. "+ key
rval = False
if key == self.text[self.pointer:self.pointer+1]:
# richtig getippt
rval = True
if self.text[self.pointer:self.pointer+1] == "\n":
self.pos["x"] = 0
self.pos["y"] += 1
else:
self.pos["x"] += 1
self.pointer += 1
return rval
def getNextChar(self):
return self.text[self.pointer:self.pointer+1]
def getText(self):
print "printText"
sys.stdout.write(self.text)
return self.text
if __name__ == "__main__":
root = Tk()
root.title("tos Tipper")
main = TipperUI(root)
root.mainloop()