I wanted to make my app look more beautiful and it's harder than I though! Now I had an app with mainly 2 buttons and date-time label on top. Buttons are just with text, but I want to use pictures on them. That's my code now:
def showMainMenu():
global cardNumber, allowToGPIO
cardNumber = "" #Reset cardNumber global value
allowToGPIO = True
clear()
showNewTime()
watchDog.awake()
GuestTestButton = Button(canvas, text="GUEST TEST", width=buttonwidth, height=buttonheight, compound = TKinter.CENTER, command = guestTest)
GuestTestButton.config(font=("Mojave-Regular.ttf", 24))
#GuestTestButton.pack()
GuestTestButton.place(x=90, y=100)
AddEmployeeButton = Button(canvas, text="ADD NEW USER", width=buttonwidth, height=buttonheight, compound = TKinter.CENTER, command = addEmployee)
AddEmployeeButton.config(font=("Mojave-Regular.ttf", 24))
#AddEmployeeButton.pack()
AddEmployeeButton.place(x=90, y=270)
And for now, it works. But when I tried to make them more colorful (just use image instead of text), button shows up without anything on it. Is it even possible to make things like that in TKinter? Everything I do is on canvas:
app = TKinter.Tk()
canvas = TKinter.Canvas()
I tried to do this that way:
GuestImage = TKinter.PhotoImage(file="guest.gif")
GuestTestButton = Button(canvas, text="GUEST TEST", width=buttonwidth, height=buttonheight, compound = TKinter.CENTER, command = guestTest)
GuestTestButton.config(image=GuestImage, font=("Mojave-Regular.ttf", 24))
GuestTestButton.place(x=90, y=100)
But as I said, it's not working properly :D Thanks in advance for any help!
I got it now, my images shows up but it dissapears after miliseconds, now I made the GuestImage and AddEmployeeImage as global variables and it works perfectly!
Related
Before you read:
I am a complete novice at programming let alone Python. I don't expect solutions. I will appreciate it even if I just get a pointer in the right direction. If you feel the way I've requested help is unrefined, please let me know so next time I need help, I'll do a better job at asking.
Goal:
I'm making a program to test how to get a program to respond depending on which widget has to focus on. Currently, I'm just having it respond by displaying 'what' has focus.
Eventually, once I've figured this out I can implement what I've learnt into another program I'm working on was focusing on an entry field will result in the field clearing of all input. So naturally, I will want this program to not only change the label but the entry widget too. That will be for later.
Progress:
I've managed to have the program print which widget has a focus in both the terminal and in a label widget.
Problem:
My issue is that the message is ugly, and I want it to look neater.
Example of the problem:
Instead of saying "Entry has focus", it says ".!frame.!entry {has focus}"
I have tried:
Checking if other's have made similar programs. The only one I found was how I made this much progress but it didn't make the text nicer. I've also done research on various sites on how Python handles certain commands I've used in this program.
I am a novice with programming so I admit I'm not completely sure what the best way to run this program is and so trying to research it is difficult for me.
Code:
# Call tkinter tools
from tkinter import *
from tkinter import ttk
"""
TODO:
Add different widgets that can 'gain' focus.
Print in the terminal which widget has focus.
Change entry and label text depending on which widget has focus.
"""
# Develop the window and frame
root = Tk()
root.title("Focus Test")
root.columnconfigure(0, weight = 1)
root.rowconfigure(0, weight = 1)
frame = ttk.Frame(root, padding = "1 1 1 1")
frame.grid(column = 0, row = 0, sticky = (N, S, E, W))
# Resizes columns in frame
for col in range(1, 3):
frame.columnconfigure(col, weight = 1)
# Resizes rows in frame
for row in range(1, 3):
frame.rowconfigure(row, weight = 1)
# Add response label
foc_labvar = StringVar()
foc_labvar.set("No focus")
foc_lab = ttk.Label(frame, width = 7, textvariable = foc_labvar)
foc_lab.grid(column = 2, row = 2, sticky = (W, E))
# Add entry box
foc_entvar = StringVar()
foc_entvar.set("Entry widget")
foc_ent = ttk.Entry(frame, width = 7, textvariable = foc_entvar)
foc_ent.grid(column = 1, row = 1, sticky = (W, E))
# Add button
foc_butvar = StringVar()
foc_butvar.set("Button widget")
foc_but = ttk.Button(frame, width = 7, textvariable = foc_butvar)
foc_but.grid(column = 2, row = 1, sticky = (W, E))
# Focus commands
def focus(event):
focused_widget = frame.focus_get()
foc_labvar.set((focused_widget, "has focus"))
print(focused_widget, "has focus")
# Bind mouse click to run focus command
root.bind("<Button-1>", focus)
# Resize widgets inside frame
for child in frame.winfo_children():
child.grid_configure(padx = 5, pady = 5)
root.mainloop()
You can just easily do this having event handle the widget identification part, like:
def focus(event):
focused_widget = event.widget.winfo_class()
foc_labvar.set((focused_widget, "has focus")) # Or f'{focused_widget} has focus'
print(focused_widget, "has focus")
Here event will provide the widget with widget method and then you can use any widget methods on it, like focus() or insert()(if its an entry widget) and so on. Here winfo_class should work, because it is a universal method and works with all the widgets.
More info on winfo_class, it will provide the class of the widget, like TButton for buttons, because that is how tk refers to them. If you adamantly still want to get rid of the T then just go for event.widget.winfo_class()[1:] to trim the 'T' off.
You can give widgets a name of your choosing. You can then use winfo_name to get the name of the widget. About the only required for a name is that it cannot have a period in it.
Also, you should bind to <FocusIn> and <FocusOut> so that your code works even if the focus changes via the keyboard.
foc_ent = ttk.Entry(..., name="foc entry")
foc_but = ttk.Button(..., name="foc button")
...
def focus(event):
focused_widget = frame.focus_get()
if focused_widget:
foc_labvar.set(f"{focused_widget.winfo_name()} as focus")
else:
foc_labvar.set("nothing has focus")
root.bind("<FocusIn>", focus)
root.bind("<FocusOut>", focus)
You can just use an if statement like this:
def focus(event):
focused_widget = frame.focus_get() # You can also use `event.widget` like what #CoolCloud did.
if focused_widget == foc_ent:
foc_labvar.set("Entry has focus")
if focused_widget == foc_but:
foc_labvar.set("Button has focus")
Combining the advice provided. Here is what I've ended up with which is working the way I had imagined in my head plus a little extra from everyone's help:
# Focus commands
def focus(event):
focused_widget = event.widget.winfo_class()[1:]
foc_labvar.set(focused_widget + " has focus")
foc_entvar.set(focused_widget + " has focus")
print(focused_widget, "has focus")
# Bind mouse and keyboard to run focus command
root.bind("<Button-1>", focus)
root.bind("<FocusIn>", focus)
root.bind("<FocusOut>", focus)
I've been watching this youtube tutorial and had (I thought) a way better idea of solving the build an image viewer app.
But nothing happens on input, and I don't understand why, I think I might have totally misunderstood list as it doesn't start with the first picture (index 0).
The code is here
from tkinter import *
from PIL import ImageTk,Image
i = 0
root = Tk()
root.title("Learning to code")
root.iconbitmap('blue.PNG')
my_img1 = ImageTk.PhotoImage(Image.open("pics\me1.JFIF"))
my_img2 = ImageTk.PhotoImage(Image.open("pics\me2.JPG"))
my_img3 = ImageTk.PhotoImage(Image.open("pics\me3.JPG"))
my_img4 = ImageTk.PhotoImage(Image.open("pics\me4.JPG"))
my_img5 = ImageTk.PhotoImage(Image.open("pics\pop.JPG"))
img_list = [my_img1,my_img2,my_img3,my_img4,my_img5]
my_label = Label(image=img_list[i])
my_label.grid(row=0,column=0,columnspan=3)
def f_fwd():
global i
global my_label
if i < 4 :
my_label.grid_forget()
i =+1
my_label = Label(image=img_list[i])
my_label.grid(row=0,column=0,columnspan=3)
def f_bwd():
return
button_bwd = Button(root, text= "<<")
button_bwd.grid(row=1,column=0)
button_quit =Button(root, text="Exit", command= root.quit)
button_quit.grid(row=1,column=1)
button_fwd = Button(root, text=">>", command=f_fwd())
button_fwd.grid(row=1,column=2)
root.mainloop()
Sorry if I worded the problem poorly.
I expected the index to go up and display the next picture in the list when the f_fwd function is called from the button command, and I don't understand why its not working.
im relatively new to coding and am trying to display an image on tkinter, i have it set so when you press on a button on the first screen it will open to another screen - i have got this working fine my issue is that when the new window is opened the image that should be on the second screen goes onto the first screen, and i cannot work out how to fix it. I dont get any errors it just puts the image in the middle of the first screen, I hope this makes sense. Thanks
The code is below: (for the second screen that should be displaying the image but isnt)
from tkinter import *
window2 = Tk()
window2.geometry("1920x1200")
Namearea = Label(window2, text = "Please Name the Prebuild: ")
Namearea.pack()
e = Entry(window2, width=50, borderwidth=3, bg="Light Grey", fg="black")
e.pack()
e.insert(0, "Remove this text and Enter the name of your prebuild: ")
# this is the part for the image
img3 = PhotoImage(file=r"C:\Tkinter\ComputerImage.png ")
picture1 = Label(image=img3)
picture1.pack()
SaveAndContinue = Button(window2, text = "Save and Return to Main Menu", padx = 75, pady = 20, bg = "Light Grey")
SaveAndContinue.pack()
LinkTitle = Label(window2, text = "Here are some links to purchase the parts from:")
Link1 = Label(window2, text = "Scorptec: www.scorptec.com.au/")
Link2 = Label(window2, text = "Centre-Com: www.centrecom.com.au/")
LinkTitle.pack()
Link1.pack()
Link2.pack()
Since you used multiple instances of Tk() (one for first window, one for second window), you need to specify the parent for picture1 and img3:
img3 = PhotoImage(master=window2, file=r"C:\Tkinter\ComputerImage.png")
picture1 = Label(window2, image=img3)
picture1.pack()
However, you should avoid using multiple instances of Tk(). Better change second instance of Tk() to Toplevel().
Hey you forgot to mention the window name in picture1 = Label(image=img3)
here is the right one the mistake
# this is the part for the image
img3 = PhotoImage(file=r"C:\\Tkinter\\ComputerImage.png ")
picture1 = Label(window2,image=img3)
picture1.pack()
And the
error error _tkinter.TclError: image "pyimage4" doesn't exist -
You have to use Toplevel() in second window
window2=Toplevel ()
It works for me
I have looked at every posting I can find, but still can't seem to fix the issue. I have a tkinter app and am trying to add radiobuttons. No matter what I try, the buttons come up with both preselected. I'd like them to appear blank.
Please help me. am trying to figure Python out and have been able to handle the screen scraping, logging into a site that tries hard to lock out applications, but can't get this detail straight. Thee code is quite long, but i think i am including the relevant section. The problem area is the last section at the bottom.
Thanks in advance for any help provided.
Create the User Name/Password Heading Area
self.heading_prompt = tk.Label(self.label_entry_frame, text='LOG `enter code here`on\ `ASSSISTANT')
self.heading_prompt.config(fg='blue', font('times',heading_font, 'bold'))
self.heading_prompt.pack(side = 'left')
self.label_entry_frame.place(x = 112, y=100)
# User credentials - prompt
self.user_name_prompt = tk.Label(self.name_entry_frame, text='Select `enter code here`User: ')
self.user_name_prompt.config(fg='green', font=('times', ``regular_font, 'bold'))
self.user_name_prompt.pack(side = 'left')
# Create Course Name Listbox
self.user_name_selected = tk.Listbox(self.name_entry_frame,width =7, `enter code here`height = 2, highlightcolor="green",selectmode = 'single', `enter code here`exportselection = "False" )
self.user_name_selected.config(fg='green', font=enter code here`enter code here`('times',regular_font, 'bold'))
self.user_name_selected.insert(1, "Margy")
self.user_name_selected.insert(2, "Steve")
self.user_name_selected.pack(side = 'left')
self.name_entry_frame.place(x=10,y=130)
# Position Cursor into User Name Listbox
self.user_name_selected.focus_set()
# User credentials - buttons
self.user_no = 0
#self.user_no.set(value = 0)
user_rb_1 = tk.Radiobutton(self.name_entry_frame, text = "Margy", variable = self.user_no, value = 1)
user_rb_1.config(fg='green', font=('times',regular_font, 'bold'))
user_rb_1.pack(side = "left")
user_rb_2 = tk.Radiobutton(self.name_entry_frame, text = "Steve", variable = self.user_no, value = 1)
user_rb_2.config(fg='green', font=('times',regular_font, 'bold'))
user_rb_2.pack(side = "left")
self.name_entry_frame.place(x=30, y=160)
The Radiobutton's variable is supposed to be a tkinter variable:
import tkinter as tk
root = tk.Tk()
user_no = tk.IntVar()
user_rb_1 = tk.Radiobutton(root, text = "Margy", variable = user_no, value = 1)
user_rb_1.pack()
user_rb_2 = tk.Radiobutton(root, text = "Steve", variable = user_no, value = 2)
user_rb_2.pack()
root.mainloop()
You can then get the value selected (1 or 2) whenever you want with user_no.get(). As long as nothing's selected it will be 0.
I am using Tkinter with Python2 to create a new window by clicking on the button. In this new window I want to Display text. Now I have Troubles with the alignment, is it possible to align it to the left? It is always centered and neither anchor=LEFT nor sticky="NSEW" help.
import tkinter as tki
btn3 = tki.Button(self.root, text="HELP", command=self.help, fg="black", bg="white", font=("Courier",22))
btn3.grid(row=1, column=2, padx=10, pady=10, sticky="NSEW" )
def help(self):
self.text = """ Hello.
You can find help here to the following subjects:
- getting started
- installation
- FAQ."""
self.top = tki.Toplevel()
self.top.title("Help")
self.label1 = tki.Label(self.top, text = self.text, height = 0, width=80, fg="black", bg="white", font=("Courier",18))
self.label1.pack()
When you use anchor = n you need to put anchor = "n" i.e. with the n in quotes. You're getting the global name is not defined error because of this.
Alternatively, use anchor = tki.N. Because you used import tkinter as tki you must prefix tkinter variables with tki. in order for python to know what you're referring to. However, I think you might want to try justify=tki.LEFT also if that doesn't work.