I created a timer but for some reason the timer randomly stops updating until I click the tkinter window then it starts to update again. This happens about every minute or two. Here is my code:
from tkinter import *
from threading import Thread
tk = Tk()
tk.attributes('-alpha',1)
tk ['bg']='#302F2F'
tk.title('')
tk.wm_attributes('-topmost', 1) # put the window to front
def timer():
while True:
sleep(0.009)
...
#cut out all the stuff of creating the time but here is how i did it
label['text'] = (ftime2)
label['fg'] = colorfortext
label2['text'] = (ftime)
label2['fg'] = colorfortext
label3['text'] = (numberofworlds)
label3['fg'] = 'blue'
label = Label(tk, '', font=('Arial', 30),bg='#302F2F')
label.grid(columnspan=2)
label2 = Label(tk, '', font=('Arial', 30),bg='#302F2F')
label2.grid(columnspan=2)
label3 = Label(tk, '', font=('Arial', 30),bg='#302F2F')
label3.grid(columnspan=2)
timer_thread = Thread(target=timer)
timer_thread.start()
tk.mainloop()
Related
I am trying to make a game using a countdown timer for 60s.
My issue is that as the countdown timer is recursive, it keeps running until t == 0 when it runs the endgame() function.
if you pass the level, the initial countdown timer will still end after 60s which in turn will end the game. I need a way to run the next level without the initial countdown ending and ending the game.
I have tried using if True statements at the start of the function which only paused the loop until the next instance of the function started.
code:
from tkinter import *
import ctypes
from scrambld_back import *
from tkinter import font
import time
from nltk.corpus import words
user32 = ctypes.windll.user32
screensize = [user32.GetSystemMetrics(0), user32.GetSystemMetrics(1)]
root = Tk()
root.geometry(f'500x500+{screensize[1]-250}+100')
root.title('Scrambld')
root.configure(bg='white')
over = Tk()
over.geometry(f'500x500+{screensize[1]-250}+100')
root.title('Scrambld')
root.configure(bg='white')
over.iconify()
gamefont = font.Font(family='impact', size=30)
levelfont = font.Font(family='impact', size=20)
level = 0
Label(over, text='GAME OVER', font=gamefont)
Label(over, text=f'Level {level}', font=levelfont)
def endgame():
over = Toplevel(root)
over.geometry(f'500x500+{screensize[1]-250}+100')
Label(over, text='GAME OVER', font=gamefont).place(x=250, y=215, anchor='center')
Label(over, text=f'Level {level}', font=levelfont).place(x=250, y=285, anchor='center')
def play(level):
t = 15
gamewords = []
for x in words.words():
if len(x) == level+3:
gamewords.append(x)
word = gamewords[random.randint(0, len(gamewords))]
gameplay = generate(list(word))
Label(root, text=f'Level {level}', font=levelfont, bg='white').place(x=250, y=70, anchor='center')
Label(root, text=gameplay, font=gamefont, bg='white', width=100).place(x=250, y=140, anchor='center')
guess = Entry(root, font=levelfont, bg='white')
guess.place(x=250, y=360, anchor='center')
guess.bind('<Return>', lambda event, word=word: compare(event, word))
def compare(event, word):
if word.upper() == guess.get().upper():
play(level+1)
else:
pass
submit = Button(root, text='SUBMIT', font=levelfont, bg='white', width=21, command=lambda: compare(None, word))
submit.place(x=250, y=420, anchor='center')
timer = StringVar()
Label(root, textvariable=timer, font=levelfont, bg='white', width=8).place(x=250, y=250, anchor='center')
def countdown(t, lev):
print(lev, level)
print(t)
t=int(t)-1
if t < 10:
t=f'0{t}'
timer.set(f'00:{t}')
root.update()
if int(t) < 1 and lev == level:
endgame()
else:
root.after(1000, lambda: countdown(t, lev))
countdown(t, 1)
play(1)
I want to add global hotkey (using the pynput module) to my Tkinter script (Random Number Generator). I want to get random number every time I press 'f7' button. It also has to work without focusing on the app. Unfortunately the app is not responding after a while. It worked once/twice but after a minute or so it got frozen.
import tkinter as tk
import random
from pynput import keyboard
rng = random.SystemRandom()
def Draw():
global text
frame=tk.Frame(root,width=100,height=100,relief='solid',bd=0)
frame.place(relx = 0.5, rely = 0.5, anchor = 'center')
text=tk.Label(frame,text='HELLO', font = "Helvetica 65 bold", justify='center')
text.pack()
def on_press(key):
try:
k = key.char
except:
k = key.name
if k in ['f7']:
return False #stop listening
n = 0
def Refresher():
global text
global n
text.configure(text=rng.randint(0,100), fg ="white", bg = "black")
root.after(100, Refresher)
if n == 1:
listener = keyboard.Listener(on_press=on_press)
listener.start()
listener.join()
n = 1
root=tk.Tk()
root["bg"] = "black"
root.title("RNG")
Draw()
Refresher()
root.mainloop()
I found the solution. We need bindglobal library and then we have global hotkeys in Tkinter. More info: https://libraries.io/pypi/bindglobal
My code:
import tkinter as tk
import random
from bindglobal import BindGlobal
rng = random.SystemRandom()
def Draw():
global text
frame=tk.Frame(root,width=100,height=100,relief='solid',bd=0)
frame.place(relx = 0.5, rely = 0.5, anchor = 'center')
text=tk.Label(frame,text='HELLO', font = "Helvetica 65 bold", justify='center')
text.configure(text=rng.randint(0,100), fg ="white", bg = "black")
text.pack()
def Refresher(e):
global text
text.configure(text=rng.randint(0,100), fg ="white", bg = "black")
root = tk.Tk()
root.title("RNG - F7")
root["bg"] = "black"
Draw()
bg = BindGlobal()
bg.start()
bg.gbind("<f7>",Refresher)
root.mainloop()
Plus I needed to modify the mentioned library because there was no support for 'F7' button.
Find and open bindglobal/init.py and add 'f7', e.g. like this:
class TkKeys(object):
tk_keys = {}
for i in ( 'space','BackSpace', 'Tab'
, 'Delete', 'End', 'Home', 'Caps_Lock'
,'Left','Right', 'Up', 'Down', 'f7'
,'Menu','Insert', 'Pause', 'Num_Lock', 'Scroll_Lock' #Those fails on OSX
):
I started coding just a few days ago, so I hope you can help me :)
I'm trying to connect an entry with my timer. So user can choose which time they want to set. They can set the value in minutes. I already got it to get the value of the entry in my timer, but the timer won't start. I'm using tkinter to code this.
So if the user enters e.g. "3" my timer will display "03:00" but time won't start running. The console is printing no errors either. Here is my code:
from tkinter import *
from PIL import ImageTk, Image
import math
window = Tk()
window.title("u'Clock")
window.config(padx=50, pady=50, bg="#1a1c20", highlightthickness=0)
timer = None
def start_timer():
count_down(0)
def get_time():
time = input_time_do.get()
int_time = int(time)
return int_time
def count_down(count):
count = get_time()
count_min = count
count_sec = count*60 % 60
if count_min < 10:
count_min = f"0{count_min}"
if count_sec < 10:
count_sec = f"0{count_sec}"
canvas.itemconfig(timer_text, text=f"{count_min}:{count_sec}")
if count > 0:
global timer
window.after(1000, count_down, count - 1)
input_time_do = Entry(width="20", background="DarkSeaGreen")
input_time_do.insert(END, string="Set Workout Time")
input_time_do.grid(column=1, row=2, padx=10, pady=10)
start_button = Button(text="START", command=start_timer)
start_button.grid(column=1, row=6, padx=10, pady=10)
canvas = Canvas(width=400, height=266, bg="#fbf7f0", highlightthickness=0)
gym_img = ImageTk.PhotoImage(Image.open("gym1.jpg")) # PIL solution
canvas.create_image(200, 133, image=gym_img)
timer_text = canvas.create_text(200, 135, text="00:00", fill="#fbf7f0", font=
("Roboto", 30))
canvas.grid(column=1, row=1)
window.mainloop()
I have this render_gui function in Python.
def render_gui():
global root
global prev_key
global listbox, label1, entry1
prev_key = 0
root = tk.Tk()
root.title('Server Chat Application')
scroll = Scrollbar(root)
scroll.pack(side = "right" , fill= "y")
listbox = Listbox(root, width=80, height=30)
listbox.grid(row=1,column=1, columnspan=5,rowspan=3)
scroll.config(command = listbox.yview)
label1 = ttk.Label(root, text='Message Entry Box : ')
label1.grid(row=4,column=1)
entry1 = ttk.Entry(root, width=60)
entry1.grid(row=4, column=2)
root.geometry('490x520')
#print('before main loop')
root.bind('<KeyPress>', onKeyPress)
#print('after main loop')
root.mainloop()
It was throwing an error after I added the scrollbar thing. How will I encorporate a vertical and horizontal scrollbar in my listbox. Thanks.
UPDATE:
Below is the complete code. I have edited it and omit the pack thing replace it with grid function but the scrollbar wasn't showing. How am I gonna deal with this?
import os
import signal
import socket
import time
import threading
import keyboard
from threading import Thread
import tkinter as tk
from tkinter import ttk
from tkinter import *
import webbrowser
def onKeyPress(event):
global prev_key
global root
global listbox, label1, entry1
if(event.keycode == 13):
print(Entry.get(entry1))
msg = Entry.get(entry1)
if len(str.encode(msg)) > 0:
client.send(str.encode("\nserver > " + msg))
listbox.insert(END, "server > " + msg)
entry1.delete(0,END)
if(event.keycode == 88) and (prev_key == 17):
root.destroy()
try:
raise client.send(str.encode("***Server has been shutdowned***"))
except:
print ("You are not yet connected to any client to send shutdown notice.")
sys.exit()
os.kill(os.getpid(), signal.SIGUSR1)
prev_key = event.keycode
def render_gui():
global root
global prev_key
global listbox, label1, entry1
prev_key = 0
root = tk.Tk()
root.title('Server Chat Application')
scroll = Scrollbar(root)
#scroll.pack(side = "right" , fill= "y")
scroll.grid(row=0, column=10, rowspan=10, sticky='ns')
listbox = Listbox(root, width=80, height=30)
listbox.grid(row=1,column=1, columnspan=5,rowspan=3)
scroll.config(command = listbox.yview)
listbox.config(yscrollcommand=scroll.set)
label1 = ttk.Label(root, text='Message Entry Box : ')
label1.grid(row=4,column=1)
entry1 = ttk.Entry(root, width=60)
entry1.grid(row=4, column=2)
root.geometry('490x520')
#print('before main loop')
root.bind('<KeyPress>', onKeyPress)
#print('after main loop')
root.mainloop()
if __name__ == "__main__":
Thread(target= render_gui).start()
I'm trying to show a sequence of numbers on the screen at regular intervals.
I'm new to python so it may be something obvious but I have tried .after and pygame.time.wait, but neither worked.
this is the code:
from tkinter import*
from random import *
import time
my_list = []
def Create_NUM(event):
x = 0
for x in range(level + 2):
button1.destroy()
num = randint(1, 100)
my_list.append(num)
Label(root, text=num,fg="red").pack()
one.pack()
time.sleep(2)
root=Tk()
num = 0
level = 1
bottomFrame = Frame(root)
bottomFrame.pack(side=BOTTOM)
button1 = Button(bottomFrame, text="Click to start game",fg="red")
button1.bind("<Button-1>", Create_NUM)
button1.pack()
root.mainloop()
I assume you want to show new number in place of old number, not below it.
import tkinter as tk
import random
def start():
# hide button
button.pack_forget()
# run `add_number` first time
add_number(level+2)
def add_number(x):
num = random.randint(1, 100)
my_list.append(num)
label['text'] = num
if x > 0:
# repeat after 2000ms (2s)
root.after(2000, add_number, x-1)
else:
# show button again after the end
button.pack()
# --- main ---
my_list = []
level = 1
root = tk.Tk()
label = tk.Label(root)
label.pack()
button = tk.Button(root, text="Click to start game", command=start)
button.pack()
root.mainloop()
Just use this simple command in your function root.update()