Error inside of the terminal.
/Users/aidan/Documents/GitHub/Perceptual/Threading.py:81: UserWarning: Starting a Matplotlib GUI outside of the main thread will likely fail.
plt.show()
2022-11-06 14:28:07.960 Python[25376:1206036] *** Terminating app due to uncaught exception 'NSInternalInconsistencyException', reason: 'NSWindow drag regions should only be invalidated on the Main Thread!'
Code of the python project.
import time
import tkinter as tk
#import tkinter as tkk
from tkinter.ttk import *
from PIL import Image, ImageTk
import random
import threading
#imports for BackEnd
import pyautogui as mouse
import matplotlib.pyplot as plt
#Created Global Array
x = []
y = []
root = tk.Tk()
root.title("Perceptual Threading")
root.geometry("900x600")
#Sperates the canvase into diffrent coloms
root.columnconfigure(6, weight = 0)
root.rowconfigure(10, weight = 0)
def BackEndDebug():
DebugInt = 0
while(DebugInt != -1):
DebugNumber.config(text=f'Random Number: {DebugInt}')
DebugInt += 1
time.sleep(0.0000000001)
#Load Logo
def LoadLogo():
logo = Image.open("PerceptualLogoTransparent.png")
logo = logo.resize((125, 125))
logo = ImageTk.PhotoImage(logo)
logo_label = tk.Label(image = logo)
logo_label.image = logo
logo_label.grid(column=0, row=0, sticky=tk.W, padx=5, pady=5)
def LoadDashboard():
Dashboard = Image.open("Mercades Dashboard .jpeg")
Dashboard = Dashboard.resize((775,300))
Dashboard = ImageTk.PhotoImage(Dashboard)
Dashboard_label = tk.Label(image = Dashboard)
Dashboard_label.image = Dashboard
Dashboard_label.grid(column = 2, row = 6, columnspan=3, rowspan=2)
def MouseGraph():
control = True
count = 0
t = 1
inc = .1
check1, check2, check3 = 0, 1, 2
mouse.moveTo(960, 540)
while control:
thing = mouse.position()
y.append(thing[0] - 960)
x.append(inc * t)
if thing[1] > 540 or thing[1] < 540:
mouse.moveTo(thing[0], 540)
count += 1
t += 1
if count > 2:
if (y[check2] < y[check1] and y[check2] < y[check3]) or (y[check2] == y[check1] and y[check2] < y[check3]):
print(f'{y[check2]} is the relative minimum.')
if (y[check2] > y[check1] and y[check2] > y[check3]) or (y[check2] == y[check1] and y[check2] > y[check3]):
print(f'{y[check2]} is the relative maximum.')
check1 += 1
check2 += 1
check3 += 1
if count > 100:
control = False
# return(x, y)
plt.plot(x, y)
plt.xlabel('time')
plt.ylabel('distance turned')
plt.show()
time.sleep(inc)
DebugNumber = Label(root, text="Debug Number!")
DebugNumber.grid(column= 6, row= 0, sticky=tk.E)
StartBackendDebug = Button(root, text="Start the BackendDebug", command = threading.Thread(target=BackEndDebug).start)
StartBackendDebug.grid(column= 5, row= 0, sticky=tk.E)
StartGraph = Label(root, text="Start Graph!")
StartGraph.grid(column= 6, row= 1, sticky=tk.E)
StartGraphButton = Button(root, text="Begin", command = threading.Thread(target=MouseGraph).start)
StartGraphButton.grid(column= 5, row= 1, sticky=tk.E)
LoadLogo()
LoadDashboard()
root.mainloop()
I have tried returning the arrays after making them global variables but I do not know how to then have a call after the thread is over. This is my first project using threading and am unsure if I need to add classes or what. Is there a way to call the method of a class from another class or run the code in the main thread without Tkinter having an issue. I have also tried looking into other graphing methods but this seems to be the only real way.
Related
I have a 2 vertical lines on a canvas with a gap in the middle (generated randomly every time). This line starts on the right side of the canvas. When I click the "l" key it runs a function that moves the line left by 5, and you can keep clicking "l" until it reaches the left side. I want to know how to set it up so I only have to press the "l" key once and the line will slowly move across the screen until it reaches the left side. Any help would be appreciated
import random
import time
from tkinter import *
window = Tk()
window.geometry("300x300")
window.title("GUI")
window.resizable(FALSE, FALSE)
label1 = Label(window, text="My First GUI", font=("arial", 16, "bold"))
label1.pack()
canvas = Canvas()
canvas.config(bg="gray")
canvas.place(width=300, height=150, x=0, y=150)
def key_pressed(event):
if event.char == "l":
move_line()
def create_gap():
gap_ycoords = []
# random number between 10 and 95 in increments of 5
first_line_end = random.randrange(10, 96, 5)
gap_ycoords.append(first_line_end)
second_line_start = first_line_end + 50
gap_ycoords.append(second_line_start)
return gap_ycoords
def draw_line_obstacle(canvas_ref):
y_coord = create_gap()
top_line = canvas_ref.create_line(295, 5, 295, y_coord[0], tags="top_line")
bottom_line = canvas_ref.create_line(295, y_coord[1], 295, 145, tags="bottom_line")
draw_line_obstacle(canvas)
def move_line():
if canvas.coords("top_line")[0] > 5:
tcoords = canvas.coords("top_line")
bcoords = canvas.coords("bottom_line")
canvas.coords("top_line", tcoords[0] - 5, tcoords[1], tcoords[2] - 5, tcoords[3])
canvas.coords("bottom_line", bcoords[0] - 5, bcoords[1], bcoords[2] - 5, bcoords[3])
window.bind("<Key>", key_pressed)
window.mainloop()
You're so close! Only one more line needed in your move_line function:
def move_line():
if canvas.coords("top_line")[0] > 5:
... # other code
canvas.after(100, move_line) # delay in ms, lower=faster movement
You need to use .after(). This basically calls a function every, say, 20 milliseconds.
Calling this function repeatedly will make it so that when you press the "l" key once, the line will move to the other end of the screen.
Code:
import random
import time
from tkinter import *
window = Tk()
window.geometry("300x300")
window.title("GUI")
window.resizable(FALSE, FALSE)
label1 = Label(window, text="My First GUI", font=("arial", 16, "bold"))
label1.pack()
canvas = Canvas()
canvas.config(bg="gray")
canvas.place(width=300, height=150, x=0, y=150)
def key_pressed(event = None):
move_line()
window.after(20, key_pressed)
def create_gap():
gap_ycoords = []
# random number between 10 and 95 in increments of 5
first_line_end = random.randrange(10, 96, 5)
gap_ycoords.append(first_line_end)
second_line_start = first_line_end + 50
gap_ycoords.append(second_line_start)
return gap_ycoords
def draw_line_obstacle(canvas_ref):
y_coord = create_gap()
top_line = canvas_ref.create_line(295, 5, 295, y_coord[0], tags="top_line")
bottom_line = canvas_ref.create_line(295, y_coord[1], 295, 145, tags="bottom_line")
draw_line_obstacle(canvas)
def move_line():
if canvas.coords("top_line")[0] > 5:
tcoords = canvas.coords("top_line")
bcoords = canvas.coords("bottom_line")
canvas.coords("top_line", tcoords[0] - 5, tcoords[1], tcoords[2] - 5, tcoords[3])
canvas.coords("bottom_line", bcoords[0] - 5, bcoords[1], bcoords[2] - 5, bcoords[3])
window.bind("<l>", key_pressed)
window.mainloop()
On this line: window.after(20, key_pressed), you can change the number 20 to something higher to move slower, and something lower to move faster.
Hope this helps!
I'm writing a scientific calculator with 2nd button. What is the function for second button so for example it changes sin to sin^-1, plus changing the sin button command; and if you click the 2nd button again, it changes sin^-1 back to sin
I would split my calculator up into section using different frames (one to show the calculations , one with buttons which won't have 2 functions and lastly the buttons which have 2 functions).
The reason I would split it up is because I would use destroying objects and making the new ones this splitting up means you can destroy the wanted frame rather than specific buttons (would require less code). Also for this I would have 3 create GUI defs. one would be the buttons with one function and the bit showing the calculations. one be the buttons which have 2 functions (their first function) and lastly the buttons which have 2 functions (their second functions). To decide between which GUI gen def to use have an if statement with global variable which gets changed each time 2nd function button called and that decides which def to use.
If it was just commands you wanted changing instead of both labels and commands I would have a variable which is etheir 1 or 2(change when 2nd button clicked) then in your definitions (ones which your buttons call) have an if statement to decide between to do normal action (e.g cos) or 2nd action (e.g cos-1).
Here is code below that uses what i have described in the first paragraph:
from tkinter import *
class Calc(Frame):
def __init__(self, master):
self.modefunction = 1
""" Initialize the frame. """
super(Calc,self).__init__(master)
self.grid()
self.calculations_frm = Frame(self, width=100, height=30)#bg = "red"
self.calculations_frm.grid(row = 0, column = 0, columnspan=2)
self.buttons_frm = Frame(self, width= 50, height=30,)#bg = "green")
self.buttons_frm.grid(row = 1, column = 1)
self.buttons_2_functions_1_frm = Frame(self, width=50, height=30)#bg = "blue")
self.buttons_2_functions_1_frm.grid(row = 1, column = 0)
self.create_GUI()
def create_show_calculations(self):
self.calculation_lbl = Label(self.calculations_frm, text = "will show caluclations here").pack()
def create_buttons(self):
#mc stands for mode change
self.mode_change_btn = Button(self.buttons_frm, text = "mc", command = self.mode_change, height = 1, width = 5)
self.mode_change_btn.grid(row = 0,column = 0)
self.plus_btn = Button(self.buttons_frm, text = "plus", height = 1, width = 5)
self.plus_btn.grid(row = 1,column = 0)
def create_GUI(self):
self.create_show_calculations()
self.create_buttons()
self.create_1_function_gui()
def create_1_function_gui(self):
self.tan_btn = Button(self.buttons_2_functions_1_frm, text = "tan", height = 1, width = 5)
self.tan_btn.grid(row = 0,column = 0)
self.san_btn = Button(self.buttons_2_functions_1_frm, text = "san", height = 1, width = 5)
self.san_btn.grid(row = 0,column = 1)
self.coz_btn = Button(self.buttons_2_functions_1_frm, text = "coz", height = 1, width = 5)
self.coz_btn.grid(row = 1,column = 0)
def create_2_function_gui(self):
self.buttons_2_functions_2_frm = Frame(self, width=50, height=30)#bg = "blue")
self.buttons_2_functions_2_frm.grid(row = 1, column = 0)
self.inverse_tan_btn = Button(self.buttons_2_functions_2_frm, text = "tan-1", height = 1, width = 5)
self.inverse_tan_btn.grid(row = 0,column = 0)
self.inverse_san_btn = Button(self.buttons_2_functions_2_frm, text = "san-1", height = 1, width = 5)
self.inverse_san_btn.grid(row = 0,column = 1)
self.inverse_coz_btn = Button(self.buttons_2_functions_2_frm, text = "coz-1", height = 1, width = 5)
self.inverse_coz_btn.grid(row = 1,column = 0)
def mode_change(self):
if self.modefunction == 1:
self.buttons_2_functions_1_frm.destroy()
self.modefunction = 2
self.buttons_2_functions_2_frm = Frame(self, width=50, height=30)#bg = "blue")
self.buttons_2_functions_2_frm.grid(row = 1, column = 0)
self.create_2_function_gui()
else:
self.buttons_2_functions_2_frm.destroy()
self.modefunction = 1
self.buttons_2_functions_1_frm = Frame(self, width=50, height=30)#bg = "blue")
self.buttons_2_functions_1_frm.grid(row = 1, column = 0)
self.create_1_function_gui()
root = Tk()
root.title("booking system")
root.geometry("500x500")
root.configure(bg="white")
app = Calc(root)
root.mainloop()
hi I'm a student and I'm working with ktinker for the first time. I am currently trying to create a program that follows this order:
open a map in matplotlib
a popup window is called for users to enter in information
when the user clicks on the map grid the coordinates and user
info are stored in a dictionary
matplotlib generates a plot point on the location
The trouble is, when I call the popup window I have written in tkinter, calling the mainloop() function breaks the matplotlib window and it wont generate the plot points until the map window is closed.
getting rid of the mainloop fixes it but then means i cant get the data from the popup.
Anyone know how I can stop one from interfering with the other? i have to keep them in separate classes as Im meant to demonstrate modularity in my code.
here is the main code
import matplotlib.pyplot as plt
import matplotlib.image as mpimg
import numpy as np
import popup1 as ap
__author__ = "k1221169"
__date__ = "$15-Nov-2015 11:29:21$"
markerList = []
xplots = []
yplots = []
desc = ''
title = ''
fig = plt.figure()
ax = fig.add_subplot(111)
ax.plot(np.random.rand(10))
img = mpimg.imread('overland map 1.png')
imgplot = plt.imshow(img)
plt.ylim(ymax=1)
plt.xlim(xmin=1)
def mrkApnd(a,b):
a.update(b)
print a
markerList.append(a)
def onclick(event):
if spacecheck(event.xdata, event.ydata):
#print markerList[0]['x']
idx = np.abs(xplots - event.xdata).argmin()
print xplots[idx]
for i in markerList:
if xplots[idx] == i['x'] :
print i
#c = i
ap.useroutput(i)
else:
input1 = ap.userinput()
input2 = {'x':event.xdata, 'y':event.ydata}
input1['title'] = title
input1['desc'] = desc
mrkApnd(input1,input2)
drawMarks()
print input1
return markerList
cid = fig.canvas.mpl_connect('button_press_event', onclick)
def drawMarks():
plt.ion()
for i in markerList:
xplots.append(i['x'])
yplots.append(i['y'])
plt.plot(i['x'], i['y'], i['type'])
def spacecheck(x,y):
a = bool
if np.isclose(xplots, x, atol=50.0).any() and np.isclose(yplots, y, atol=50.00).any():
a=True
print 'yes'
return a
plt.draw()
plt.show()
and here is the popup code called from another file
from Tkinter import *
class popup1():
def __init__(self):
pass
def userinput():
pop = Toplevel()
pop.title("marker")
pop.geometry("300x500+200+200")
#string for title
frame = Frame(pop)
entry = Entry(frame)
entry.pack(side = TOP)
frame.pack( padx =20, pady =20)
#radius button for visibility
frame2 = Frame(pop)
selection = StringVar()
radio_1 = Radiobutton(frame2, text = 'Character', variable = selection, value = 'ob')
radio_2 = Radiobutton(frame2, text = 'Item', variable = selection, value = 'or')
radio_3 = Radiobutton(frame2, text='Event', variable = selection, value = 'oy')
radio_1.select()
radio_1.pack(side = LEFT)
radio_2.pack(side = LEFT)
radio_3.pack(side = LEFT)
frame2.pack(padx =30, pady =30)
#radius button for marker type
frame3 = Frame(pop)
visible = bool
check_1 = Checkbutton(frame3, text = 'GM Only', variable = visible, onvalue= True, offvalue= False)
check_1.pack(side = LEFT)
frame3.pack(padx =30, pady =30)
#string for user input
frame4 = Frame(pop)
entry4 = Entry(frame4)
entry4.pack(side = LEFT)
frame4.pack( padx =20, pady =20)
def infoPass():
#info1 = {'title': entry.get(), 'type': selection.get(), 'vis': visible, 'Desc': entry4.get()}
#info.update(info1)
#print info
pop.destroy()
#buttons
label = Label(pop, text="", height=0, width=100)
label.pack()
b = Button(pop, text="Cancel", width=20, command= pop.destroy )
b.pack(side='bottom',padx=5,pady=5)
b2 = Button(pop, text="Save", width=20, command= infoPass )
b2.pack(side='bottom',padx=5,pady=5)
info = {'title': entry.get(), 'type': selection.get(), 'vis': visible, 'desc': entry4.get()}
pop.mainloop()
return info
If i underdstood your question right, then try to add your own loop.
Remove pop.mainloop()
Make the code be a class for a cleaner code
class userinput:
def __init__(self):
#open your window here and style it etc. and:
self.data_sent = False
def infopass(self):
self.data_sent = True
#your infopass code here and
Create your own loop at the end of init:
def __init__(self):
#...
while self.data_sent == False:
root.update()
while data_sent == False:
pop.update()
Call your popup by
mypopup = userinput()
Good luck ;)
I am a beginner programmer. I have a task to make a GUI with a linear equation y=mx+b and a set of parameters where I can change the m and b values. I have both matplotlib and numpy. I also have tkinter for the GUI. This is what i have so far i edited my friends code on a coordinate GUI.
def onButtonValChange():
if X1.get() != '':
x[0] = float(X1.get())
if Y1.get() != '':
y[0] = float(Y1.get()
def createGraph(x,y):
graphRoot = Tk.Tk()
graphRoot.wm_title("Your Graph")
graphRoot.resizable(0,0)
f = Figure(figsize=(5, 4), dpi=100)
a = f.add_subplot(111)
a.plot(x, y)
canvas = FigureCanvasTkAgg(f, master=graphRoot)
canvas.show()
canvas.get_tk_widget().pack(side=Tk.TOP, fill=Tk.BOTH, expand=1)
x = [1]
y = [1]
ButtonChangeValues = Tk.Button(root, text="Submit Change", command=onButtonValChange)
ButtonChangeValues.grid(row=11, columnspan=3)
ButtonCreateGraph = Tk.Button(root, text="Create This Graph", command=lambda: createGraph(x, y))
ButtonCreateGraph.grid(row="15", columnspan=3)
Tk.mainloop()
So here is some code that i use its a moving line graph but you could adapt the code to move only when you change the equation. all you would have to do is populate the lists of x0Coords y0Coords and xy0Coords with the right mx+b formula
# Run from IDLE or LXTerminal not IDLE 3
# for import spidev to work, must run as python (v2) not python3
from Tkinter import * #to run on python 2, use Tkinter, for python3 use tkinter
import math
from datetime import datetime, timedelta
import numpy as np
import spidev
#--------------------- variables -------------------------
#---user defined settings
screenWidth = 450
resolution = 5 #number of pixels between data points, for visual purposes only
samplePeriod = 100 #milliseconds, time between data points written to txt file
timeRange = .5 #minutes
#---end user settings
baseTime = int(timeRange*60*1000/screenWidth)
startTime = datetime.now()
nl = "\n"
root = Tk()
root.title("Simple GUI")
root.geometry("500x300") #widthxheight
C = Canvas(root, bg = "gray", height = 250, width = screenWidth)
x0Coords = []
y0Coords = []
xy0Coords = []
coordLength = int(screenWidth/resolution)
#---initiation of lists
for i in range(0,coordLength):
x0Coords.append(i*resolution)
y0Coords.append(125)
xy0Coords.append(0)
xy0Coords.append(0)
#putting X and Y corrdinites in a list
def coordinate():
global x0Coords, y0Coords, xy0Coords
for i in range(0,coordLength*2,2):
xy0Coords[i] = x0Coords[i/2]
xy0Coords[i+1] = y0Coords[i/2]
#print(xy0Coords)
#---End initiation of lists
c0 = C.create_rectangle(0,0,20,50)
cl0 = C.create_line(xy0Coords)
pressure = Label(root, text="test")
pressure.pack()
spi_0 = spidev.SpiDev()
spi_0.open(0, 0)
#--------------------------- End of Variables -------------------------
#--------------------------- Definitions ------------------------------
#shifts y values down in index in array to represent time moved forward
def shiftCoords(nextValue):
global y0Coords, xy0Coords
y0Coords.pop(0)
y0Coords.append(nextValue)
coordinate()
#updates the GUI based on the new time
def move_time():
global c0,cl0,xy0Coords, resolution, baseTime
C.delete(c0)
C.delete(cl0)
c0 = C.create_rectangle(0,0,20,int(float(readadc_0(0))/1023*250))
shiftCoords(125-int(float(readadc_0(0))/1023*125))
cl0 = C.create_line(xy0Coords)
#print(float(readadc_0(0))/1023*250)
root.title("V= " + str(round(3.3*float(readadc_0(0))/1023,2)))
root.after(baseTime*resolution,move_time)
C.pack()
root.after(baseTime,move_time)
root.after(samplePeriod,writeData)
root.mainloop()
In this program i want the time to continue on each button even if another is clicked, yet, time seems to stop on a button when another is click i any suggestions here?
from Tkinter import *
import os
import time
class Application(Frame):
##########################################################################
def my_timeDrag(self): # creates a timer starting at 5 min , counts down to 0 then repeats
min = 5
sec = 59
while sec <=60:
self.Button3.configure(text="{}:{}".format(min,sec))
self.Button3.update()
os.system('cls')
print min, "Minutes", sec, "Seconds"
time.sleep(1)
sec -= 1
if sec == 0:
min -= 1
sec = 59
elif min == 0:
min = 5
##########################################################################################
def my_timeBB(self): # creates a timer starting at 5 min , counts down to 0 then repeats
min = 4
sec = 59
while sec <=60:
self.Button1.configure(text="{}:{}".format(min,sec))
self.Button1.update()
os.system('cls')
print min, "Minutes", sec, "Seconds"
time.sleep(1)
sec -= 1
if sec == 0:
min -= 1
sec = 59
elif min == 0:
min = 4
#######################################################
def my_timeRB(self): # creates a timer starting at 5 min , counts down to 0 then repeats
min = 4
sec = 59
while sec <=60:
self.Button2.configure(text="{}:{}".format(min,sec))
self.Button2.update()
os.system('cls')
print min, "Minutes", sec, "Seconds"
time.sleep(1)
sec -= 1
if sec == 0:
min -= 1
sec = 59
elif min == 0:
min = 4
########################################################
def createButtons(self): # creats a button
self.Button1 = Button(self)
self.Button1["text"] = "Blue Buff"
self.Button1["fg"] = "Blue"
self.Button1["command"] = self.my_timeBB # suppose to implement countdown in button text when click.
self.Button1.pack({"side": "left"})
self.Button2 = Button(self)
self.Button2["text"] = "Red Buff"
self.Button2["fg"] = "Red"
self.Button2["command"] = self.my_timeRB
self.Button2.pack({"side":"right"})
self.Button2.pack(padx=50)
self.Button3 = Button(self)
self.Button3["text"] = " Dragon "
self.Button3["fg"] = "Pink"
self.Button3["bg"] = "Purple"
self.Button3["command"] = self.my_timeDrag
self.Button3.pack(side="bottom",pady=50)
self.Quit = Button(self)
self.Quit["text"] = "Quit"
self.Quit["command"] = self.quit
self.Quit.pack()
##############################################################
##############################################################
def __init__(self, master=None):
Frame.__init__(self, master) # initializes window
self.pack()
self.createButtons()
root = Tk()
root.title("Jungle Timer by BabyAchilles")
root.geometry("400x300")
app = Application(master=root)
root.mainloop()
Your problem is that Button from tkinter just only implement the command function whenever the user clicks on that button. Therefore, when the user clicks on another button, that command function will stop/terminate and change to the clicked button command function. That's the main reason why your timer stops!
There are two solutions for this problem:
The easiest way is to store your timer (such as Button1 minutes, secs, Button2 minutes, secs,...) as attributes and to use tkinter Label to display the timer for each of them on the interface instead of dealing your problem about the Button since the command function will always stop and change to another one whenever the user clicks on the buttons.
Another way to solve this problem is to use the .invoke() method in the Button widget to call back the command functions from previous clicked buttons. If you want to use this way, you can look up on this link about how this method works: http://infohost.nmt.edu/tcc/help/pubs/tkinter/web/button.html
P/S: I love League of Legends, too!
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Here is my code demo for the timer, so check it out! I used .after() method for the root window. Also, I stored all my time data as an object attribute, so it's easier to access!
import tkinter
import time
DEFAULT_FONT = ('Helvetica',30)
class LoL_JungleTimer():
def __init__(self):
self._root_window = tkinter.Tk()
Dragon_button = tkinter.Button(master = self._root_window, text = 'Dragon', fg = 'purple', command = self._dragon_start)
BlueBuff_button = tkinter.Button(master = self._root_window, text = 'Blue Buff', fg = 'blue', command = self._blue_buff_start)
RedBuff_button = tkinter.Button(master = self._root_window, text = 'Red Buff', fg = 'red', command = self._red_buff_start)
self._blue_buff_label = tkinter.Label(master = self._root_window, text = '5:00', fg = 'blue', font = DEFAULT_FONT)
self._red_buff_label = tkinter.Label(master = self._root_window, text = '5:00', fg = 'red', font = DEFAULT_FONT)
self._dragon_label = tkinter.Label(master = self._root_window, text = '6:00', fg = 'purple', font = DEFAULT_FONT)
Dragon_button.grid(row = 0, column = 0, padx = 10, pady = 10)
BlueBuff_button.grid(row = 1, column = 0, padx = 10, pady = 10)
RedBuff_button.grid(row = 2, column = 0, padx = 10, pady = 10)
self._blue_buff_label.grid(row = 1, column = 1, padx = 10, pady = 10)
self._red_buff_label.grid(row = 2, column = 1, padx = 10, pady = 10)
self._dragon_label.grid(row = 0, column = 1, padx = 10, pady = 10)
self.drag_minute = 5
self.drag_second = 59
self.BB_minute = 4
self.BB_second = 59
self.RB_minute = 4
self.RB_second = 59
def run(self):
self._root_window.mainloop()
def _time_counter(self, minutes, seconds):
if seconds < 60:
seconds -= 1
if seconds == 0:
seconds = 59
minutes -= 1
return minutes, seconds
def _blue_buff_start(self):
self._blue_buff_label.configure(text = "{0}:{1:02d}".format(self.BB_minute,self.BB_second))
self._root_window.update()
self.BB_minute,self.BB_second = self._time_counter(self.BB_minute,self.BB_second)
self._root_window.after(1000, func = self._blue_buff_start)
def _dragon_start(self):
self._dragon_label.configure(text = "{0}:{1:02d}".format(self.drag_minute,self.drag_second))
self._root_window.update()
self.drag_minute,self.drag_second = self._time_counter(self.drag_minute,self.drag_second)
self._root_window.after(1000, func = self._dragon_start)
def _red_buff_start(self):
self._red_buff_label.configure(text = "{0}:{1:02d}".format(self.RB_minute,self.RB_second))
self._root_window.update()
self.RB_minute,self.RB_second = self._time_counter(self.RB_minute,self.RB_second)
self._root_window.after(1000, func = self._red_buff_start)
if __name__ == '__main__':
LoL_JungleTimer().run()