How to make a GUI multithread in python - python

I am doing a monitor process in python which indicate the pid, the name and the memory used by a process.
How to use multi-threads for make a gui and synchonized with the interior methods which calculate the process information
class Monitor(tk.Frame):
def __init__(self, root):
tk.Frame.__init__(self, root)
self.canvas = tk.Canvas(root, borderwidth = 0, background = "#ffffff")
self.frame = tk.Frame(self.canvas, background = "#ffffff")
self.vsb = tk.Scrollbar(root, orient = "vertical", command = self.canvas.yview)
self.canvas.configure(yscrollcommand = self.vsb.set)
self.vsb.pack(side="right", fill="y")
self.canvas.pack(side="left", fill="both", expand=True)
self.canvas.create_window((4,4), window = self.frame, anchor="nw",tags="self.frame")
self.frame.bind("<Configure>", self.onFrameConfigure)
self.tabla()
def tabla(self):
'''Put in some fake data'''
proceso = Proceso()
num_procesos = proceso.num_procesos()
tk.Label(self.frame,text = "PID",width = 8, borderwidth = 1, relief = "solid").grid(row = 0, column = 0)
tk.Label(self.frame,text = "Nombre",width = 7, borderwidth = 1, relief = "solid").grid(row = 0, column = 1)
tk.Label(self.frame,text = "Estado del proceso",width = 15, borderwidth = 1, relief = "solid").grid(row = 0, column = 2)
tk.Label(self.frame,text = "Cache",width = 7, borderwidth = 1, relief = "solid").grid(row = 0, column = 3)
tk.Label(self.frame,text = "Memoria",width = 15, borderwidth = 1, relief = "solid").grid(row = 0, column = 4)
tk.Label(self.frame,text = "Disco",width = 7, borderwidth = 1, relief = "solid").grid(row = 0, column = 5)
tk.Label(self.frame,text = "Acciones",width = 12, borderwidth = 1, relief = "solid").grid(row = 0, column = 6)
killentrada = tk.Entry(self.frame,width = 7, borderwidth = 2, relief = "solid").grid(row =1, column = 8)
killboton = tk.Button(self.frame,text = "Matar proceso", width = 10, borderwidth = 2, relief = "solid",command = proceso.kill()).grid(row = 1, column = 7)
for renglon in range(num_procesos+1):
tk.Label(self.frame, text = proceso.pid(renglon-1),borderwidth="0",relief="solid").grid(row = renglon+1, column=0)
tk.Label(self.frame, text = proceso.nombre(renglon-1)).grid(row = renglon+1, column=1)
tk.Label(self.frame, text = proceso.estado(renglon-1)).grid(row = renglon+1, column=2)
#tk.Label(self.frame, text = proceso.memoria(renglon-1)).grid(row = renglon+1, column=4)
def onFrameConfigure(self, event):
'''Reset the scroll region to encompass the inner frame'''
self.canvas.configure(scrollregion=self.canvas.bbox("all"))

Related

OOP in Tkinter - Create Frame with Listbox

