Updating Label Variable With Button [duplicate] - python

This question already has answers here:
Update Tkinter Label from variable
(3 answers)
Closed 2 years ago.
I am creating a program for scorekeeping basketball. I have a few different files with classes and what not. My main problem is trying to update the points of each players.
For example:
I have a button set up on the screen;
pointsButton = Button(root, text='1PT', command=addPoint)
pointsButton.grid(row=0, column=1)
And a label next to that, that calls the points of a specific player (supposedly).
plabel = Label(root, text=(str(p.points)), relief='groove', bg='#41B6E6', fg = '#DB3EB1', padx=numX, pady=numY)
plabel.grid(row=rowNumber, column=4)
Here's the code from my player class that is probably needed to understand my problem.
class BasketballPlayer:
#Constructor
def __init__(self , preName, lastName, jerseyNumber):
self.preName = preName
self.lastName = lastName
self.jerseyNumber = jerseyNumber
self.points = 0
self.assists = 0
self.rebounds = 0
self.steals = 0
self.blocks = 0
self.fouls = 0
self.threePointers = 0
self.careerHighPoints = 0
self.careerHighAssists = 0
self.careerHighRebounds = 0
self.careerHighSteals = 0
self.careerHighBlocks = 0
self.careerHighThreePointers = 0
And a couple functions from the class:
def addPoints(self, p):
self.points += p
def incrementOnePoint(self):
self.points += 1
def getPoints(self):
return self.points
Here's a couple functions I've tried.
def addPoint():
p.incrementOnePoint()
plabel.config(text=p.points)
Or:
def addPoint():
p.addPoints(1)
plabel.config(text=p.points)
I really thought it would just automatically update because I'm adding a integer to a variable, but it's not updating at all.
Here is a minimal reproducible example as requested in the comments.
from tkinter import *
root = Tk()
class bballPlayer:
def __init__(self):
self.points = 0
def incrementOnePoint(self):
self.points += 1
def getPoints(self):
return self.points
def addOnePoint():
p.incrementOnePoint
global pointslabel
pointslabel.config(text=str(p.points))
p = bballPlayer()
pointslabel = Label(root, text=str(p.points))
pointslabel.grid(row=0, column=1)
btn = Button(root, text='Add Point', command=addOnePoint)
btn.grid(row=0, column=0)
root.mainloop()

Ahhh, now I see the problem, your code isn't calling the incrementOnePoint() method (only referencing its name).
def addOnePoint():
p.incrementOnePoint() # ADD MISSING PARENTHESES TO END.
global pointslabel # NOT STRICTLY NECESSARY BTW.
pointslabel.config(text=str(p.points))

Related

Counter always reseting

I have been trying to make a Python script that counts how many people are coming and going from your store.
How it is supposed to work:
you have a +1, and a -1 buttons;
when someone comes in, you click +1, and when someone goes away, you do -1.
What is wrong: when I click +1 it changes the counter from 0 to 1, but if I click it again, it doesn't change to 2.
The same thing happens when I do -1.
Here is the code:
import tkinter as tk
import customtkinter as ctk
app = ctk.CTk()
app.title('People Counter')
app.geometry('300x180')
ctk.set_appearance_mode("System")
ctk.set_default_color_theme("blue")
Label = ctk.CTkLabel
StringVar = ctk.StringVar
counter = 0
l1 = tk.Label(app, text=counter)
def pl1():
l1.config(text=counter + 1)
def mi1():
l1.config(text=counter - 1)
p1 = ctk.CTkButton(master=app,text = '+1', command=pl1, height=5 , width=30)
p1.place(relx=0.3, rely=0.5, anchor=tk.CENTER)
m1 = ctk.CTkButton(master=app, text="-1", command=mi1, height=5 , width=30)
m1.place(relx=0.7, rely=0.5, anchor=tk.CENTER)
l1.pack()
app.mainloop()
You only update the text on the label. You don't actually change the value of the counter variable. Try this:
def pl1():
global counter
counter += 1
l1.config(text=counter)
def mi1():
global counter
counter -= 1
l1.config(text=counter)
Another option is to create a simple Counter class with methods add() and sub(). It will help you avoid the use of global variables. I also added a test to prevent the counter get negative numbers.
import tkinter as tk
import customtkinter as ctk
app = ctk.CTk()
app.title('People Counter')
app.geometry('300x180')
ctk.set_appearance_mode("System")
ctk.set_default_color_theme("blue")
Label = ctk.CTkLabel
StringVar = ctk.StringVar
class Counter():
def __init__(self):
self.count = 0
def add(self):
self.count += 1
counter_display.config(text=self.count)
return self.count
def sub(self):
self.count -= 1
if self.count < 0:
self.count = 0
counter_display.config(text=self.count)
return self.count
def __repr__(self):
return str(self.count)
counter = Counter()
counter_display = tk.Label(app, text=counter)
add_one = ctk.CTkButton(
master=app,
text='+1',
command=counter.add,
height=5,
width=30
)
add_one.place(relx=0.3, rely=0.5, anchor=tk.CENTER)
sub_one = ctk.CTkButton(
master=app,
text='-1',
command=counter.sub,
height=5,
width=30
)
sub_one.place(relx=0.7, rely=0.5, anchor=tk.CENTER)
counter_display.pack()
app.mainloop()

