tkinter NavigationToolbar2Tk with matplotlib disappears - python

Good afternoon,
I've been trying for two days to solve this problem and desperate, I am looking for your help. I want to show a plot (using matplotlib) within my tkinter application (not opening it in a different window) and the problem is that when I press any of the toolbar buttons as soon as I cross with the mouse coursor the lines of the plot, the plot disappears for a brief moment and appears again, but the toolbar buttons disappear until I cross them again with the mouse coursor. So for the button to appear back I should cross it and cross out off the button.
I noticed that if I change the background image (just the color, placed in label) the disappeared buttons are replaced with that color, so it seems that when I cross the lines of the plot everything in the Label except the plot is overlayed by the background.
Regards,
Wladyslaw
The code is:
import tkinter as tk
from tkinter.ttk import *
from tkinter import *
import tkinter.font as tkFont
from tkinter import scrolledtext
import logging
from PIL import Image, ImageTk
import matplotlib
matplotlib.use("TkAgg")
from matplotlib.backends.backend_tkagg import (FigureCanvasTkAgg, NavigationToolbar2Tk)
# Implement the default Matplotlib key bindings.
from matplotlib.backend_bases import key_press_handler
from matplotlib.figure import Figure
import numpy as np
from matplotlib.figure import Figure
import numpy as np
import sys
if sys.version_info[0] < 3:
import Tkinter as tk
else:
import tkinter as tk
from matplotlib.backends import _backend_tk
from matplotlib.backends.backend_agg import FigureCanvasAgg
class WidgetLogger(logging.Handler):
def __init__(self, widget):
logging.Handler.__init__(self)
self.setLevel(logging.INFO)
self.widget = widget
self.widget.config(state='disabled')
def emit(self, record):
self.widget.config(state='normal')
# Append message (record) to the widget
self.widget.insert(tk.END, self.format(record) + '\n')
self.widget.see(tk.END) # Scroll to the bottom
self.widget.config(state='disabled')
class Product:
def __init__(self, window):
self.wind = window
self.wind.geometry("1060x700")
self.wind.title('Artificial intelligence based pricer')
self.wind.lift()
#self.wind.resizable(width=False, height=False)
background_color = '#526b70'
background_color2 = '#e4e8eb'
background_color3 = '#e4e8eb'
background_color4 = '#c4cfd2'
text_color = 'white'
style = ttk.Style()
style.configure("TProgressbar", background=background_color)
img = Image.open('Files/Images/background_image.jpg')
img = ImageTk.PhotoImage(img)
background = tk.Label(self.wind, image=img, bd=0)
background.grid(row = 0, column = 0, rowspan = 8, columnspan = 5)
background.image = img
img2 = Image.open('Files/Images/background_image2.jpg')
img2 = ImageTk.PhotoImage(img2)
background2 = tk.Label(self.wind, image=img2, bd=0)
background2.grid(row = 9, column = 0, rowspan = 10, columnspan = 10)
background2.image = img2
########## LEFT TOP SIDE ##############################
fontStyleTitle = tkFont.Font(family="Times New Roman (Times)", size=12, weight='bold')
fontStyleText = tkFont.Font(family="Arial", size=10, weight='bold')
Label1 = Label(background, text = ' ')
Label1.grid(row = 0, column = 0)
Label1.configure(background=background_color)
Label2 = Label(background, text = 'GLOBAL CONFIGURATION', fg=text_color, font=fontStyleTitle)
Label2.grid(row = 1, column = 1, padx = 3, columnspan = 2, sticky = W)
Label2.configure(background=background_color)
Label3 = Label(background, text = 'Shop ID: ', fg=text_color, font=fontStyleText)
Label3.grid(row = 2, column = 1, pady = 4, sticky = W)
Label3.configure(background=background_color)
self.shop = Entry(background)
self.shop.focus()
self.shop.grid(row = 2, column = 2)
self.shop.configure(background=background_color3)
Label4 = Label(background, text = 'Item ID: ', fg=text_color, font=fontStyleText)
Label4.grid(row = 3, column = 1, sticky = W)
Label4.configure(background=background_color)
self.item = Entry(background)
self.item.grid(row = 3, column = 2)
self.item.configure(background=background_color3)
Label5 = Label(background, text = '')
Label5.grid(row = 4, column = 1)
Label5.configure(background=background_color)
Label6 = Label(background, text = 'ANN CONFIGURATION', font = fontStyleTitle, fg=text_color)
Label6.grid(row = 5, column = 1, padx = 3, columnspan = 2, sticky = W)
Label6.configure(background=background_color)
Label7 = Label(background, text = 'Model: ', fg=text_color, font=fontStyleText)
Label7.grid(row = 6, column = 1, pady = 4, sticky = W)
Label7.configure(background=background_color)
self.model = Entry(background)
self.model.grid(row = 6, column = 2)
self.model.configure(background=background_color3)
Label8 = Label(background, text = 'Test set: ', fg=text_color, font=fontStyleText)
Label8.grid(row = 7, column = 1, sticky = W)
Label8.configure(background=background_color)
self.test_set = Entry(background)
self.test_set.grid(row = 7, column = 2)
self.test_set.configure(background=background_color3)
Button1 = tk.Button(background, bg=background_color2, text = 'Calculate performance')
Button1.grid(row = 8, column = 1, padx = 50, pady = 10, columnspan = 2, sticky = W+E)
#Button1.configure(background=background_color)
########## CENTER TOP SIDE ############################
Label9 = Label(background, text = 'ANN MODEL PERFORMANCE', font=fontStyleTitle, fg=text_color)
Label9.grid(row = 1, column = 3, padx = 40, sticky = W)
Label9.configure(background=background_color)
performace = Text(background, height=8, width=50)
performace.grid(row = 2, column = 3, padx = 40, rowspan = 6)
temporalText = '''MSE of standarized mean predictions: 700,5496
MSE of standarized ANN predictions: 700,5496
MSE of deseasonalized mean predictions: 700,5496
MSE of deseasonalized ANN predictions: 700,5496
MSE of seasonalized mean predictions: 700,5496
MSE of seasonalized ANN predictions: 700,5496'''
performace.insert(tk.END, temporalText)
performace.configure(background=background_color3)
Widget_Logger = WidgetLogger(performace)
progress = Progressbar(background, style='TProgressbar', orient = HORIZONTAL, length = 100, mode = 'determinate')
progress.grid(row = 8, column = 3, padx = 40, sticky = W+E)
#progress.configure(background=background_color)
########## RIGHT TOP SIDE #############################
Label10 = Label(background, text = ' ')
Label10.grid(row = 0, column = 6)
Label10.configure(background=background_color)
Label11 = Label(background, text = "PREDICTION'S CONFIGURATION", font=fontStyleTitle, fg=text_color)
Label11.grid(row = 1, column = 4, padx = 3, columnspan = 2, sticky = W)
Label11.configure(background=background_color)
Label12 = Label(background, text = 'Precision: ', fg=text_color, font=fontStyleText)
Label12.grid(row = 2, column = 4, pady = 4, sticky = W)
Label12.configure(background=background_color)
self.precision = Entry(background)
self.precision.focus()
self.precision.grid(row = 2, column = 5)
self.precision.configure(background=background_color3)
Label13 = Label(background, text = 'Max. price multiplicator: ', fg=text_color, font=fontStyleText)
Label13.grid(row = 3, column = 4, sticky = W)
Label13.configure(background=background_color)
self.max_price_multiplicator = Entry(background)
self.max_price_multiplicator.grid(row = 3, column = 5)
self.max_price_multiplicator.configure(background=background_color3)
Label14 = Label(background, text = 'Delta multiplicator: ', fg=text_color, font=fontStyleText)
Label14.grid(row = 4, column = 4, pady = 4, sticky = W)
Label14.configure(background=background_color)
self.delta_multiplicator = Entry(background)
self.delta_multiplicator.grid(row = 4, column = 5)
self.delta_multiplicator.configure(background=background_color3)
Label15 = Label(background, text = 'Item cost: ', fg=text_color, font=fontStyleText)
Label15.grid(row = 5, column = 4, sticky = W)
Label15.configure(background=background_color)
self.item_cost = Entry(background)
self.item_cost.grid(row = 5, column = 5)
self.item_cost.configure(background=background_color3)
Radiobutton(background, text = "absolute", variable = (background,"1"), value = "1", indicator = 0, background = "light blue", activebackground=background_color2, activeforeground='black').grid(row = 6, column = 4, sticky = E)
Radiobutton(background, text = "mean price multiplicator", variable = (background,"1"), value = "2", indicator = 0, background = "light blue", activebackground=background_color2, activeforeground='black').grid(row = 6, column = 5, pady = 4, sticky = W)
Label16 = Label(background, text = 'Fixed costs: ', fg=text_color, font=fontStyleText)
Label16.grid(row = 7, column = 4, sticky = W)
Label16.configure(background=background_color)
self.fixed_costs = Entry(background)
self.fixed_costs.grid(row = 7, column = 5)
self.fixed_costs.configure(background=background_color3)
Button2 = tk.Button(background, bg=background_color2, text = 'Calculate predictions')
Button2.grid(row = 8, column = 4, padx = 80, pady = 10, columnspan = 2, sticky = W+E)
Label17 = Label(background, text = ' ')
Label17.grid(row = 0, column = 6, sticky = W)
Label17.configure(background=background_color)
########## LEFT BOTTOM SIDE ###########################
Label18 = Label(background, text = ' ')
Label18.grid(row = 9, column = 1)
Label18.configure(background=background_color)
fig = Figure(figsize=(6, 4), dpi=100)
t = np.arange(0, 3, .01)
fig.add_subplot(111).plot(t, 2 * np.sin(2 * np.pi * t))
canvas = FigureCanvasTkAgg(fig, master=background2)
canvas.draw()
canvas.get_tk_widget().pack(side=TOP, fill=BOTH, expand=1)
toolbarFrame = Frame(master=background2)
toolbarFrame.pack(side=TOP, fill=BOTH, expand=1)
toolbar = NavigationToolbar2Tk(canvas, toolbarFrame)
toolbar.update()
canvas.mpl_connect("key_press_event", on_key_press)
def on_key_press(event):
print("you pressed {}".format(event.key))
key_press_handler(event, canvas, toolbar)
if __name__ == '__main__':
window = Tk()
application = Product(window)
window.mainloop()```

Related

Tkinter Get Value and then Destroy

I'm trying to create an app that has 2 windows. The first window (A) is only called the first time the app is ran, and then opens window (B). For all future events, only window (B) is called. This is the following code:
# Script Counter/Setup
def read_counter():
if path.exists("counter.json"):
return loads(open("counter.json", "r").read()) + 1
else:
info = tk.Tk()
info.title("Setup")
info.geometry("350x120")
info.grid_columnconfigure((0, 2), weight = 1)
count = tk.Label(info, text = "Previous Post Number")
string = tk.StringVar()
count_input = tk.Entry(info, textvariable = string)
val = string.get()
def destroy_get():
val = int(count_input.get())
info.quit()
return val
count_button = tk.Button(info, text = "Done!", command = destroy_get)
tk.Label(info, text = "Setup", font='Helvetica 18 bold').grid(row = 0, column = 1, padx = 5, pady = 5)
count.grid(row = 1, column = 0, padx = 5, pady = 5)
count_input.grid(row = 1, column = 2, padx = 5, pady = 5)
count_button.grid(row = 2, column = 1, padx = 5, pady = 5)
info.mainloop()
# info.destroy()
return destroy_get()
def write_counter():
with open("counter.json", "w") as f:
f.write(dumps(counter))
counter = read_counter()
atexit.register(write_counter)
folders = ["to_post/", "not_posted/", "posted"]
for folder in folders:
if not path.exists(folder):
os.mkdir(folder)
print(os.getcwd())
# GUI
window = tk.Tk()
window.title("Confessions Bot")
window.geometry("600x350")
window.grid_columnconfigure((0,2), weight = 1)
label_tell_account = tk.Label(window, text = "Tellonym Account")
label_tell_password = tk.Label(window, text = "Tellonym Password")
label_ig_account = tk.Label(window, text = "Instagram Account")
label_ig_password = tk.Label(window, text = "Instagram Password")
tell_account = tk.Entry(window)
tell_password = tk.Entry(window)
ig_account = tk.Entry(window)
ig_password = tk.Entry(window)
image = ImageTk.PhotoImage(Image.open("logo.png"))
tk.Label(window, image = image).grid(row = 0, column = 1, padx = 10, pady = 10)
label_tell_account.grid(row = 1, column = 0)
tell_account.grid(row = 1, column = 2, padx = 10, pady = 10)
label_tell_password.grid(row = 2, column = 0, padx = 10, pady = 10)
tell_password.grid(row = 2, column = 2, padx = 10, pady = 10)
label_ig_account.grid(row = 3, column = 0, padx = 10, pady = 10)
ig_account.grid(row = 3, column = 2, padx = 10, pady = 10)
label_ig_password.grid(row = 4, column = 0, padx = 10, pady = 10)
ig_password.grid(row = 4, column = 2, padx = 10, pady = 10)
# run.grid(row = 5, column = 1, padx = 10, pady = 10)
window.mainloop()
When this is ran I get _tkinter.TclError: image "pyimage1" doesn't exist. I read that this happens since I haven't destroyed my initial window. If I change destroy_get() to have info.destroy() I'm no longer able to get the the entry from window A.
This is my first time using Tkinter and coding in general so any help is welcome.

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?

Upload image in tkinter grid

Trying to split my parent window in several functional parts, one of which will be dealing with weather
data and etc and another one will be located in the right side and contain the map image, preferably extending at full height. The image doesn't want to come up though.. Please help
import pyowm
from tkinter import *
import tkinter.messagebox
from PIL import Image, ImageTk
owm = pyowm.OWM('....') # You MUST provide a valid API key
class MyWindow(tkinter.Frame):
def __init__(self, win):
super(MyWindow, self).__init__()
self.lbl=Label(win, text="Weather info", fg='black', font=("Helvetica", 11))
self.lbl1=Label(win, text='Wind speed')
self.lbl2=Label(win, text='Wind direction')
self.lbl.grid(row = 0, column = 0, sticky = W, pady = 2)
self.lbl1.grid(row = 1, column = 0, sticky = W, pady = 2)
self.lbl2.grid(row = 2, column = 0, sticky = W, pady = 2)
# widgets for destination and weather output
self.e1=Entry()
self.e2=Entry()
self.e3=Entry(bd=3)
# this will arrange entry widgets
self.e1.grid(row = 0, column = 1, pady = 2)
self.e2.grid(row = 1, column = 1, pady = 2)
self.e3.grid(row = 2, column = 1, pady = 2)
self.btn1 = Button(win, text='Get weather', command=self.getWeather)
self.btn1.grid(row = 3, column = 1, pady = 2)
self.btn1.bind('<Button-1>', self.getWeather)
img = Image.open(r"/User/.../pic.png")
photo = ImageTk.PhotoImage(img)
# setting image with the help of label
self.imgLBL = Label(self, image = photo)
self.imgLBL.grid(row = 0, column = 2, columnspan = 2, rowspan = 2, padx = 5, pady = 5)
self.imgLBL.image = photo
#### Get weather function, etc...###
window=Tk()
mywin=MyWindow(window)
window.title('name')
window.geometry("2732x2048")
window.configure(bg='grey')
window.mainloop()
Replace last few lines with this:
self.photo = ImageTk.PhotoImage(Image.open(r"/User/.../pic.png"))
# setting image with the help of label
self.imgLBL = Label(window, image=self.photo)
self.imgLBL.grid(row = 0, column = 2, columnspan = 2, rowspan = 2, padx = 5, pady = 5)
self.imgLBL.image = self.photo

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.

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