Hey I would like to create a frame which contains a Listbox and some buttons. What I would like to do is to somehow pass as an argument a name of this listbox. This is my current code in which I set the name of this listbox to master.thisListbox but I would like to pass it somehow as argument. Is it possible or should I separately crate a listbox in my App and the pass it as an argument to a frame? I'm going to create a lot of such listboxes in my App hence the name of listbox shouldn't be the same. I'm pretty new in OOP.
class myApp(tk.Tk):
def __init__(self):
tk.Tk.__init__(self)
self.dateFrame = DateFrame(self)
self.dateFrame.grid(row = 0, column = 0)
print(self.day.get())
self.myFrame = ListboxFrame(self, "Label!", [1,2,3])
self.myFrame.grid(row = 1, column = 0)
x = self.thisListbox.get(0, END)
print(x)
class DateFrame(ttk.Frame):
def __init__(self, master):
ttk.Frame.__init__(self, master)
# Day
ttk.Label(self, text = "Day", width = 4).grid(row = 0, column = 0, padx = 3, pady = 3)
master.day = IntVar(master, value = 31)
self.dayCB = ttk.Combobox(self, values = [x for x in range(1, 32)], textvariable = master.day, width = 4)
self.dayCB.grid(row = 1, column = 0, padx = 3, pady = 3)
# Month
ttk.Label(self, text = "Month", width = 6).grid(row = 0, column = 1, padx = 3, pady = 3)
self.month = IntVar(master, value = 12)
self.monthCB = ttk.Combobox(self, values = [x for x in range(1, 13)], textvariable = self.month, width = 4)
self.monthCB.grid(row = 1, column = 1, padx = 3, pady = 3)
# Year
ttk.Label(self, text = "Year", width = 4).grid(row = 0, column = 2, padx = 3, pady = 3)
self.year = IntVar(master, value = 2021)
self.yearCB = ttk.Spinbox(self, from_ = 2020, to = 2100, textvariable = self.year, width = 6)
self.yearCB.grid(row = 1, column = 2, padx = 3, pady = 3)
class ListboxFrame(ttk.Frame):
def __init__(self, master, labelText, values, selectmode = "extended", height = 6, width = 30):
ttk.Frame.__init__(self, master)
# Listbox
ttk.Label(self, text = labelText).grid(row = 0, column = 0, columnspan = 3)
master.thisListbox = tk.Listbox(self, selectmode = selectmode, height = height, width = width)
master.thisListbox.grid(row = 1, column = 0, columnspan = 3, padx = 2, pady = 2)
# Entry
self.entry = ttk.Entry(self)
self.entry.grid(row = 2, column = 0, padx = 2, pady = 2)
# Buttons
self.addButton = ttk.Button(self, text = "Add", width = 4, command = self.Add)
self.addButton.grid(row = 2, column = 1, padx = 2, pady = 2)
self.deleteButton = ttk.Button(self, text = "Delete", width = 6, command = self.Delete)
self.deleteButton.grid(row = 2, column = 2, padx = 2, pady = 2)
for v in values:
master.thisListbox.insert(END, v)
def Add(self):
if self.entry.get() == "": return
master.thisListbox.insert(END, self.entry.get())
self.entry.delete(0, END)
def Delete(self):
for index in reversed(master.thisListbox.curselection()):
master.thisListbox.delete(index)
# listbox.config(height = listbox.size())

why is the layout all messed up if i expand the window, python tkinter

