how to show run time and loops per hour - python

I have a script which operates gpio's then loops until the loop is broken by a tkinter button, id like to see how many loops its doing per hour. im already able to see how many loops its done with a global variable but cannot work out nor find out how to make it show the current run time and how many loops per hour.. please help..
Here's the MCVE
import Tkinter as tk
root = tk.Tk()
from Tkinter import *
import time
import datetime
root.geometry("748x150")
root.title("Countdown Tester")
run_counter = 0
ts = datetime.datetime.now()
tf = datetime.datetime.now()
te = tf - ts
def _1():
label2["text"] = "1"
label2.config(bg='orange', fg='black')
root.update_idletasks()
time.sleep(1)
def _0():
label2["text"] = "0"
label2.config(bg='orange', fg='black')
root.update_idletasks()
time.sleep(1)
global run_counter
run_counter += 1
root.update_idletasks()
label6["text"] = run_counter
label7["text"] = run_counter# *********** Id like to have the run times per hour listed here
label8["text"] = te# *********** Id like to have the total run time listed here
root.update_idletasks()
canvas = Canvas(width=720, height=150, bg='black')
canvas.grid(rowspan=26, columnspan=20, sticky='W,E,N,S')
label2 = Label(root, width=11, font='-weight bold', background='black', foreground='white')
label2.grid(padx=5, pady=10, row=0, column=0, sticky='W,E,N,S')
label6 = Label(root, text=run_counter, width=11, font='-weight bold', background='white', foreground='black')
label6.grid(padx=5, pady=10, row=0, column=1, sticky='W,E,N,S')
label7 = Label(root, text=run_counter, width=11, font='-weight bold', background='white', foreground='black')
label7.grid(padx=5, pady=10, row=1, column=1, sticky='W,E,N,S')
label8 = Label(root, text=te, width=11, font='-weight bold', background='white', foreground='black')
label8.grid(padx=5, pady=10, row=1, column=0, sticky='W,E,N,S')
#root.resizable(width=FALSE, height=FALSE)
#timer()
while 1:
try:
_1()
_0()
root.update()
except KeyboardInterrupt:
break
root.mainloop()
for some reason this MCVE reports an error on _1() when quit

Related

Python tkinter : how to resize widgets when i resize the screen

I'm beginner...
When the code below is executed, how do I make the widgets inside increase when the screen size is increased to width? but, it couldn't resized..
Does it matter if I use either pack or grid?
i can't solve it....
from tkinter import *
from tkinter import ttk
class program:
def __init__(self):
self.root = Tk()
self.root.title("Python")
self.root.resizable(True, True)
self.create_project()
def create_project(self):
Topic_Label = ttk.Label(self.root, text="program")
Topic_Label.pack(side="top")
Record_LabelFrame = LabelFrame(self.root, text="Record information")
Record_LabelFrame.pack(side="top", anchor=W, padx=10)
date = ttk.Label(Record_LabelFrame, text="date")
date.grid(column=0, row=0, sticky=W)
Topic_Label_Entry1 = ttk.Entry(Record_LabelFrame)
Topic_Label_Entry1.grid(column=0, row=1)
time = ttk.Label(Record_LabelFrame, text="time")
time.grid(column=1, row=0, sticky=W)
Topic_Label_Combo1 = ttk.Combobox(Record_LabelFrame)
Topic_Label_Combo1.grid(column=1, row=1)
recorder = ttk.Label(Record_LabelFrame, text="record")
recorder.grid(column=2, row=0, sticky=W)
Topic_Label_Entry2 = ttk.Entry(Record_LabelFrame)
Topic_Label_Entry2.grid(column=2, row=1)
loc = ttk.Label(Record_LabelFrame, text="location")
loc.grid(column=0, row=2, sticky="W")
RadioVar = IntVar()
Radio_Frame = Frame(Record_LabelFrame)
Radio_Frame.grid(column=0, row=3, sticky=W)
Topic_Label_Radio1 = ttk.Radiobutton(Radio_Frame, text="A", variable=RadioVar, value=1)
Topic_Label_Radio1.grid(column=0, row=0)
Topic_Label_Radio2 = ttk.Radiobutton(Radio_Frame, text="B", variable=RadioVar, value=2)
Topic_Label_Radio2.grid(column=1, row=0)
Topic_Label_Radio3 = ttk.Radiobutton(Radio_Frame, text="C", variable=RadioVar, value=3)
Topic_Label_Radio3.grid(column=2, row=0)
count = ttk.Label(Record_LabelFrame, text="count")
count.grid(column=1, row=2, sticky="W")
Topic_Label_Combo2 = ttk.Combobox(Record_LabelFrame)
Topic_Label_Combo2.grid(column=1, row=3)
seed_name = ttk.Label(Record_LabelFrame, text="seed")
seed_name.grid(column=2, row=2, sticky="W")
Topic_Label_Entry4 = ttk.Entry(Record_LabelFrame)
Topic_Label_Entry4.grid(column=2, row=3)
mt = program()
mt.root.mainloop()
I want to print like this that widget resize automatically when i resize the screen
https://i.stack.imgur.com/iSbaJ.png
https://i.stack.imgur.com/mzv9R.png

