Always use REply-All or Reply-List to the tutor list. On 17/11/16 18:34, Freedom Peacemaker wrote: > Thank you Alan for answer but i still cant make it. I have improved my > program but it still uses root.update() and now my app looks > professional :) It is my first program. I am self learning Python > since july this year but still i need a lot of knowledge. Could you > help me improve my app with root.after?
OK, I'll try. > And there is problem - when im closing app with X button after using > app it shows two windows. One with messagebox i wrote, and second > blank new tk window. I dont know where im doing mistake, or it is > caused by root.update maybe? Maybe with using root.after problem will > be no more. Maybe, but I'll need to look at the code more closely. There are a couple of things that could cause this.... Having looked, I think you need to bind the window manager close button to root.quit Take a look at the wm_xxxx methods in the Tkinter docs. > > def displayCountdown(): > lcd = "{:02d}:{:02d}".format(*divmod(t, 60)) > timeString.set(lcd) > setTime -= 1 > if setTime > 0: > root.after(1000,displayCountdown) > Where is 't' (used in the divmod) defined? Looking below I think it should use setTime? Otherwise it looks like it should work. All you need to do is insert a call to displayCountdown() in your START button event handler. > There are problems with my app but im so proud that i wrote myself Its rare that anything is ever perfect but the buzz of getting something to work more or less as you want it to is always good. :-) > import sys, time, os > import tkinter as tk > from tkinter import * > You should probably only ose one of the tkinter imports. And the first is the preferred method for production code. > def change_1(): > B1['state'] = tk.DISABLED > B2['state'] = tk.NORMAL > > def change_2(): > B1['state'] = tk.NORMAL > B2['state'] = tk.DISABLED > > def change_3(): > B1['state'] = tk.DISABLED > B2['state'] = tk.DISABLED Add the displayCountdown() definition here > > def startCount(): > setTime = setMinutes.get() * 60 > strTime = str(setTime) > timeSet = ("\""+"shutdown /s /f /t " +strTime+"\"") > os.system(timeSet) > change_1() displayCountdown() # uses the after() method. This removes the need for all of the code below. > for t in range(setTime, -1, -1): > lcd = "{:02d}:{:02d}".format(*divmod(t, 60)) > timeString.set(lcd) > try: > root.update() > except TclError: > messagebox.showinfo('Info', 'Closing app wont stop timer.') > return > time.sleep(1) > return > The rest of your code is unchanged. But note I haven't tested this! :-) > def stopCount(): > passwd = "science" > passwdGet = getPass.get() > if passwd != passwdGet: You could make this more secure. You should probably do some reading about best [practice for handling passwords. But for now it probably meets your needs. > messagebox.showinfo('Wrong', 'It wasnt correct password') > change_3() > else: > messagebox.showinfo('Good', 'Shutdown canceled') > os.system("shutdown /a") > change_2() > return > > root = tk.Tk() > setMinutes = IntVar() > getPass = StringVar() > timeString = StringVar() > label_font = ('Verdana', 30) > root.geometry('260x150+200+200') > root.title('Timer v1.4') > root.resizable(0, 0) > > L1 = tk.Label(root, text='How much time you have?') > L1.grid(row=0, columnspan=3, sticky='WE') > > L2 = tk.Label(root, textvariable=timeString, font=label_font, bg='white', > fg='orange', relief='raised', bd=3) > L2.grid(row=1, columnspan=3, sticky='WE', padx=5, pady=5) > > E1 = tk.Entry(root, textvariable=setMinutes, bg='lightgreen') > E1.grid(row=2, column=1, padx=5, pady=5) > > B1 = tk.Button(root, text='S T A R T', fg='green', bg='black', > command=startCount) > B1.grid(row=2, rowspan=2, sticky='NS', column=0, padx=5, pady=5) > > E2 = tk.Entry(root, textvariable=getPass, bg='red') > E2.grid(row=3, column=1, padx=5, pady=5) > > B2 = tk.Button(root, text='S T O P', fg='red', bg='black', > command=stopCount, > state=tk.DISABLED) > B2.grid(row=2, rowspan=2, sticky='NS', column=2, padx=5, pady=5) > > root.mainloop() > > > > 2016-11-17 1:03 GMT+01:00 Alan Gauld via Tutor <tutor@python.org > <mailto:tutor@python.org>>: > > On 16/11/16 18:48, Freedom Peacemaker wrote: > > Hi, i need help. I am using Python 3.4 and I have wrote little > app for > > windows only ( windows 7 and higher). Its timer and my app > working but not > > good. Some people said that i should use after method instead of > update() > > after() executes a function after a delay. > In your case you could use it to trigger an > immediate shutdown after the delay elapses. > But I'm not sure that would be much better > than doing what you are doing. > > The other use of after is to avoid loops in > event handlers such as the one you have here. > This allows control to return to the GUI window. > > See below... > > > When you run app first enter minutes in entry then press start. > If you > > first press start your pc will shutdown with no time to stop it > > You can fix that by setting a default value for the time. > But you still need to write some code to cancel the shutdown > (by killing the process perhaps?) > > > def startCount(): > > setTime = setMinutes.get() * 60 > > strTime = str(setTime) > > timeSet = ("\""+"shutdown /s /f /t " +strTime+"\"") > > os.system(timeSet) > > Up to here is fine but you don't want a long running loop > inside an event handler. Although, in this case, it probably > doesn't run for long, it just counts down very quickly. > > Instead you want it to count down every second or so. > > So you want to call a function that displays the time > remaining then calls after() with a delay of 1 second. > The call to after should have the same function in it. > Like so: > > def displayCountdown(): > # display the time here > # decrement the time by 1 second > # if any time remains: > # call after(1000,displayCountdown) # 1000ms = 1s > > Note that after only needs the function name, don't > include any parentheses. > > > for t in range(setTime, -1, -1): > > lcd = "{:02d}:{:02d}".format(*divmod(t, 60)) > > timeString.set(lcd) > > try: > > root.update() > > except TclError: > > messagebox.showinfo('Info', 'Closing app wont stop > timer.') > > return > > time.sleep(1) > > return > > > HTH > -- > Alan G > Author of the Learn to Program web site > http://www.alan-g.me.uk/ > http://www.amazon.com/author/alan_gauld > <http://www.amazon.com/author/alan_gauld> > Follow my photo-blog on Flickr at: > http://www.flickr.com/photos/alangauldphotos > <http://www.flickr.com/photos/alangauldphotos> > > > _______________________________________________ > Tutor maillist - Tutor@python.org <mailto:Tutor@python.org> > To unsubscribe or change subscription options: > https://mail.python.org/mailman/listinfo/tutor > <https://mail.python.org/mailman/listinfo/tutor> > > -- Alan G Author of the Learn to Program web site http://www.alan-g.me.uk/ http://www.amazon.com/author/alan_gauld Follow my photo-blog on Flickr at: http://www.flickr.com/photos/alangauldphotos _______________________________________________ Tutor maillist - Tutor@python.org To unsubscribe or change subscription options: https://mail.python.org/mailman/listinfo/tutor