i want it to expand the size accordingly if the window is expanded, so far i use the grid.row/column configure to make its weight =1 but it will be all messed up it i expand the window.
import time
import tkinter as tk
#Initialise the window
clock = tk.Tk()
clock.title('Easy CLock')
clock.configure(bg='#121212')
clock.columnconfigure(0, weight = 1)
clock.rowconfigure(0, weight = 1)
border_effects = {
"flat": tk.FLAT,
"sunken": tk.SUNKEN,
"raised": tk.RAISED,
"groove": tk.GROOVE,
"ridge": tk.RIDGE,
}
#Logo will be under the main parent
logo = tk.PhotoImage(file = r'C:\Users\User\VSC\Alarm\Logo1.png')
logo_size = logo.subsample(5)
#Time and Date function
def time_date():
# current time
current_time = time.strftime('%H:%M:%S')
current_date = time.strftime(r'%m/%d/%Y')
clock.after(200, time_date)
#Displays the time
c_time = tk.Label(f_time, text = current_time, fg='white', bg='#121212', font=('Verdana', 30))
c_date = tk.Label(f_time, text = current_date, font=('Verdana', 10), fg='white', bg='#121212')
c_time.grid(column=0, row=0)
c_date.grid(column=0, row=1)
#alarm button command
def alarm_func():
#Alarm label
c_clicked = tk.Label(f_alarm, text='Alarm Interface', fg='white', bg='#121212')
c_clicked.grid(column=0, row=1, sticky = 'N')
def recall_frame(event):
if event == f_alarm:
event.grid_forget()
f_time.grid(column=0, row =1, columnspan = 4, sticky = 'N')
elif event == f_time:
event.grid_forget()
f_alarm.grid(column=0, row=1, columnspan = 4, rowspan = 2)
def back_func():
pass
#Creating Frames
f_time = tk.Frame(clock) #Clock Button
f_alarm = tk.Frame(clock) #Alarm Buttton
#configure the frames
f_time.configure(bg = '#121212')
f_alarm.configure(bg = '#121212')
#Setting label in the frame
f_lbl = tk.Label(clock, text= ' Simplistic Clock', image = logo_size, font=('Verdana', 30), fg='white', bg='#121212', compound = tk.LEFT)
time_but = tk.Button(clock, text='Clock', command= lambda :[time_date(), recall_frame(f_alarm)], bg='#f39c12', width = 15, relief = border_effects['ridge'])
alarm_but = tk.Button(clock, text = 'Alarm', command = lambda :[alarm_func(), recall_frame(f_time)], bg='#f39c12', width = 15, relief = border_effects['ridge'])
quit_but = tk.Button(clock, text='Exit', command = clock.quit, bg='#f39c12', width = 15, relief = border_effects['ridge'])
back_but = tk.Button(clock, text = 'Back To Home', command = back_func, bg='#f39c12', width = 15, relief = border_effects['ridge'])
f_lbl.config(borderwidth = 4, relief = border_effects['sunken'])
f_lbl.grid_columnconfigure(0, weight = 1)
#Putting it on the frames
f_lbl.grid(column = 0, row = 0, columnspan = 4, sticky = 'N')
time_but.grid(column = 0, row = 3)
alarm_but.grid(column = 1, row = 3)
back_but.grid(column = 2, row = 3)
quit_but.grid(column = 3, row = 3)
clock.mainloop()
also, why does the border in the f_lbl, simplistic clock not fully extended through out all 4 column since i put columnspan = 4 , and weight = 1 , should't it expand fully through all 4 columns?

Python Tkinter appl uncoloured area