How to create a mandatory window in tkinter

I am using python 3.7 and tkinter for making a GUI which saves all my important passwords which are saved in a file passwords.txt. In this I want to create a button in my main window which pops up another window with an entry box and a button(which will close the window) and till this window is not closed it will not let the user to interact with my old window.
Here's my codes:
from tkinter import *
from tkinter import ttk
root = Tk()
f = open("passwords.txt", "r")
list1 = []
for item in f.readlines():
item = item.replace("\n", "")
list1.append(item)
def secondwindow():
root2 = Tk()
root2.title("Secure Your Password")
root2.configure(bg="black")
root2.geometry('700x600')
frame_color = "#%02x%02x%02x" % (150,150,150)
# Create A Main frame
main_frame = Frame(root2, bg=frame_color)
main_frame.pack(fill=BOTH,expand=1)
# Create Frame for X Scrollbar
sec = Frame(main_frame, bg=frame_color)
sec.pack(fill=X,side=BOTTOM)
# Create A Canvas
my_canvas = Canvas(main_frame, bg="black")
my_canvas.pack(side=LEFT,fill=BOTH,expand=1)
# Add A Scrollbars to Canvas
x_scrollbar = ttk.Scrollbar(sec,orient=HORIZONTAL,command=my_canvas.xview)
x_scrollbar.pack(side=BOTTOM,fill=X)
y_scrollbar = ttk.Scrollbar(main_frame,orient=VERTICAL,command=my_canvas.yview)
y_scrollbar.pack(side=RIGHT,fill=Y)
# Configure the canvas
my_canvas.configure(xscrollcommand=x_scrollbar.set)
my_canvas.configure(yscrollcommand=y_scrollbar.set)
my_canvas.bind("<Configure>",lambda e: my_canvas.config(scrollregion= my_canvas.bbox(ALL)))
# Create Another Frame INSIDE the Canvas
second_frame = Frame(my_canvas, bg=frame_color)
# Add that New Frame a Window In The Canvas
my_canvas.create_window((0,0),window=second_frame, anchor="nw")
f = Frame(second_frame, borderwidth=2, relief=SUNKEN, bg=frame_color)
f.pack(side=TOP, fill=X)
Label(f, text="Secure Your Password", fg="white", bg=frame_color, font="Algerian 35 italic").pack()
f1 = Frame(second_frame, bg="black")
f1.pack(fill=BOTH, side=TOP, expand=1)
Label(f1, text="Application", fg="red", bg="black", font="Calibri 20 bold", pady=10, padx=60).grid(row=1, column=1)
Label(f1, text="Username", fg="red", bg="black", font="Calibri 20 bold", pady=10, padx=210).grid(row=1, column=2)
Label(f1, text="Password", fg="red", bg="black", font="Calibri 20 bold", pady=10, padx=198).grid(row=1, column=3, padx=140)
for i in range(len(list1)):
application = list1[i].split(";;;")[0]
username = list1[i].split(";;;")[1]
password = list1[i].split(";;;")[2]
Label(f1, text=application, fg="white", bg="black", font="Calibri 20 bold", pady=5).grid(row=i+2, column=1)
Label(f1, text=username, fg="white", bg="black", font="Calibri 20 bold", pady=5).grid(row=i+2, column=2)
Label(f1, text=password, fg="white", bg="black", font="Calibri 20 bold", pady=5).grid(row=i+2, column=3)
root2.mainloop()
def checkPassword(password, l):
if password == "a":
root.destroy()
secondwindow()
else:
l.config(text="Wrong Password")
def password_window():
root.geometry('450x270')
root.title("Secure Your Password")
root.minsize(450, 270)
root.maxsize(450, 270)
root.configure(bg="black")
Label(root, text="Secure Your Password", fg="white", bg="black", font="Algerian 24 italic").pack(side=TOP)
Label(root, text="Your Password", fg="white", bg="black", font="Clibri 15").pack(pady=10)
password = StringVar()
Entry(root, textvariable=password, bg="grey", fg="white", font="Calibri 15 bold").pack(pady=10)
Button(root, text="Login", bg="grey", fg="white", activebackground="grey", font="Calibri 10", command=lambda: checkPassword(password.get(), l)).pack(pady=8)
l = Label(root, fg="red", bg="black", font="Clibri 10 bold")
l.pack()
password_window()
root.mainloop()
And my passwords.txt:
StackOverflow;;;PomoGranade;;;PomoGranade_StackOverflow
GitHub;;;Pomogranade;;;PomoGranade_GitHub
I am new to python and tkinter. Thanks for help in advance :)
I do not recommend using * imports, though it may not be exactly wrong in this case.
Use the TopLevel widget instead of initialising another Tk window. See why using another Tk is not good.
Use .grab_set() (Look at #TheLizzard's link in the comment for a better example)
Look at this example -
import tkinter as tk
root = tk.Tk()
def f1():
top1 = tk.Toplevel(root)
b2 = tk.Button(top1,text='Close New Window',command=top1.destroy)
b2.pack()
top1.grab_set()
b1 = tk.Button(root,text='Create Mandatory Window',command=f1)
b1.pack()
root.mainloop()
If you run this code, you will see that the first window does not react to any mouse press etc... and also you cannot close the first window after opening the new window until the it is closed

Why does my Tkinter toplevel freeze after a while?

I have stopwatch running on both my main window and my top level. The watch starts as soon as the program is launched and is stopped by closing the program. The toplevel is launched by using a button. The toplevel is supposed to display a copy of the stopwatch. But, when I keep the toplevel open for over an hour, it freezes. The main window runs fine. The toplevel works fine for another hour or so when I manually close and reopen it. Does anyone know what could be the problem? I'm running the code on Windows OS.
Here's the relevant code:
import datetime
import time
import tkinter as tk
time_elapse_flag = False
start_time = datetime.datetime.now()
diff = 0
def time_elapse():
global time_elapse_flag
global diff
if(not time_elapse_flag):
time_elapse_flag = True
time_elapse_count = tk.Label(window, text='', relief='sunken', bg='white', font='Helvetica 16 bold')
time_elapse_count.place(x=10, y=150, width=200, height=50)
start_time = datetime.datetime.now().replace(microsecond=0)
time_elapse_label = tk.Label(window, text='Recording data since:', font='Helvetica 12 bold')
time_elapse_label.place(x=10, y=120, width=200, height=30)
def update_time():
global start_time
global diff
current_time = datetime.datetime.now().replace(microsecond=0)
diff = current_time - start_time
time_elapse_count.config(text=diff)
time_elapse_label.after(1000,update_time)
update_time()
else:
time_elapse_flag = False
time_elapse_count = tk.Label(window, text='')
time_elapse_count.place(x=10, y=150, width=200, height=50)
time_elapse_label = tk.Label(window, text='')
time_elapse_label.place(x=10, y=120, width=200, height=30)
def Param_Window():
global time_elapse_flag
global diff
pw = tk.Toplevel()
pw.geometry('1200x550')
def update_values():
global diff
if(time_elapse_flag):
time_elapse_label = tk.Label(pw, text='Recording data since:', font='Helvetica 20 bold')
time_elapse_count = tk.Label(pw, text=diff, relief='sunken', bg='white', font='Helvetica 16 bold')
time_elapse_label.place(x=640, y=350, width=300, height=50)
time_elapse_count.place(x=640, y=400, width=200, height=50)
else:
time_elapse_label = tk.Label(pw, text='')
time_elapse_count = tk.Label(pw, text='')
time_elapse_label.place(x=640, y=350, width=300, height=50)
time_elapse_count.place(x=640, y=400, width=200, height=50)
pw.after(800,update_values)
update_values()
if __name__ == "__main__":
window = tk.Tk()
window.geometry('550x250')
disp_param_button = tk.Button(window, text='Display Parameters', command=Param_Window, bg='sky blue', font='Helvetica 12 bold', width=20, state='normal', relief='raised')
disp_param_button.place(x=300, y=150)
print('Automatically starting in')
for cd in range(5):
print(5-cd)
time.sleep(1)
time_elapse()
window.mainloop( )
The problem is that you're creating two new label widgets every 800 milliseconds in Param_Window. When you run for an hour, that means you will have created 4,500 label widgets. At some point you're going to hit a hard limit, because you can't create an infinite number of widgets.
You need to restructure your code so that you create the labels once and then reconfigure them instead of creating new widgets on every iteration.
To add to Bryan's answer you should also move the code for sleep to be outside of the tk instance and fix your indention.
Here is a corrected version of your code that will fix all the problems I can see.
Indention fix
Sleep moved outside of tk instance (not related to your main problem but is wrong just the same)
changed the Param_Window function to update labels instead of recreating them ever 0.8 seconds.
Code:
import tkinter as tk
import datetime
import time
time_elapse_flag = False
start_time = datetime.datetime.now().replace(microsecond=0)
def time_elapse():
global time_elapse_flag
global diff
if(not time_elapse_flag):
time_elapse_flag = True
time_elapse_count = tk.Label(window, text='', relief='sunken', bg='white', font='Helvetica 16 bold')
time_elapse_count.place(x=10, y=150, width=200, height=50)
start_time = datetime.datetime.now().replace(microsecond=0)
time_elapse_label = tk.Label(window, text='Recording data since:', font='Helvetica 12 bold')
time_elapse_label.place(x=10, y=120, width=200, height=30)
def update_time():
global start_time
global diff
current_time = datetime.datetime.now().replace(microsecond=0)
diff = current_time - start_time
time_elapse_count.config(text=diff)
time_elapse_label.after(1000, update_time)
update_time()
else:
time_elapse_flag = False
time_elapse_count = tk.Label(window, text='')
time_elapse_count.place(x=10, y=150, width=200, height=50)
time_elapse_label = tk.Label(window, text='')
time_elapse_label.place(x=10, y=120, width=200, height=30)
def Param_Window():
global time_elapse_flag
global diff
pw = tk.Toplevel()
pw.geometry('1200x550')
time_elapse_label = tk.Label(pw, text='Recording data since:', font='Helvetica 20 bold')
time_elapse_count = tk.Label(pw, text=diff, relief='sunken', bg='white', font='Helvetica 16 bold')
time_elapse_label.place(x=640, y=350, width=300, height=50)
time_elapse_count.place(x=640, y=400, width=200, height=50)
def update_values():
global diff
if(time_elapse_flag):
time_elapse_label.config(text='Recording data since:')
time_elapse_count.config(text=diff)
else:
time_elapse_label.config(text='')
time_elapse_count.config(text='')
pw.after(800, update_values)
update_values()
if __name__ == "__main__":
print('Automatically starting in')
for cd in range(5):
print(5-cd)
time.sleep(1)
window = tk.Tk()
window.geometry('550x250')
disp_param_button = tk.Button(window, text='Display Parameters', command=Param_Window, bg='sky blue', font='Helvetica 12 bold', width=20, state='normal', relief='raised')
disp_param_button.place(x=300, y=150)
time_elapse()
window.mainloop()

Pack manager of tkinter in python

I have written this code in python 2.7 and i have used "pack_propagate" in this code. First time "pack_propagate" works fine but when i click on the button 1, "pack_propagate" doesn't work. can anyone tell me the reason?
from tkinter import *
root = Tk()
root.title("pack_forget check")
tk_window_width = 500
tk_window_height = 300
screen_width = root.winfo_screenwidth() # width of the screen
screen_height = root.winfo_screenheight() # height of the screen
x = (screen_width/2) - (tk_window_width/2)
y = (screen_height/2) - (tk_window_height/2)
root.geometry('%dx%d+%d+%d' %(tk_window_width, tk_window_height, x, y))
frame1 = Frame(root, bg="red", height=250, width=250)
frame2 = Frame(root, bg="green", height=250, width=250)
def first():
frame1.pack(side=TOP, padx=20, pady=20)
frame1.pack_propagate(0)
frame2.pack_forget()
def second():
frame2.pack(side=TOP, padx=20, pady=20)
frame2.pack_propagate(0)
frame1.pack_forget()
label1 = Label(frame1, text="Frame 1")
label1.pack(side="top")
button1 = Button(frame1, text="button 1", command=second, width=10)
button1.pack(side="bottom")
label2 = Label(frame2, text="Frame 2")
label2.pack(side="top")
button2 = Button(frame2, text="button 2", command=first, width=10)
button2.pack(side="bottom")
frame1.pack(side=TOP, padx=20, pady=20)
frame1.pack_propagate(0)
root.mainloop()
Add this before the mainloop(), it seems to solve the problem. Honestly, I am unsure how it works, but looks like it does. I saw you did that with frame1 and I was like: hey, why not frame2? :D
frame2.pack(side=TOP, padx=20, pady=20)
frame2.pack_propagate(0)
root.mainloop()

Need some help in creating a tkinter countdown

I am trying to create a timer in tkinter. It count down from set time and then output "Time is up". I have written most of my code. I also have inserted a logging system, so I can work over some errors, which are recorded into a log file.
Code:
from tkinter import *
import logging
logging.basicConfig(filename='timer_err.log',format='%(levelname)s:%(message)s',level=logging.DEBUG)
main = Tk()
main.wm_attributes("-fullscreen",True)
main.wm_attributes("-transparentcolor","darkgreen")
main.title("Timer")
main.config(background="orange")
timerun = 0
comp = 0
secs = DoubleVar()
mins = IntVar()
hrs = IntVar()
def ok():
global timerun
try:
comp = float(float(secs.get())+int(mins.get()*60)+int(hrs.get()*3600))
done.config(state="disabled")
logging.info(("\t{} - Program launched").format(asctime(localtime())))
while timerun < comp:
timerun = clock()
disp.config(state="normal")
disp.insert(0, str(round(comp-timerun, 3)))
main.update()
disp.delete(0, END)
disp.config(state="readonly")
disp.config(state="normal")
disp.insert(0, "Time is up!")
disp.config(state="readonly")
main.update()
def end(self):
main.destroy()
logging.info(("\t{} - Program successfully terminated").format(asctime(localtime())))
main.bind("<Escape>",end)
except Exception as e:
logging.debug(("\t{} - {}").format(asctime(localtime()),str(e)))
logging.warning(("\t{} - {}").format(asctime(localtime()),str(e)))
pass
finally:
logging.info(("\t{} - Program stopped").format(asctime(localtime())))
dispframe = Frame(main, bg="orange")
dispframe.pack(fill="both")
disp = Entry(dispframe, fg="black", bg="lightgray", font=("Arial", 100, "bold"), bd=0, state="readonly", takefocus=False, readonlybackground="lightgray", selectforeground="white", selectbackground="navy")
disp.pack(fill="x", pady=12, side="left")
setframe = Frame(main, bg="orange")
setframe.pack(fill="both")
seconds = Spinbox(setframe, fg="red", bg="yellow", from_=0, to=59.5, increment=0.5, font=("Arial", 100, "bold"), bd=0, state="readonly", takefocus=True, readonlybackground="yellow", buttonbackground="green", selectforeground="white", selectbackground="navy", wrap=True, textvariable=secs)
seconds.pack(fill="x", pady=12)
minutes = Spinbox(setframe, fg="red", bg="yellow", from_=0, to=59, font=("Arial", 100, "bold"), bd=0, state="readonly", takefocus=True, readonlybackground="yellow", buttonbackground="green", selectforeground="white", selectbackground="navy", wrap=True, textvariable=mins)
minutes.pack(fill="x", pady=12)
hours = Spinbox(setframe, fg="red", bg="yellow", from_=0, to=99999, font=("Arial", 100, "bold"), bd=0, state="readonly", takefocus=True, readonlybackground="yellow", buttonbackground="green", selectforeground="white", selectbackground="navy", wrap=True, textvariable=hrs)
hours.pack(fill="x", pady=12)
okframe = Frame(main, bg="orange")
okframe.pack(fill="both")
done = Button(okframe, fg="red", bg="yellow", text="Done", font=("Arial", 100, "bold"), bd=0, activeforeground="red", activebackground="yellow", underline=1, command=ok)
done.pack(fill="x", pady=12)
from time import *
main.mainloop()
Could someone help me to create a "Reset" button, which sets time back to 0?
Or at least give me a slight advice to me on how to do that. Thank you.

Categories