Text in button not increasing - python

I'm creating a memory quiz app for people with dementia where it asks them about their day and they have to answer the question. A family/friend has to first fill in their memories which gets entered into a database.
I'm trying to increase the size of the text in the buttons, however the size of the button increases instead. I'm unsure on how to fix this. The answers are saved to an SQL database and retrieved from there. I am using a Guizero GUI.
Here's my code:
box1=Box(Todays_Quiz, layout = "auto", width = 1000, height = 700)
emptyspace =Text(box1, text="")
question1= Text(box1, "What time did you wake up?", width = "fill")
question1.bg= "#A1A9A9"
question1.text_size= 20
emptyspace =Text(box1, text="""
""")
wakeupAnswer1 = get_q1_answers(0)
wakeupAnswer2 = get_q1_answers(1)
wakeupAnswer3 = get_q1_answers(2)
wakeup1 = PushButton(box1, width = 50, height = 5, text = wakeupAnswer1, command=change_score1) # correct answer
emptyspace =Text(box1, text="")
wakeup2 = PushButton(box1, width = 50, height = 5, text = wakeupAnswer2, command=next_question1)
emptyspace =Text(box1, text="")
wakeup3 = PushButton(box1, width = 50, height = 5, text = wakeupAnswer3, command=next_question1)
wakeup1.bg="#fa7a7a"
wakeup1.text_size = 15
wakeup2.bg="#fa7a7a"
wakeup2.text_size =15
wakeup3.bg="#fa7a7a"
wakeup3.text_size = 15

Related

tkinter strange phenomenon with buttons and images

I don't know what to say because I am clueless on why this is not working.
The first button appears but the image does not the second and third button does not appear.
from tkinter import *
Master = Tk()
Master.geometry("1408x768")
Master.configure(background = "#000000")
# Top
Top = Frame(Master)
Top.configure(background = "#1C1C1C", width = 1024.0, height = 384.0)
Top.place(x = 0.0, y = -5.684341886080802e-14)
Nextimg = PhotoImage(file = "Next.png")
Next = Button(master = Top, background = "#0084FF", image = Nextimg)
Next.place(x = 624.0, y = 551.0, width = 100, height = 50)
# Bottom
Bottom = Frame(Master)
Bottom.configure(background = "#8C8C8C", width = 1024.0, height = 384.0)
Bottom.place(x = 0.0, y = 384.0)
Nextimg = PhotoImage(file = "Next.png")
Next = Button(master = Bottom, background = "#0084FF", image = Nextimg)
Next.place(x = 624.0, y = 551.0, width = 100, height = 50)
# Dashboard
Dashboard = Frame(Master)
Dashboard.configure(background = "#252525", width = 384.0, height = 768.0)
Dashboard.place(x = 1024.0, y = 0.0)
Continueimg = PhotoImage(file = "Continue.png")
Continue = Button(master = Dashboard, background = "#FF8900", image = Continueimg)
Continue.place(x = 1091.0, y = 359.0, width = 250, height = 50)
Your primary issue here appears that you are expecting your widget placement to be relative to the root window but in fact they are relative to the frames they are placed in.
Try this. Change all your buttons X/Y to 20 and see what I mean.
You will see all the buttons show up in the top left corner of each frame they are assigned to.
One issue is that you are using place to manage widgets and this is very bad for code maintenance. It is much better to use grid() and/or pack() to build your windows for several reasons.
Automatic weights to adjust placement based on window size and easy of maintainability as your code grows.
The issue you will see with your 1st and 2nd buttons is the 1st button does not show the image due to the reference being reassigned.
If you want to use the same image for both just save a reference once.
In this case you can remove the 2nd Nextimg = from your code.
See what happens when we change the placement to 20's
from tkinter import *
Master = Tk()
Master.geometry("1408x768")
Master.configure(background = "#000000")
Top = Frame(Master)
Top.configure(background = "#1C1C1C", width = 1024.0, height = 384.0)
Top.place(x = 0.0, y = -5.684341886080802e-14)
Nextimg = PhotoImage(file = "Next.png")
Next = Button(master = Top, background = "#0084FF", image = Nextimg)
Next.place(x = 20, y = 20, width = 100, height = 50)
Bottom = Frame(Master)
Bottom.configure(background = "#8C8C8C", width = 1024.0, height = 384.0)
Bottom.place(x = 0.0, y = 384.0)
# Nextimg = PhotoImage(file = "Next.png") Removed this as it is why your image does not show up on the first button.
Next = Button(master = Bottom, background = "#0084FF", image = Nextimg)
Next.place(x = 20, y = 20, width = 100, height = 50)
Dashboard = Frame(Master)
Dashboard.configure(background = "#252525", width = 384.0, height = 768.0)
Dashboard.place(x = 1024.0, y = 0.0)
Continueimg = PhotoImage(file = "Continue.png")
Continue = Button(master = Dashboard, background = "#FF8900", image = Continueimg)
Continue.place(x = 20, y = 20, width = 250, height = 50)
Master.mainloop()
Note that I replaced your images with grey squares since I did not have your image to use.
Results:
A more conventional way to write this would be to use grid() or pack().
Also I have rewritten the code to more closely fit PEP* standards.
See below example:
import tkinter as tk
master = tk.Tk()
master.geometry("1408x768")
master.configure(background="#000000")
top = tk.Frame(master)
top.grid_propagate(False)
top.configure(background="#1C1C1C", width=1024.0, height=384.0)
top.grid(row=0, column=0)
nextimg = tk.PhotoImage(file="gray.png")
tk.Button(master=top, background="#0084FF", image=nextimg).grid(row=0, column=0)
bottom = tk.Frame(master)
bottom.grid_propagate(False)
bottom.configure(background="#8C8C8C", width=1024.0, height=384.0)
bottom.grid(row=1, column=0)
tk.Button(master=bottom, background="#0084FF", image=nextimg).grid(row=0, column=0)
dashboard = tk.Frame(master)
dashboard.grid_propagate(False)
dashboard.configure(background = "#252525", width = 384.0, height = 768.0)
dashboard.grid(row=0, column=1, rowspan=2)
continueimg = tk.PhotoImage(file="gray.png")
tk.Button(master=dashboard, background="#FF8900", image=continueimg).grid(row=0, column=0)
master.mainloop()
Results:
You can also manage spacing of the widgets from the edges if you like. That can be done by providing a padx/pady parameter to the grid().