So I am creating a Python Tkinter application. At the moment I am trying to set the background of the app to Python's default grey colour, but am having an issue where part of the screen isn't colouring properly.
This is what the screen currently looks like
Now I went and intentionally coloured the current frame's background blue, and the container's background red so I could try and see the area that is uncoloured. As you can see the white grey-ish area is neither part of the container or the frame, and I can't figure out how to get it's colour to change. Here is my code:
Main.py:
from Interface import Interface
#Development environent variable. Set to false when program is released to public
inDevelopment = True
#Sets up the Window
root = Interface(inDevelopment)
root['bg'] = 'red'
#Sets the Window TItle
root.title("Tester")
#Sets the Window size depending on if it is the release copy of the program
if inDevelopment:
#Sets the window size. Disabled when Fullscreen enabled
root.geometry("800x480")
if not inDevelopment:
#Sets the window to fullscreen. Disabled when screen dimensions enabled
root.attributes("-fullscreen", True)
root.mainloop()
Interface.py:
import tkinter as tk
from tkinter import ttk
from MeterGauge import Meter
TEXT_FONT = ("Arial", 11, "bold")
currentMeter = None
voltageMeter = None
class Interface(tk.Tk):
def __init__(self, inDevelopment, *args, **kwargs):
self.inDevelopment = inDevelopment
tk.Tk.__init__(self, *args, **kwargs)
container = tk.Frame(self)
container.grid(column = 0, row = 0, sticky = "nwes")
container.grid_rowconfigure(0, weight = 1)
container.grid_columnconfigure(0, weight = 1)
self.frames = { }
for F in (DefaultScreen, TestScreen):
frame = F(container, self)
self.frames[F] = frame
frame.grid(row = 0, column = 0, padx = 25, pady = 25, sticky = "nsew")
self.show_frame(DefaultScreen)
def show_frame(self, cont):
frame = self.frames[cont]
frame.tkraise()
# Screen which will be the default display
# Emulates release copy of program
class DefaultScreen(tk.Frame):
def __init__(self, parent, controller):
tk.Frame.__init__(self, parent)
self.config(background='blue')
frame_style = ttk.Style()
frame_style.configure("My.TFrame", background = "grey")
#Frame for Current Monitor
currentMeterFrame = ttk.Frame(controller, style="My.TFrame")
currentMeterFrame.place(height = 165, width = 185, x = 545, y = 25)
#Frame for Voltage Monitor
voltageMeterFrame = ttk.Frame(controller, style="My.TFrame")
voltageMeterFrame.place(height = 165, width = 185, x = 545, y = 250)
tc = TemperatureCommands()
#Label for the Controller State
lblControllerState = ttk.Label(self, text = "Controller State",
background = "grey", font = TEXT_FONT).grid(
column = 1, row = 1, columnspan = 5)
#Label for the Temperature State
lblTempState = ttk.Label(self, text = "this is test text",
background = "grey", font = TEXT_FONT)
lblTempState.grid(column = 1, row = 2, columnspan = 5)
lblTempState.config(font=("", 14, "bold"))
ttk.Label(self, width=20, background = "grey").grid(column = 1, row = 3, columnspan = 2)
#High Cool Button
btnHighCool = ttk.Button(self, text="High Cool", command = tc.HighCool).grid(
column = 1, row = 4, columnspan = 2, rowspan = 2, sticky = "nsew")
#Medium Cool Button
btnMediumCool = ttk.Button(self, text="Medium Cool", command = tc.MediumCool).grid(
column = 1, row = 6, columnspan = 2, rowspan = 2, sticky = "nsew")
#Low Cool Button
btnLowCool = ttk.Button(self, text="Low Cool", command = tc.LowCool).grid(
column = 1, row = 8, columnspan = 2, rowspan = 2, sticky="nsew")
#OFF Button
btnOff = ttk.Button(self, text = "OFF", command = tc.Off).grid(
column = 1, row = 10, columnspan = 5, rowspan = 2, sticky = "nsew")
#Driver Button (disabled for release version)
if controller.inDevelopment:
btnDriver = ttk.Button(self, text= "Driver", command = tc.Driver).grid(
column = 1, row = 12, columnspan = 2, rowspan = 2, sticky = "nsew")
#Passenger Button (disabled for release version)
if controller.inDevelopment:
btnPassenger = ttk.Button(self, text = "Passenger", command = tc.Passenger).grid(
column = 4, row = 12, columnspan = 2, rowspan = 2, sticky = "nsew")
ttk.Label(self, width = 0, background = "grey").grid(column = 3, row = 3)
ttk.Label(self, width = 20, background = "grey").grid(column = 4, row = 3, columnspan = 2)
#High Heat Button
btnHighHeat = ttk.Button(self, text="High Heat", command = tc.HighHeat).grid(
column = 4, row = 4, columnspan = 2, rowspan = 2, sticky = "nsew")
#Medium Heat Button
btnMediumHeat = ttk.Button(self, text = "Medium Heat", command = tc.MediumHeat).grid(
column = 4, row = 6, columnspan = 2, rowspan = 2, sticky= "nsew")
#Low Heat Button
btnLowHeat = ttk.Button(self, text = "Low Heat", command = tc.LowHeat).grid(
column = 4, row = 8, columnspan = 2, rowspan = 2, sticky = "nsew")
fill_Width = 5
col_Num = 6
for i in range(14):
ttk.Label(self, width = fill_Width, background = "grey").grid(column = col_Num, row = i)
row_Num = 14
col_Num = 7
n = 0
col = 6
for n in range(col):
ttk.Label(self, width = fill_Width, background = "grey").grid(column = col_Num, row = row_Num)
col_Num = col_Num + 1
#Current Readout
ttk.Label(self, text = "Current Draw", background = "grey").grid(column = 7, row = 1)
lblCurrentDraw = ttk.Label(self, text = "0.00 A", foreground = "lime", background = "black").grid(
column = 7, row = 2, sticky = "ew")
#Voltage Readout
ttk.Label(self, text = "Voltage Tester", background = "grey").grid(column = 7, row = 8)
lblVoltageDraw = ttk.Label(self, text = "0.00 VDC", foreground = "lime", background = "black").grid(
column = 7, row = 9, sticky = "ew")
#Current Meter Gauge
currentMeter = Meter(currentMeterFrame, height = 300, width = 300, background = "grey", highlightthickness = 0)
currentMeter.SetRange(0.0, 5.0)
currentMeter.place(x = 10, y = 2)
current0 = ttk.Label(currentMeterFrame, text = "0.0", background = "grey").place(
height = 18, width = 28, x = 0, y = 141)
current1 = ttk.Label(currentMeterFrame, text = "1.0", background = "grey").place(
height = 18, width = 28, x = 4, y = 100)
current2 = ttk.Label(currentMeterFrame, text = "2.0", background = "grey").place(
height = 18, width = 28, x = 21, y = 60)
current3 = ttk.Label(currentMeterFrame, text = "3.0", background = "grey").place(
height = 18, width = 28, x = 54, y = 27)
current4 = ttk.Label(currentMeterFrame, text = "4.0", background = "grey").place(
height = 18, width = 28, x = 97, y = 7)
current5 = ttk.Label(currentMeterFrame, text = "5.0", background = "grey").place(
height = 18, width = 28, x = 144, y = 1)
#Voltage Meter Gauge
voltageMeter = Meter(voltageMeterFrame, height = 300, width = 300, background = "grey", highlightthickness = 0)
voltageMeter.SetRange(0, 15)
voltageMeter.place(x = 10, y = 2)
voltage1000 = ttk.Label(voltageMeterFrame, text = "0.0", background = "grey").place(
height = 18, width = 28, x = 0, y = 141)
voltage1200 = ttk.Label(voltageMeterFrame, text = "5.0", background = "grey").place(
height = 18, width = 28, x = 21, y = 60)
voltage1300 = ttk.Label(voltageMeterFrame, text = "10.0", background = "grey").place(
height = 18, width = 28, x = 54, y = 27)
voltage1500 = ttk.Label(voltageMeterFrame, text = "15.0", background = "grey").place(
height = 18, width = 28, x = 144, y = 1)
for child in self.winfo_children(): child.grid_configure(padx = 5, pady = 5)
# Screen for testing new items before adding them to the main display
class TestScreen(tk.Frame):
def __init__(self, parent, controller):
tk.Frame.__init__(self, parent)
I don't know exactly what it is that is causing the light grey area to appear. Any help would be appreciated.