I can't change the background of the tkinter canvas in python

Despite using the config() method, my canvas's background color won't change. I've made sure the if statement is correct by using some print statements, I've done some research and this is the only way to change the color of an existing canvas-
google search results for how to change the canvas background color
screenshot of program when executed (the canvas is the white thing with the question text, the score is a label, the check mark and X buttons are buttons, and I've used the grid() methods to make them display)
In addition, after browsing some old questions, one of the potential causes for this was that a new canvas was being created after each iteration, and since I've defined the cavas in the innit() method, this isn't the case.
So what exactly should I do?
QuizBrain Class-
import html
class QuizBrain:
def __init__(self, q_list):
self.question_number = 0
self.score = 0
self.question_list = q_list
self.current_question = None
def still_has_questions(self):
return self.question_number < len(self.question_list)
def next_question(self):
self.current_question = self.question_list[self.question_number]
self.question_number += 1
q_text = html.unescape(self.current_question.text)
return f"Q.{self.question_number}: {q_text}"
def check_answer(self, user_answer):
correct_answer = self.current_question.answer
if user_answer.lower() == correct_answer.lower():
self.score += 1
return True
else:
return False
QuizInterface Class- look at the def give_feedback(self, is_right: bool) method, it's responsible for changing the canvas background which tells the user if they got it right(green) or wrong(red). I've also shared the other classes (above and below) for context and incase the problem is there.
from tkinter import *
from quiz_brain import QuizBrain
THEME_COLOR = "#375362"
class QuizInterface:
def __init__(self, quiz_brain: QuizBrain):
self.quiz = quiz_brain
self.window = Tk()
self.window.config(background=THEME_COLOR, padx=20, pady=20)
self.window.title("Quiz")
self.score_label = Label(text="score: 0", font=("Arial", 20, "italic"), padx=20, pady=20, bg=THEME_COLOR,
fg="white")
self.score_label.grid(row=0, column=1)
self.canvas = Canvas(width=300, height=250, background="white")
self.question_text = self.canvas.create_text(150, 125, text="SAMPLE",
font=("Arial", 20, "italic"), fill="black", width=250)
self.canvas.grid(column=0, row=1, columnspan=2, pady=40)
true_image = PhotoImage(file="images/true.png")
false_image = PhotoImage(file="images/false.png")
self.true_button = Button(image=true_image, command=self.true_pressed)
self.true_button.grid(row=2, column=0)
self.false_button = Button(image=false_image, command=self.false_pressed)
self.false_button.grid(row=2, column=1)
self.get_next_question()
self.window.mainloop()
def get_next_question(self):
question_text = self.quiz.next_question()
self.canvas.itemconfig(self.question_text, text=question_text)
def true_pressed(self):
is_right = self.quiz.check_answer("True")
self.give_feedback(is_right)
def false_pressed(self):
is_right = self.quiz.check_answer("False")
self.give_feedback(is_right)
def give_feedback(self, is_right: bool):
print("Called")
if is_right:
print("Called-2")
self.canvas.configure(bg="green")
print("Executed")
elif not is_right:
print("called-3")
self.canvas.configure(bg="red")
print("Executed")
self.window.after(3000, self.get_next_question)
self.canvas.config(background="white")
Question Class-
class Question:
def __init__(self, q_text, q_answer):
self.text = q_text
self.answer = q_answer
How I get my questions-
import requests
parameters = {
"amount": 10,
"type": "boolean"
}
quiz_data = requests.get(url="https://opentdb.com/api.php", params=parameters)
quiz_data.raise_for_status()
quiz_questions = quiz_data.json()
question_data = quiz_questions["results"]
Main.py-
from question_model import Question
from data import question_data
from quiz_brain import QuizBrain
from ui import QuizInterface
question_bank = []
for question in question_data:
question_text = question["question"]
question_answer = question["correct_answer"]
new_question = Question(question_text, question_answer)
question_bank.append(new_question)
quiz = QuizBrain(question_bank)
quiz_interface = QuizInterface(quiz)
#
# while quiz.still_has_questions():
# quiz.next_question()
#
# print("You've completed the quiz")
# print(f"Your final score was: {quiz.score}/{quiz.question_number}")
Move the line
self.canvas.config(background="white")
from give_feedback function to get_next_question function.

is there a way to grid an extra button while running your program in tkinter correctly?

I'm making an mp3 player app and I want the user to be able to add playlists (which will be buttons in a grid system.
Like so.
However in this state when I'm trying to add a playlist button this happens:
The top buttons and the button i just added get squeezed off and the scrollbar is stuck (I can't use it)
I've tried refreshing by self.playlist_frame.update_idletasks() after running create_playlists() but it doesn't seem to change anything
this is my code so you can test it:
import os
import tkinter as tk
from tkinter import ttk
from PIL import Image, ImageTk
class MyApp:
def __init__(self):
self.root = tk.Tk()
self.width = self.root.winfo_screenwidth()
self.height = self.root.winfo_screenheight()
self.height = self.root.winfo_screenheight() - int(self.height / 13)
self.root.geometry(f'{self.width}x{self.height}')
self.root.title("Mp3")
self.c = '#14141D'
self.playlists_buttons_list = []
self.playlists = {}
self.helping_d = {}
self.main = ttk.Notebook(self.root)
self.playlists_tab = tk.Frame(self.main)
self.playlist_menu_frame = tk.Frame(self.playlists_tab, bg=self.c)
self.playlists_canvas = tk.Canvas(self.playlists_tab, bg=self.c)
self.playlist_frame = tk.Frame(self.playlists_canvas, bg=self.c)
self.playlists_scrollbar = ttk.Scrollbar(self.playlists_tab, orient='vertical',
command=self.playlists_canvas.yview)
self.add_playlist_win = tk.Toplevel(self.root)
self.add_playlists_button = tk.Button(self.playlist_frame)
self.default_img = Image.open('images/default.png').resize((75, 72))
self.default_img = ImageTk.PhotoImage(self.default_img)
self.add_img = Image.open('images/add.png').resize((50, 50))
self.add_img = ImageTk.PhotoImage(self.add_img)
self.widgets()
self.root.mainloop()
def widgets(self):
self.playlists_tab.place(height=self.height, width=self.width, x=0, y=0)
self.main.add(self.playlists_tab, text="Playlists")
self.main.pack(expand=1, fill="both")
self.playlist_frame = tk.Frame(self.playlists_canvas, bg=self.c)
self.playlists_canvas.create_window((0, 0), window=self.playlist_frame, anchor='center')
self.playlists_canvas.config(bg=self.c)
self.playlists_canvas.place(height=int(self.height / 1.428), width=self.width, x=0, y=int(self.height / 9))
self.add_playlists_button = tk.Button(self.playlists_canvas, image=self.add_img, bg=self.c, bd=0,
command=self.add_playlists)
self.add_playlists_button.place(x=1284, y=75)
self.playlists_scrollbar.pack(side='right', fill='y')
self.playlists_canvas.config(yscrollcommand=self.playlists_scrollbar.set)
self.playlists_canvas.bind('<Configure>', lambda e: self.playlists_canvas.configure(
scrollregion=self.playlists_canvas.bbox('all')))
if os.path.getsize('playlistsnames.txt') != 0:
lines = open('playlistsnames.txt', 'r', encoding='utf-8').read().splitlines()
for i in lines:
self.playlists[i] = []
self.create_playlists()
def create_playlists(self):
self.playlists_buttons_list = []
for i in range(len(self.playlists.keys())):
self.playlists_buttons_list.append(tk.Button(self.playlist_frame, bg=self.c,
text=' ' + list(self.playlists.keys())[i].split('!')[0],
fg='white', image=self.default_img, height=280, width=300))
row = 0
column = 0
for i in self.playlists_buttons_list:
if column > 3:
row += 1
column = 0
if column > 7:
row += 1
column = 0
i.grid(row=row, column=column)
column += 1
def get_name(self):
self.name_of_plst = self.plst_entry.get()
self.playlists[self.name_of_plst] = []
self.create_playlists()
with open('playlistsnames.txt', 'a', encoding='utf-8') as names_file:
names_file.write(self.name_of_plst + '!\n')
def add_playlists(self):
self.add_playlist_win = tk.Toplevel(self.root)
self.name_label = tk.Label(self.add_playlist_win, text='Name:', bg=self.c, fg='pink').pack()
self.plst_entry = tk.Entry(self.add_playlist_win)
self.plst_entry.pack()
self.confirm_btn = tk.Button(self.add_playlist_win, text='Confirm', bg=self.c, fg='pink',
command=self.get_name).pack()
self.add_playlist_win.mainloop()
MyApp()
I should also mention that because I store the playlist names in a file called playlistnames.txt when I rerun the program I can see all the playlist buttons plus the one I created before and things work just fine.
So what I want is making the grid update and work while running the app without having to rerun the app of course
My playlistsnames.txt file has this format:
rock!
metal!
chill!
rap!
jazz!
blues!
hard rock!
trap!
Any suggestions would be helpful!
Thanks in advance!

Need help understanding how to initialize classes in tkinter python

I'm creating a program that can trade currency using the binance API.
It works as intended (irrelevant code not included)
My problem is that I now want to make is possible to create several instances of the class Trade, in new pop up windows. I'm having trouble understanding how to achieve this in terms of creating new instances of the class Trade. Also I'm pretty sure that my use of self: self = Trade(top) dosen't make any sense (even though it works).
To sum it up:
I want to be able to click a button that starts a new instance of Trade(), so that I can use the methods in the class for two different trading routines at the same time in the same instance of the program. How?
I'll appreciate any form of help, including suggesting me to read up on something.
I'm sorry if im too noob.
Thx in advance.
class Trade(Frame):
stop_trading = False
amount_orders = 0
after_id = 0
def __init__(self, master=None):
Frame.__init__(self, master)
def change_orders(self):
if list_variable4.get() == 'TRUE':
if self.check_open_order() == False or self.amount_orders<2:
if self.delete_open_orders() == True and self.stop_trading != True:
self.create_orders()
...
def cron():
self.amount_orders += 1
if self.amount_orders > int(trade_cap_box.get(0.0, tk.END)):
message_window.insert(tk.END,'\nTrade Cycle Cap reached with {} trades'.format(self.amount_orders - 1))
cap_stop_trading()
if self.stop_trading != True:
message_window.insert(tk.END,'\nTrading Cycle Started{}'.format(self.amount_orders))
interval = int(rate_of_check_box.get(0.0, tk.END))
print('Trading!')
self.change_orders()
self.after_id = top.after(interval*1000*60, cron)
def start_trading():
self.amount_orders = 0
self.stop_trading = False
cron()
top = Tk()
top.geometry("600x500")
top.title('Trade Cron Job')
self = Trade(top)
message_window = Text(top, height=5, width=65)
message_window.place(x = 40,y = 10)
trading_symbol_box = Text(top, height=1, width=20)
trading_symbol_box.place(x = 200,y = 130)
default_trading_symbol = (self.config_data['configs']['symbol'])
if default_trading_symbol:
trading_symbol_box.insert(END, default_trading_symbol)
else:
trading_symbol_box.insert(END, "")
trading_symbol_labels = Label(top, text='Trading Symbol')
trading_symbol_labels.place(x = 40,y = 130)
start_value_box = Text(top, height=1, width=20)
start_value_box.place(x = 200,y = 160)
start_value_box.insert(END, 0)
start_value_labels = Label(top, text='Start Value To Progress From')
start_value_labels.place(x = 40,y = 160)
and so on...
top.mainloop()
You need to create an instance of Toplevel, then add the instance of Trade to that window.
def new_window():
window = Toplevel()
trade_frame = Trade(window)
trade_frame.pack(fill="both", expand=True)
...
new_window_button = Button(top, text="New Window", command=new_window)

Why is Python still garbage-collecting my Tkinter image?

I'm aware that this is a question that has been asked before on this site. However, I've made an honest attempt to implement the solutions put forward in those answers, and I'm still running into the same problem: Python seems to keep garbage-collecting my image, and I get an empty slot in my window where the image ought to be, as shown in the attached screenshot.
This is the part of my code where I attempt to import an image:
def make_top_title(self):
result = Frame(self.top)
text_lbl = Label(result, text="Proserpine",
font=(main_font, title_pt, "bold"))
arms_image = PhotoImage("icon.png")
arms_lbl = Label(result, image=arms_image, height=200)
arms_lbl.image = arms_image
arms_lbl.pack()
text_lbl.pack()
return result
You'll notice that I've already attempted to use the trick of preserving the image by anchoring it onto a property of a label object. You may also notice, from the attached screenshot, that I have no problem importing a custom icon - using the same image file - for this window.
I'm happy to share any more code from this program, as required.
A couple of people have suggested I share a bit more of my code. This is the whole file in which the code above is located:
### This code holds a class which allows the user to inspect a the coldstore
### object attached to its parent.
# GUI imports.
from tkinter import *
# Custom imports.
from sibstructures import data_storage
from sibstructures.numerals import index_to_label_column, \
index_to_label_row, \
index_to_label_layer
# Imports
import time
from threading import Thread
# Local constants.
main_font = "Arial"
title_pt = 60
subtitle_pt = 30
big_pt = 20
standard_pt = 15
diddy_pt = 10
standard_pad = 10
inner_pad = 5
tile_width = 15
details_height = 10
details_width = 30
grid_border = 5
spot_stack_width = tile_width+5
##############
# MAIN CLASS #
##############
# The class in question.
class CS_Viewer:
def __init__(self, parent):
self.parent = parent
self.parent_window = self.parent.get_top()
self.code = self.parent.coldstore.code
self.parent.coldstore.reconstruct()
self.max_max_layers = self.parent.coldstore.get_max_max_layers()
self.layer = 0
self.top = Frame(self.parent_window)
self.top_title = self.make_top_title()
self.subtitle = Label(self.top, text="code="+self.code,
font=(main_font, subtitle_pt, "bold"))
self.main_container = Frame(self.top)
self.spot_grid = Spot_Grid(self, self.main_container)
self.box_details = Text(self.main_container,
height=details_height, width=details_width,
state=DISABLED)
self.spot_stack = Spot_Stack(self.main_container, None,
self.box_details)
self.add_headings()
self.arrange()
# Ronseal.
def make_top_title(self):
result = Frame(self.top)
text_lbl = Label(result, text="Proserpine",
font=(main_font, title_pt, "bold"))
arms_image = PhotoImage("icon.png")
arms_lbl = Label(result, image=arms_image, height=200)
arms_lbl.image = arms_image
arms_lbl.pack()
text_lbl.pack()
return result
# Add headings to the holster widgets.
def add_headings(self):
spot_grid_label = Label(self.main_container, text="Coldstore",
font=(main_font, big_pt, "bold"))
spot_stack_label = Label(self.main_container, text="Spot",
font=(main_font, big_pt, "bold"),
width=spot_stack_width)
box_details_label = Label(self.main_container, text="Box",
font=(main_font, big_pt, "bold"))
spot_grid_label.grid(column=0, row=0)
spot_stack_label.grid(column=1, row=0)
box_details_label.grid(column=2, row=0)
# Ronseal.
def place_spot_stack(self):
self.spot_stack.get_top().grid(column=1, row=1,
padx=standard_pad, pady=standard_pad)
# Arrange the object's elements.
def arrange(self):
self.top_title.pack()
self.subtitle.pack()
self.spot_grid.get_top().grid(column=0, row=1, sticky=N,
padx=standard_pad, pady=standard_pad,
ipadx=inner_pad, ipady=inner_pad)
self.place_spot_stack()
self.box_details.grid(column=2, row=1, sticky=N,
padx=standard_pad, pady=standard_pad)
self.main_container.pack()
# Replace the spot stack widget.
def replace_spot_stack(self):
self.spot_stack.get_top().grid_forget()
self.place_spot_stack()
# Ronseal.
def get_top(self):
return self.top
################################
# HELPER CLASSES AND FUNCTIONS #
################################
# A class which holds the grid of spots.
class Spot_Grid:
def __init__(self, parent, parent_window):
self.parent = parent
self.parent_window = parent_window
self.top = Frame(self.parent_window, borderwidth=grid_border,
relief="solid")
Thread(target=self.make_grid).start()
# Fill the grid with boxes.
def make_grid(self):
cs = self.parent.parent.coldstore
for i in range(len(cs.columns)):
column_label = Label(self.top, text=str(index_to_label_column(i)),
font=(main_font, big_pt, "bold"))
column_label.grid(column=(i+1), row=0, padx=standard_pad)
for j in range(len(cs.columns[0].spots)):
if i == 0:
row_label = Label(self.top, text=str(index_to_label_row(j)),
font=(main_font, big_pt, "bold"))
row_label.grid(column=0, row=(j+1), padx=standard_pad)
tile = Spot_Tile(self, self.parent, cs.columns[i].spots[j],
self.parent.box_details)
tile.get_top().grid(column=(i+1), row=(j+1))
# Ronseal.
def get_top(self):
return self.top
# A class which holds a clickable representation of a spot.
class Spot_Tile:
def __init__(self, parent, main_ref, spot_obj, box_details_ref):
self.parent = parent
self.main_ref = main_ref
self.spot_obj = spot_obj
self.box_details_ref = box_details_ref
self.parent_window = self.parent.get_top()
self.top = Frame(self.parent_window)
Thread(target=self.make_filling).start()
# Fill the object with either a tile or a label.
def make_filling(self):
if self.spot_obj.max_layers == 0:
filling = Label(self.top, text="VOID", font=(main_font, diddy_pt),
width=tile_width)
elif self.spot_obj.layers() == 0:
filling = Button(self.top, text="free", command=None,
font=(main_font, diddy_pt, "italic"),
width=tile_width, state=DISABLED)
else:
filling = self.make_filling_button()
filling.pack()
# Make the filling object if it is a button.
def make_filling_button(self):
result = Button(self.top, text=self.make_filling_button_text(),
command=self.inspect,
font=(main_font, diddy_pt), width=tile_width)
return result
# Make the text portion of the filling button.
def make_filling_button_text(self):
growers = set()
varieties = set()
fields = set()
for box in self.spot_obj.boxes:
current_epc = box.epc
current_data = data_storage.fetch_most_recent_crop(current_epc)
growers.add(current_data["grower"])
varieties.add(current_data["variety"])
fields.add(current_data["field"])
result = (set_to_string(growers)+"\n"+set_to_string(varieties)+"\n"+
set_to_string(fields)+"\n"+str(len(self.spot_obj.boxes)))
return result
# Inspect a given spot.
def inspect(self):
self.main_ref.spot_stack = Spot_Stack(self.main_ref.main_container,
self.spot_obj,
self.box_details_ref)
self.main_ref.replace_spot_stack()
# Ronseal.
def get_top(self):
return self.top
# A class which holds a representation of the boxes on a given spot.
class Spot_Stack:
def __init__(self, parent_window, spot_obj, box_details_ref):
self.parent_window = parent_window
self.spot_obj = spot_obj
self.box_details_ref = box_details_ref
self.top = Frame(self.parent_window)
if self.spot_obj is None:
self.fill_empty()
else:
Thread(target=self.add_boxes).start()
# "Fill in" the representation if the spot object is empty.
def fill_empty(self):
label = Label(self.top, text="Select spot",
font=(main_font, standard_pt, "italic"), width=tile_width)
label.pack()
# Add representations of the spot's boxes.
def add_boxes(self):
no_of_boxes = len(self.spot_obj.boxes)
if no_of_boxes == 0:
empty_label = Label(self.top, text="Empty spot",
font=(main_font, standard_pt, "italic"),
width=tile_width)
empty_label.pack()
else:
for i in range(no_of_boxes):
backwards_index = (no_of_boxes-1)-i
box_tile = Box_Tile(self.top, self.spot_obj.boxes[backwards_index],
backwards_index, self.box_details_ref)
box_tile.get_top().pack()
# Ronseal.
def get_top(self):
return self.top
# A class which holds a clickable representation of a box.
class Box_Tile:
def __init__(self, parent_window, box, index, box_details_ref):
self.parent_window = parent_window
self.box = box
self.index = index
self.box_details_ref = box_details_ref
self.top = Frame(self.parent_window)
self.make_filling()
# Fill the object with either a tile or a label.
def make_filling(self):
label = Label(self.top, text=str(index_to_label_layer(self.index)),
font=(main_font, standard_pt))
filling = Button(self.top, text=self.box.epc, command=self.inspect,
font=(main_font, standard_pt), width=tile_width)
label.grid(column=0, row=0, padx=standard_pad)
filling.grid(column=1, row=0)
# Ronseal.
def get_top(self):
return self.top
# Inspect the data for this particular box in more detail.
def inspect(self):
text_to_insert = data_storage.fetch_most_recent_crop(self.box.epc)
self.box_details_ref.config(state=NORMAL)
self.box_details_ref.delete("1.0", END)
self.box_details_ref.insert(END, text_to_insert)
self.box_details_ref.config(state=DISABLED)
# Turns a set into a string, with items thereof separated by commas.
def set_to_string(the_set):
result = ""
the_list = list(the_set)
# Reversal is necessary, since .add() seems to add items to the FRONT of
# the set.
the_list.reverse()
for item in the_list:
if the_list.index(item) == 0:
result = item
else:
result = result+", "+item
return result
This is the other file, which, with its fellow, makes up the whole program:
### This code holds a class which manages transitions between windows, and
### also oversees their interactions with the Coldstore object.
# Imports.
from pathlib import Path
# GUI imports.
from tkinter import *
# Custom imports.
from sibstructures.coldstore import Coldstore
# Local imports.
from cs_viewer import CS_Viewer
# Constants.
path_to_db = str(Path.home())+"/cseye/source/proserpine/data.db"
##############
# MAIN CLASS #
##############
# The class in question.
class Comptroller:
def __init__(self):
self.coldstore = Coldstore(proserpine_mode=True,
proserpine_path=path_to_db)
self.gui = Tk()
self.top = Frame(self.gui)
self.window = CS_Viewer(self)
self.arrange()
# Return the top-level GUI object.
def get_top(self):
return self.top
# Arrange the widgets.
def arrange(self):
self.window.get_top().pack()
self.top.pack()
# Run the "mainloop" method on the GUI object.
def run_me(self):
self.gui.title("Proserpine")
self.gui.iconphoto(True, PhotoImage(file="icon.png"))
self.gui.mainloop()
###################
# RUN AND WRAP UP #
###################
def run():
comptroller = Comptroller()
comptroller.run_me()
if __name__ == "__main__":
run()
The argument to PhotoImage("...") is wrong. It should be PhotoImage(file="...").

Categories