unable to apply a ttk theme to .toplevel() - python-3.x

I'm trying to rcreate a slasph screen which doubles as an about screen on a menu bar in tkinter and python 3.
so far I've read I should be using a Toplevel() method on the second splash_root but It justs send me the error that, name 'Toplevel' is not defined.
Have I missed something basic here or just misunderstood how Toplevel() works?
import tkinter as tk
import tkinter.ttk as ttk
from PIL import ImageTk, Image
from ttkthemes import ThemedTk
def splash_screen():
splash_root = Toplevel(root)
splash_root.geometry("500x400")
img_title = ImageTk.PhotoImage(Image.open("art/icons/random.png"))
lbl_img_title = ttk.Label(splash_root,image=img_title)
lbl_img_title.pack(side="top",pady=20)
splash_label_by = ttk.Label(splash_root, text="name")
splash_button = ttk.Button(splash_root, text="close", command=lambda: splash_root.destroy())
splash_label_by.pack(pady=20, padx=20)
splash_button.pack(ipadx=10, ipady=10)
splash_screen()
root = ThemedTk(themebg=True)
root.set_theme('black')
root.title("splash")
root.geometry("500x500")
root.mainloop()

The answer to your question:
#Toplevel(root) is not defined
tk.Toplevel(root) #will solve your Toplevel problem.
If you call
splash_screen()
before declaring root, root will be not defined and your code still wont work.

Related

What should I do to get the first example of ttk.style working properly?

I wanted to try the ttk.Style() settings, so I copied the example from the docs at Ttk Styling and ran it. I noticed that no matter what I set the "raised" parameter to, it looks the same. Here's the code I ran:
from tkinter import ttk
import tkinter
root = tkinter.Tk()
Running Python 3.10.8
ttk.Style().configure("TButton", padding=10, relief="raised",
background="#fff")
btn = ttk.Button(text="Sample")
btn.pack()
root.mainloop()
Running this, the button looks like this:
If I change "raised" to "flat" or "sunken", it looks the same. What should I do to see the button style change?
The button doesn't know you want it to use the style defined above. Try adding style=[style_name] to to the btn definition. Here is an example below.
from tkinter import ttk
import tkinter
root = tkinter.Tk()
style=ttk.Style()
style.configure("TButton", padding=10, relief="raised",
background="#fff")
btn = ttk.Button(text="Sample", style= "TButton")
btn.pack()
root.mainloop()
Hope it helps.

Unexpected Blank Window Tkinter

A blank window along with the main window is created.
I've seen other questions but my case is different I'm not using any constructor.
The blank window appears when I initialize ttk.style.
correct_style = ttk.Style()
correct_style.configure('correct.TButton',background='#39b54a')
root = ThemedTk(theme="equilux")
If I delete these lines, the empty window doesn't appear.
I think you call the two lines before creating the instance of Tk(), something like below:
import tkinter as tk
from tkinter import ttk
correct_style = ttk.Style()
correct_style.configure('correct.TButton',background='#39b54a')
root = tk.Tk()
...
root.mainloop()
As ttk.Style() requires an instance of Tk(), if there is none, it will be created implicitly for you. So there will be two instances of Tk().
Move the two lines after creating Tk():
import tkinter as tk
from tkinter import ttk
root = tk.Tk()
correct_style = ttk.Style()
correct_style.configure('correct.TButton',background='#39b54a')
...
root.mainloop()

Import tkinter as tk does not work with text widget

I tried to create a text widget with option import tkinter as tk but I don't know why the text methods not working with my object.
If I use from tkinter import * then it is all good, but as I read this is not the recommended importing method.
So, could you please advise why first code works and the second doesn't? What am I missing?
This works:
from tkinter import *
root = Tk()
text = Text(root)
text.insert(INSERT, "Hello.....")
text.insert(END, "Bye Bye.....")
text.pack()
root.mainloop()
This doesn't:
import tkinter as tk
root = tk.Tk()
text = tk.Text(root)
text.insert(INSERT, "Hello.....")
text.insert(END, "Bye Bye.....")
text.pack()
root.mainloop()
Thanks
if you are using:
import Tkinter as tk
INSERT is a constant defined in Tkinter, so you also need to precede it with Tkinter.
you need to use INSERT like:
tk.INSERT
your code:
import tkinter as tk
root = tk.Tk()
text = tk.Text(root)
text.insert(tk.INSERT, "Hello.....")
text.insert(tk.END, "Bye Bye.....")
text.pack()
root.mainloop()
in this case if you are using :
text.insert(INSERT, "Hello.....")
you will get an error:
NameError: name 'INSERT' is not defined