Tkinter button not working (Python 3.x)

I'm working on my final project for my computing I class.
The problem that I am having is:
When I click on the new entry button, hit the back button and click on the new entry button once again it does not work.
If you guys could tell me why that is?
The command on the button seems to be only working once. Thanks for your help.
Code:
from tkinter import *
import tkinter.filedialog
class App(Tk):
def __init__(self):
Tk.__init__(self)
self.title("Entry Sheet")
self.font = ("Helvetica","13")
self.header_font = ("Helvetica","18")
self.exercise_font = ("Helvetica","13","bold")
self.delete = 'a'
self.new_user()
def new_user(self):
if self.delete == 'b':
self.delete = 'c'
self.hide()
self.delete = 'b'
self.new_entry = Button(self, text = 'New Entry', command = self.entry, width = 15)
self.new_entry.grid(row = 1, column = 0, columnspan = 3, padx = 10, pady = 5)
self.look_entry = Button(self, text = 'See Entries', command = self.see_entries, width = 15)
self.look_entry.grid(row = 2, column =0, columnspan = 3, padx = 10, pady = 5)
def entry(self):
print(1)
self.delete = 'b'
self.hide()
self.entry = Label(self, text = 'New Entry', font = self.header_font)
self.entry.grid(row = 0, column = 0, columnspan = 2)
self.numberlbl = Label(self, text = 'Please choose a muscle?', font = self.font)
self.numberlbl.grid(row = 1, column= 0, columnspan = 2, sticky = 'w' )
self.muscle_chosen = IntVar()
self.chest = Radiobutton(self, text = "chest", variable = self.muscle_chosen, value = 1, font = self.font)
self.bicep = Radiobutton(self, text = "bicep", variable = self.muscle_chosen, value = 2, font = self.font)
self.chest.grid(row = 2, column = 0)
self.bicep.grid(row = 2, column = 1)
self.exerciseslbl = Label(self, text = 'Please enter the number of exercises: ', font = self.font)
self.exerciseslbl.grid(row = 3, column = 0, columnspan = 3)
self.exercises_spinbox = Spinbox(self, from_= 1, to_= 50, width = 5, font = self.font)
self.exercises_spinbox.grid(row = 4, column = 0)
self.back_button = Button(self, text = 'Back', command = self.new_user, width = 10)
self.back_button.grid(row =5, column=0, pady =10)
def see_entries(self):
print("Goes through")
def hide(self):
if self.delete == 'b':
self.new_entry.grid_remove()
self.look_entry.grid_remove()
elif self.delete == 'c':
self.entry.grid_remove()
self.numberlbl.grid_remove()
self.chest.grid_remove()
self.bicep.grid_remove()
self.exerciseslbl.grid_remove()
self.exercises_spinbox.grid_remove()
self.back_button.grid_remove()
def main():
app = App()
app.mainloop()
if __name__=="__main__":
main()
In your entry function you overwrite self.entry, which is the name of the function, with a reference to a Label. When the button then calls self.entry it isn't function.
Simply call the Label something else.