Image & Text button - no image appears - tkinter [duplicate]

This question already has answers here:
Why does Tkinter image not show up if created in a function?
(5 answers)
Closed 5 months ago.
It's my first post here, I also have a puzzlement about the code below.
I don't have the image displayed next to the text, the button is properly displayed (p.s : why the height and width have to be adjusted again, for example the button without the picture has width = 22 and height = 2, when I put the picture to be visible I have 200 by 200, well it can be a bit smaller), I have the text displayed, but the picture is missing...Could it be from .grid?
bl_logo = Image.open('img/balance.png')
bl_logo = bl_logo.resize((25,25), Image.ANTIALIAS)
balance_img = ImageTk.PhotoImage(bl_logo)
buttons_frame = tk.Frame(main_frame, bg = "#004d4d")
balance_btn = tk.Button(buttons_frame, image = balance_img, compound = tk.LEFT, text = 'BALANCE', font = ('Bebas NEUE', 20), width = 220, height = 200)
balance_btn.grid(row = 0, column = 0, sticky = tk.W, padx = 10, pady = (60,40)
You have to save the balance_img in the widget class to prevent it from the garbage collector.
add this line balance_btn.image = balance_img
bl_logo = Image.open('img/balance.png')
bl_logo = bl_logo.resize((25,25), Image.ANTIALIAS)
balance_img = ImageTk.PhotoImage(bl_logo)
buttons_frame = tk.Frame(main_frame, bg = "#004d4d")
balance_btn = tk.Button(buttons_frame, image = balance_img, compound = tk.LEFT, text = 'BALANCE', font = ('Bebas NEUE', 20), width = 220, height = 200)
balance_btn.image = balance_img
balance_btn.grid(row = 0, column = 0, sticky = tk.W, padx = 10, pady = (60,40)
I already answer this question's answer to another user.

Python Tkinter: object has no attribute tk

I am new to tkinter, python, and programming in general. I have made an example program of what I'm trying to do. I am trying to use tkinter GUI to receive user inputs for date and time, then convert these tk entries into strings, then check the format of the date and time strings, then if the format is good add the date and time to a list. My issue is with converting the tk entries into strings. When I try to do so I receive an error that says "Example object has no attribute tk". In my program, I have a tk window that is made in my UserInputWindow function, and I pass this window to PromptDateTime, which is where the user is prompted to enter a date and time. When I try to convert using "dateFromUser = tk.Entry(self)", this is the part that receives the error. I don't understand why the PromptDateTime function had no problem editing the window from UserInputWindow function, yet when tk is directly referenced there is an issue.
Also: I had some trouble with formatting my code below (new to stack overflow) so please note that the first section of code is part of "class Example()", and the second section of code is the main function.
Thank you for your help! Please be nice! I'm a newbie and open to critiques.
class Example():
#data members
__dateEntry = None
__timeEntry = None
exampleList = []
def UserInputWindow(self, windowName, instruction):
#Create new window to display fields and options
new_window = tk.Tk()
new_window.title(f'{windowName}')
new_window.geometry = ("500x500")
#Label to display instructions
label_instruction = Label(new_window, text = (f'{instruction}'), font = ("Courier", 10), justify = LEFT, fg = "black", bg = "light yellow")
label_instruction.grid(row = 0, column = 0)
return new_window
#this function checks to see if date string from user is in proper format, and if it is not an error window appears.
def VerifyDate(self, d):
#code deleted for simplicty for this example
#this function checks to see if time string from user is in proper format, and if it is not an error window appears.
def VerifyTime(self, t):
#code deleted for simplicty for this example
#this function prompts user for date and time
def PromptDateTime(self, new_window):
#Label to display instructions
label_instruction = Label(new_window, text = "Enter activity date and time: ",font = ("Courier", 10), justify = LEFT, fg = "black", bg = "light yellow")
label_instruction.grid(row = 0, column = 0)
#Create labels and entries for date and time
label_date = Label(new_window, text = "Enter date in MM/DD/YYYY format: ",fg = "black", bg = "white")
label_date.grid(row = 1, column = 0, padx = 5)
dateEntry = Entry(new_window, fg = 'black', bg = 'white', width = 10)
dateEntry.grid(row = 2, column = 0, padx = 5)
dateFromUser = tk.Entry(self)
str(dateFromUser)
label_time = Label(new_window, text = "Enter time in hh:mm format (military time): ",fg = "black", bg = "white")
label_time.grid(row = 3, column = 0, padx = 5)
timeEntry = Entry(new_window, fg = 'black', bg = 'white', width = 10)
timeEntry.grid(row = 4, column = 0, padx = 5)
self.VerifyDate(dateFromUser)
self.VerifyTime(timeEntry)
def SubmitButton(self, new_window, new_command):
button_submit = Button(new_window, fg = "black", bg = "light blue", text = "Submit", command = new_command)
button_submit.grid(row = 17, column = 10, pady = 5)
def PromptAndAddToList(self):
window = self.UserInputWindow('Date and Time', 'Enter date and time as specified below.')
self.PromptDateTime(window)
self.SubmitButton(window, lambda:exampleList.append(otherClass(dateEntry, timeEntry)))
#################################################
if __name__ == '__main__':
from tkinter import *
import tkinter as tk
import datetime
ex = Example()
ex.PromptAndAddToList()
root = tk.Tk()
root.withdraw()
root.mainloop()
As the error said, the parent of dateFromUser is Example:
dateFromUser = tk.Entry(self) # self is instance of class Example
but Example is not a tkinter widget.
Use new_window instead of self:
dateFromUser = tk.Entry(new_window)

Tkinter listboxes and canvas won't scroll together

I want the following layout in TkInter:
4 listboxes next to eachother, a canvas next to them, filled with buttons (one button for every element in the listboxes)
The problem is, that the canvas can be scrolled with the listboxes, also on it's own, but even higher than the point where it has content, which means, you can scroll it to the very top, but the listbox belonging to it won't even move, and they are de-synched already. So question is, how can I give a point for the scrolling where it can not go higher?
The code I have is the following:
from Tkinter import *
def Scroll2Gether(*args):
list1.yview(*args)
list2.yview(*args)
list3.yview(*args)
list4.yview(*args)
ButtonLine.yview(*args)
master = Tk()
EndLayer = Canvas(master)
scroll = Scrollbar(orient="vertical", command=Scroll2Gether)
UpperLayer = Frame(EndLayer, bg = '#000fff000')
list1 = Listbox(UpperLayer, bg = "#B2B2B2",width = 60)
list3 = Listbox(UpperLayer, bg = "#B2B2B2",width = 60)
list4 = Listbox(UpperLayer, bg = "#E5E5E5",width = 60)
list2 = Listbox(UpperLayer, bg = "#E5E5E5",width = 60)
Framm = Frame(UpperLayer, bg = "#ffa300", width = 30, )
Address1 = Label(list1, text = "OWNER1", bg= "#E5E5E5",width = 60,font=("Helvetica", 8,"bold"))
Address2 = Label(list2, text = "OWNER2", bg= "#B2B2B2", width = 60,font=("Helvetica", 8,"bold"))
Address3 = Label(list3, text = "MailDL", bg= "#E5E5E5", width = 60,font=("Helvetica", 8,"bold"))
Address4 = Label(list4, text = "ExpirationDate", bg= "#B2B2B2", width = 60,font=("Helvetica", 8, "bold"))
ButtonLine = Canvas(Framm, bg = "#E5E5E5", width = 30)
Address1.pack(side = TOP)
Address2.pack(side = TOP)
Address3.pack(side = TOP)
Address4.pack(side = TOP)
list1.pack(side = LEFT, fill = "y")
list2.pack(side = LEFT, fill = "y")
scroll.pack(side="right",fill="y")
list3.pack(side = LEFT, fill = "y")
list4.pack(side = LEFT, fill = "y")
Framm.pack(side=LEFT)
ButtonLine.pack(side = BOTTOM)
UpperLayer.pack()
EndLayer.pack()
x = 0
photo=PhotoImage(file="email.gif")
for i in ("qwertzuiopasfghjklyxcvbnm"):
i = Button(text="Mail")
i.config(image = photo, width = 20, height = 20)
Button_Window = ButtonLine.create_window(1, 22+x, anchor = NW, window = i)
x = x+26
Thanks for any help in advance.
SOLVED! I found out that it makes no sense to group 3 columns, so I created lines which are canvas and created canvases in them for every input in a loop.

Raspberry Pi and Python (TKinter and Omxplayer)

we made an alarm clock program in python that uses TKinter to display the word "ALARM" when the current time equals the alarm time set by the user. Now we're trying to add an alarm sound to the program, so a sound will play when the current time reaches the alarm time set.
For some weird reason when the current time reaches the alarm time the alarm sound is opened and played about 7 times all at once and then exits.
We've tried a few different things to get it to just play the sound file once but nothing has worked. Do you guys have any suggestions at all? I can post more specific information/screenshots if need be. :)
Code so far:
import time
import subprocess
#GUI Setup
from Tkinter import *
alarm_window = Tk()
alarm_window.configure(bg = 'lightblue')
alarm_window.title('Alarm Clock!')
display = Label(alarm_window, font = ('Arial', 25), bg = 'lightblue', width = 13, height = 1, borderwidth = 2)
display.grid(row = 1, column = 1, columnspan = 6)
current_time = time.strftime("%H:%M:%S")
def refresh_time():
global current_time
current_time = time.strftime("%H:%M:%S")
if current_time == times.get():
alarm_window.configure(bg='red')
timelabel.configure(bg='red')
alarmdisplay = Label(alarm_window, font = ('Arial', 25), text = 'ALARM', bg='red', width = 13, height = 1, borderwidth = 2,)
alarmdisplay.grid(row = 2, column = 1, columnspan = 6)
playProcess = subprocess.Popen(['omxplayer', '/home/pi/Digital Alarm.mp3?dl=0'])
display.config(text=current_time)
display.after(10, refresh_time)
timelabel = Label(alarm_window, text = 'Enter H:M:S', bg = 'lightblue')
timelabel.grid(row = 2, column = 1)
times = Entry(alarm_window, width = 10, bg = 'lightgrey', justify = CENTER)
times.grid(row = 2, column = 2, columnspan = 5)
times.focus()
refresh_time()
alarm_window.mainloop()
Don't know omxplayer, but if it quits after playing the sound, you could simply wait for it to finish like:
playProcess = subprocess.Popen(['omxplayer', '/home/pi/Digital Alarm.mp3?dl=0'])
playProcess.wait()

Categories