python3 tkinter Entry() cannot select text field until I click outside app window once

I've written a very simple app with python3, tkinter, but am seeing some strange behaviour with Entry(). I'm new to tkinter and python.
import os
from tkinter import Tk, Entry, filedialog
class MyGUI:
def __init__(self,master):
self.master = master
self.date_entry = Entry(master)
self.date_entry.pack()
self.date_entry.insert(0,"test")
self.master.mainloop()
root = Tk()
root.directory = os.path.abspath(filedialog.askdirectory())
my_gui = MyGUI(root)
When I run this code, the second to last line is what is causing the following problem:
When I try to edit the "test" text I cannot select it (no cursor or anything). However, if I click once away from the app (e.g. desktop) I can then edit it.
Does anyone know what the problem could be?
I was wondering if it's to do with a new app window being created by the filedialog, but I couldn't find an answer.
Thanks for your replies!
After testing this odd behavior a bit it appear as though as long as you add a button to get the directory the issue goes away.
I find it odd however and I will see if I can find anything that could explain why tkinter is acting like this.
This code should work for you:
import tkinter as tk
from tkinter import filedialog
class MyGUI(tk.Tk):
def __init__(self):
tk.Tk.__init__(self)
self.date_entry = tk.Entry(self)
self.date_entry.pack()
self.date_entry.insert(0, "test")
self.directory = ""
tk.Button(self, text="Get Directory", command=self.get_directory).pack()
def get_directory(self):
self.directory = filedialog.askdirectory()
MyGUI().mainloop()
UPDATE:
I have recently learned that adding update_idletasks() before the filedialog will fix the focus issue.
Updated code:
import os
from tkinter import Tk, Entry, filedialog
class MyGUI:
def __init__(self,master):
self.master = master
self.date_entry = Entry(master)
self.date_entry.pack()
self.date_entry.insert(0,"test")
self.master.mainloop()
root = Tk()
root.update_idletasks() # fix focus issue.
root.directory = os.path.abspath(filedialog.askdirectory())
my_gui = MyGUI(root)

Trouble adding Images into a Gui using tkinter

OK so i am trying to make a program that displays an image when pressing a button, and i am having trouble getting the images into the program
this is my full code:
# Nicolas Bart
import tkinter as tk
from PIL import Image, ImageTk
from tkinter import *
window = tk.Tk()
window.title('Bad Meme Generator')
window.geometry('500x500')
window.configure(bg='saddle brown')
meme_label = tk.Label(window, text='PRESS BUTTON FOR BAD MEMES:',
fg='blue4', bg='brown4', font=('comicsans', '20'))
meme_label.grid(pady=25, padx=25, column=0, row=0)
def button_command():
meme_window = tk.Tk()
meme_window.title('I Warned You')
meme_window.grid()
image = Image.open('pexels-photo-247932.jpg')
photo = ImageTk.PhotoImage(image)
label = tk.Label(meme_window, image=photo)
label.image = photo
label.place(x = 0, y = 0)
button = tk.Button(window, text='Dont Do It!', command=button_command,
padx=100, pady=75, font=('comicsans', '20'),
bg='brown4', fg='blue4')
button.grid(column=0, row=1)
warning_label = tk.Label(window, text="Really shit tier memes incoming:",
bg='brown4', fg='blue4',
font=('comicsans', '20'))
warning_label.grid(pady=75)
window.mainloop()
every time i run this program, when i press the button to open the image, it gives the error "AttributeError: type object 'Image' has no attribute 'open'"
the specific part of the program that is giving the error is:
def button_command():
meme_window = tk.Tk()
meme_window.title('I Warned You')
meme_window.grid()
image = Image.open('pexels-photo-247932.jpg')
photo = ImageTk.PhotoImage(image)
label = tk.Label(meme_window, image=photo)
label.image = photo
label.place(x = 0, y = 0)
any help would be appreciated. Thank you :)
This is a good example of why you shouldn't do from tkinter import *. Tkinter has an Image class, so by doing this import after importing Image from PIL you overwrite the PIL class with the tkinter class.
Since you're already importing tkinter the preferred way (import tkinter as tk), you don't need to import tkinter a second time. You need to remove the statement from tkinter import *.
You also make the mistake of creating more than one instance of Tk. I don't know if it contributes to the problem or not, but it's not something you should be doing. If you need additional windows then you should create instances of Toplevel.

Resources