Iterating via loops to make multiple widgets and make the below code better

I'm pretty new to Python and have written my first ever program with a GUI and have been reading a lot about code to loop your way into creating multiple widgets but haven't seen a solution for my code below.
I have written a program that simulates a tennis match and have created a GUI for the program which consists of GUI in the form as a Livescoreboard.
For the scoreboard I have createad a lot of labels that will contain the different scores and the players names etc like a real tennis scoreboard and I've also made a few buttons.
My code below is the two methods in which I create and update all the widgets in the GUI. Looking at it, from a novice perspective, it doesn't seem to be the best way of writing this code.
Have been searching and trying to come up with something else than this but haven't found any.
Is there a way to this better or is it fine the way it is?
# Creates the widgets in the GUI.
def create_widgets(self):
# Images
photo = tk.PhotoImage(file = 'Federer.gif')
label = tk.Label(self, image = photo)
label.image = photo
label.place(relwidth = 1, relheight = 1)
img = tk.PhotoImage(file = 'Rolex.gif')
rolex_label = tk.Label(self, image = img)
rolex_label.image = img
rolex_label.grid(row = 0, column = 3, columnspan = 2)
# Creates and sets some StringVar()
self.set_1_player_1 = tk.StringVar()
self.set_1_player_2 = tk.StringVar()
self.set_2_player_1 = tk.StringVar()
self.set_2_player_2 = tk.StringVar()
self.set_3_player_1 = tk.StringVar()
self.set_3_player_2 = tk.StringVar()
self.spelare_1 = tk.StringVar()
self.spelare_2 = tk.StringVar()
self.sets_player_1 = tk.StringVar()
self.sets_player_2 = tk.StringVar()
self.games_player_1 = tk.StringVar()
self.games_player_2 = tk.StringVar()
self.points_player_1 = tk.StringVar()
self.points_player_2 = tk.StringVar()
self.show_score_by = tk.StringVar()
self.spelare_1.set(self.prepared_match.get_player_1().get_name())
self.spelare_2.set(self.prepared_match.get_player_2().get_name())
self.sets_player_1.set('0')
self.sets_player_2.set('0')
self.games_player_1.set('0')
self.games_player_2.set('0')
self.points_player_1.set('0')
self.points_player_2.set('0')
self.show_score_by.set(None)
# The labels
tk.Label(self, font = "Purisa 8 bold", text = 'Set 1', height = 2, width = 6, relief = tk.RAISED).grid(row = 0, column = 0)
tk.Label(self, font = "Purisa 8 bold", text = 'Set 2', height = 2, width = 6, relief = tk.RAISED).grid(row = 0, column = 1)
tk.Label(self, font = "Purisa 8 bold", text = 'Set 3', height = 2, width = 6, relief = tk.RAISED).grid(row = 0, column = 2)
tk.Label(self, font = "Purisa 8 bold", text = 'SETS', height = 2, width = 6, relief = tk.RAISED).grid(row = 0, column = 5)
tk.Label(self, font = "Purisa 8 bold", text = 'GAMES', height = 2, width = 6, relief = tk.RAISED).grid(row = 0, column = 6)
tk.Label(self, font = "Purisa 8 bold", text = 'POINTS', height = 2, width = 15, relief = tk.RAISED).grid(row = 0, column = 7)
tk.Label(self, textvariable = self.set_1_player_1, height = 2, width = 6, relief = tk.RAISED).grid(row = 1, column = 0)
tk.Label(self, textvariable = self.set_2_player_1, height = 2, width = 6, relief = tk.RAISED).grid(row = 1, column = 1)
tk.Label(self, textvariable = self.set_3_player_1, height = 2, width = 6, relief = tk.RAISED).grid(row = 1, column = 2)
self.name_player_1 = tk.Label(self, textvariable = self.spelare_1, height = 2, width = 18, relief = tk.RAISED)
self.name_player_1.grid(row = 1, column = 3, columnspan = 2)
tk.Label(self, textvariable = self.sets_player_1, height = 2, width = 6, relief = tk.RAISED).grid(row = 1, column = 5)
tk.Label(self, textvariable = self.games_player_1, height = 2, width = 6, relief = tk.RAISED).grid(row = 1, column = 6)
tk.Label(self, textvariable = self.points_player_1, height = 2, width = 15, relief = tk.RAISED).grid(row = 1, column = 7)
tk.Label(self, textvariable = self.set_1_player_2, height = 2, width = 6, relief = tk.RAISED).grid(row = 2, column = 0)
tk.Label(self, textvariable = self.set_2_player_2, height = 2, width = 6, relief = tk.RAISED).grid(row = 2, column = 1)
tk.Label(self, textvariable = self.set_3_player_2, height = 2, width = 6, relief = tk.RAISED).grid(row = 2, column = 2)
self.name_player_2 = tk.Label(self, textvariable = self.spelare_2, height = 2, width = 18, relief = tk.RAISED)
self.name_player_2.grid(row = 2, column = 3, columnspan = 2)
tk.Label(self, textvariable = self.sets_player_2, height = 2, width = 6, relief = tk.RAISED).grid(row = 2, column = 5)
tk.Label(self, textvariable = self.games_player_2, height = 2, width = 6, relief = tk.RAISED).grid(row = 2, column = 6)
tk.Label(self, textvariable = self.points_player_2, height = 2, width = 15, relief = tk.RAISED).grid(row = 2, column = 7)
tk.Label(self, font = "Purisa 8 bold", text = 'Show score by: ', height = 2, width = 15).grid(row = 0, column = 8, padx = 50)
# The buttons
self.play_button = tk.Button(self, bd = 5, text = 'Play', command = self.play, height = 2, width = 10, relief = tk.RIDGE)
self.play_button.grid(pady = 10, row = 3, column = 3, columnspan = 2)
self.quit_button = tk.Button(self, bd = 3, text = 'Quit', command = self.quit, height = 1, width = 5, relief = tk.RIDGE)
self.quit_button.grid(row = 5, column = 3, columnspan = 2, pady = 5)
self.restart_button = tk.Button(self, bd = 4, text = 'Restart', command = self.restart, height = 1, width = 7, relief = tk.RIDGE)
self.restart_button.grid(row = 4, column = 3, columnspan = 2, pady = 5)
self.pause_button = tk.Button(self, text = 'Pause', command = self.pause, height = 1, width = 5, relief = tk.RIDGE)
self.pause_button.grid(row = 3, column = 8, sticky = tk.S)
tk.Radiobutton(self, command = self.show_score, text = 'Point', variable = self.show_score_by, value = 'Point', height = 1, width = 10).grid(row = 1, column = 8, padx = 50, sticky = tk.S)
tk.Radiobutton(self, command = self.show_score, text = 'Game', variable = self.show_score_by, value = 'Game', height = 1, width = 10).grid(row = 2, column = 8, padx = 50)
tk.Radiobutton(self, command = self.show_score, text = 'Set', variable = self.show_score_by, value = 'Set', height = 1, width = 10).grid(row = 3, column = 8, padx = 50, sticky = tk.N)
# Updates the widgets in the frame.
def update_widgets(self):
self.sets_player_1.set(self.prepared_match.get_sets()[0])
self.sets_player_2.set(self.prepared_match.get_sets()[1])
if self.prepared_match.show_score_by in ['Point', 'Game', None]:
self.games_player_1.set(self.prepared_match.get_games()[0])
self.games_player_2.set(self.prepared_match.get_games()[1])
if self.prepared_match.show_score_by == 'Point':
self.points_player_1.set(self.prepared_match.get_real_score()[0])
self.points_player_2.set(self.prepared_match.get_real_score()[1])
elif self.prepared_match.show_score_by == 'Game':
self.points_player_1.set('0')
self.points_player_2.set('0')
elif self.prepared_match.show_score_by == 'Set':
self.points_player_1.set('0')
self.points_player_2.set('0')
self.games_player_1.set('0')
self.games_player_2.set('0')
self.set_1_player_1.set(self.prepared_match.get_previous_sets()[0][0])
self.set_1_player_2.set(self.prepared_match.get_previous_sets()[0][1])
self.set_2_player_1.set(self.prepared_match.get_previous_sets()[1][0])
self.set_2_player_2.set(self.prepared_match.get_previous_sets()[1][1])
self.set_3_player_1.set(self.prepared_match.get_previous_sets()[2][0])
self.set_3_player_2.set(self.prepared_match.get_previous_sets()[2][1])
if self.prepared_match.match_is_ended():
if self.prepared_match.get_sets()[0] == 2:
self.name_player_1.config(fg = 'red')
else:
self.name_player_2.config(fg = 'red')
self.update()
You can make use of setattr (and as you made a class, the __ setattr __ method). You can refactor a lot of your code but you'll find hereunder optimizations your initialization code :
You can create a method like :
def create_scoreboard(self, n_players, n_sets):
""" Create attributes set_X_player_Y """
for player in range(1, n_players+1):
for set in range(1, n_sets+1):
self.__setattr__(
"set_%d_player_%d" % (set, player),
tk.StringVar()
)
for attribute in ['sets', 'games', 'points']:
self.__setattr__(
"%s_player_%d" % (attribute, player),
tk.StringVar(value='0')
)
Then you can loop over players, sets, etc.
However, the best approach would be to create player objects to store their scores. You can try to isolate objects using a "natural" approach and creating a scoreboard object, players, gamepads (for your buttons), etc.

Categories

Resources