How do I change the background of a Frame in Tkinter? - python

I have been creating an Email program using Tkinter, in Python 3.3.
On various sites I have been seeing that the Frame widget can get a different background using Frame.config(background="color").
However, when I use this in my Frames it gives the following error:
_tkinter.TclError: unknown option "-Background"
It does not work when doing the following:
frame = Frame(root, background="white")
Or:
frame = Frame(root)
frame.config(bg="white")
I can't figure it out.
I would post my whole source code but I dont want it exposed on the internet, but the frame creation goes something like this:
mail1 = Frame(self, relief=SUNKEN)
mail1.pack()
mail1.place(height=70, width=400, x=803, y=109)
mail1.config(Background="white")
I have tried multiple options trying to modify the background. The frame is like a wrap around an email preview for an inbox.
In case it's needed, this the way I am importing my modules:
import tkinter, time, base64, imaplib, smtplib
from imaplib import *
from tkinter import *
from tkinter.ttk import *
The following is the full traceback:
Traceback (most recent call last):
File "C:\Users\Wessel\Dropbox\Python\Main\Class Ginomail.py", line 457, in <module>
main()
File "C:\Users\Wessel\Dropbox\Python\Main\Class Ginomail.py", line 453, in main
app = Application(root) #start the application with root as the parent
File "C:\Users\Wessel\Dropbox\Python\Main\Class Ginomail.py", line 60, in __init__
self.initINBOX()
File "C:\Users\Wessel\Dropbox\Python\Main\Class Ginomail.py", line 317, in initINBOX
mail1.config(bg="white")
File "C:\Python33\lib\tkinter\__init__.py", line 1263, in configure
return self._configure('configure', cnf, kw)
File "C:\Python33\lib\tkinter\__init__.py", line 1254, in _configure
self.tk.call(_flatten((self._w, cmd)) + self._options(cnf))
_tkinter.TclError: unknown option "-bg"
Gives the following error with the code from the answer:
File "C:\Users\Wessel\Dropbox\Python\Main\Class Ginomail.py", line 317, in initINBOX
mail1 = Frame(self, relief=SUNKEN, style='myframe')
File "C:\Python33\lib\tkinter\ttk.py", line 733, in __init__
Widget.__init__(self, master, "ttk::frame", kw)
File "C:\Python33\lib\tkinter\ttk.py", line 553, in __init__
tkinter.Widget.__init__(self, master, widgetname, kw=kw)
File "C:\Python33\lib\tkinter\__init__.py", line 2075, in __init__
(widgetName, self._w) + extra + self._options(cnf))
_tkinter.TclError: Layout myframe not found
Solved! Thanks. Its the inbox bar to the right, background needed to be white.

The root of the problem is that you are unknowingly using the Frame class from the ttk package rather than from the tkinter package. The one from ttk does not support the background option.
This is the main reason why you shouldn't do wildcard imports -- you can overwrite the definition of classes and commands.
I recommend doing imports like this:
import tkinter as tk
import ttk
Then you prefix the widgets with either tk or ttk :
f1 = tk.Frame(..., bg=..., fg=...)
f2 = ttk.Frame(..., style=...)
It then becomes instantly obvious which widget you are using, at the expense of just a tiny bit more typing. If you had done this, this error in your code would never have happened.

You use ttk.Frame, bg option does not work for it. You should create style and apply it to the frame.
from tkinter import *
from tkinter.ttk import *
root = Tk()
s = Style()
s.configure('My.TFrame', background='red')
mail1 = Frame(root, style='My.TFrame')
mail1.place(height=70, width=400, x=83, y=109)
mail1.config()
root.mainloop()

Related

Python: Tkinter + MSS = mss.exception.ScreenShotError: XDefaultRootWindow() failed

I am facing a pretty strange behavior of Python MSS library when using inside Tkinter GUI.
I have a Tkinter window that has a button for popping up a TopLevel window. Inside that TopLevel window, I have a button for taking a screenshot (using MSS). Everything works as supposed for the first time, but the problem happens when I destroy (close TopLevel window) and then open it again to take another screenshot. Then it throws an exception that you will be able to see below. And this only happens when I destroy that TopLevel window and try again.
Edit: it seems the problem is somehow related to Ubuntu (using 20.04), because the problem doesn't exists on Win10.
Exception code:
Exception in Tkinter callback
Traceback (most recent call last):
File "/usr/lib/python3.8/tkinter/__init__.py", line 1892, in __call__
return self.func(*args)
File "example.py", line 10, in take_screenshot
with mss.mss() as sct:
File "/home/aivaras/Desktop/freelancing/darius/venv/lib/python3.8/site-packages/mss/factory.py", line 41, in mss
return linux.MSS(**kwargs)
File "/home/aivaras/Desktop/freelancing/darius/venv/lib/python3.8/site-packages/mss/linux.py", line 305, in __init__
self.root = self.xlib.XDefaultRootWindow(self._get_display(display))
File "/home/aivaras/Desktop/freelancing/darius/venv/lib/python3.8/site-packages/mss/linux.py", line 191, in validate
raise ScreenShotError(err, details=details)
mss.exception.ScreenShotError: XDefaultRootWindow() failed
The simplified Tkinter code:
import tkinter as tk
import mss
import mss.tools
def take_screenshot():
with mss.mss() as sct:
screen_part = {"top": 370, "left": 1090, "width": 80, "height": 390}
sct_img = sct.grab(screen_part)
mss.tools.to_png(sct_img.rgb, sct_img.size, output="./output.png")
def create_top_level_win():
top_level_win = tk.Toplevel(root)
take_screenshot_btn = tk.Button(top_level_win, text="Take screenshot", command=take_screenshot)
take_screenshot_btn.pack()
root = tk.Tk()
btn = tk.Button(root, text="Open TopLevel", command=create_top_level_win)
btn.pack()
root.mainloop()

Custom Tkinter Images

I'm trying to create a back button. I have an image called back-button.png in the folder img.
This is my code:
from tkinter import *
import customtkinter as ctk
root = Tk()
ctk.CTkLabel(root,
text = 'This is a label',
text_font =('Verdana', 17)).pack(side = LEFT, pady = 11)
img = PhotoImage(file="./img/back-button.png")
ctk.CTkButton(root, image = img).pack(side = LEFT)
root.mainloop()
When I run this code I get this error:
Traceback (most recent call last):
File "c:\Users\User\Desktop\youtube-audio-downloader\tempCodeRunnerFile.py", line 11, in <module>
ctk.CTkButton(root, image = img).pack(side = LEFT)
File "C:\Users\User\AppData\Local\Programs\Python\Python39\lib\site-packages\customtkinter\customtkinter_button.py", line 102, in __init__
self.draw()
File "C:\Users\User\AppData\Local\Programs\Python\Python39\lib\site-packages\customtkinter\customtkinter_button.py", line 147, in draw
self.canvas.configure(bg=CTkColorManager.single_color(self.bg_color, self.appearance_mode))
File "C:\Users\User\AppData\Local\Programs\Python\Python39\lib\tkinter\__init__.py", line 1646, in configure
return self._configure('configure', cnf, kw)
File "C:\Users\User\AppData\Local\Programs\Python\Python39\lib\tkinter\__init__.py", line 1636, in _configure
self.tk.call(_flatten((self._w, cmd)) + self._options(cnf))
_tkinter.TclError: unknown color name "."
So, why is this happening? And how can I display an image on a button?
The problem is that the CtkButton widget doesn't not accept parameters the same way as standard widgets. The first parameter to a CtkButton is the background color, but you're passing the root window and the root window isn't a valid color.
You need to explicitly assign the root window to the master argument.
ctk.CTkButton(master=root, image = img).pack(side = LEFT)
# ^^^^^^^
You are getting error because you are using built-in image define method which is in Tkinter not in Customtkinter. Don't confuse these two. If you want to use Customtkinter only use that because when you are making bigger projects than this, it will be a whole mess if you use these two together.
import customtkinter
from PIL import Image, ImageTk
window = customtkinter.CTk()
button_image = customtkinter.CTkImage(Image.open("assets/yourimage.png"), size=(26, 26))
image_button = customtkinter.CTkButton(master=window, text="Text will be gone if you don't use compound attribute",image=button_image)
image_button.pack()
window.mainloop()

AttributeError: 'str' object has no attribute 'tk' when running Tkinter

I was writing a python GUI program with Spleeter. And when it comes to the Separation function, the error occurs. Here's my code:
#!/usr/bin/python
# -*- coding: UTF-8 -*-
from spleeter.separator import Separator
from tkinter import *
from tkinter.ttk import *
from tkinter import messagebox
window = Tk()
screen_width,screen_height = window.maxsize()
window.title("Spleeter GUI Version")
w = int((screen_width-700)/2)
h = int((screen_height-400)/2)
window.geometry(f'700x400+{w}+{h}')
lbl = Label(window, text="File Path:")
lbl.grid(column=0, row=0)
txt = Entry(window, width=10)
txt.grid(column=1, row=0)
lbl2 = Label(window, text="Stems:")
lbl2.grid(column=0, row=1)
combo = Combobox(window)
combo['values'] = (2,4,5)
combo.current(0)
combo.grid(column=1, row=1)
def Separation():
File_name=txt.get();
stems='spleeter:'+combo.get()+'stems'
separator = Separator(stems)
separator.separate_to_file(File_name, 'out')
messagebox.showinfo("Notification", "Separation Finished!")
def clicked():
Separation()
btn = Button(window, text="Separate", command=clicked)
btn.grid(column=2, row=0)
def main():
window.mainloop()
if __name__=='__main__':
main()
And the error occurs every time I click on the Button, the message is like:
Exception in Tkinter callback
Traceback (most recent call last):
File "C:\Users\MyUsrname\.conda\envs\music\lib\tkinter\__init__.py", line 1705, in __call__
return self.func(*args)
File "d:\File\Code\python\helloworld.py", line 39, in clicked
Separation()
File "d:\File\Code\python\helloworld.py", line 33, in Separation
separator = Separator('spleeter:2stems')
File "C:\Users\MyUsrname\.conda\envs\music\lib\tkinter\ttk.py", line 1138, in __init__
Widget.__init__(self, master, "ttk::separator", kw)
File "C:\Users\MyUsrname\.conda\envs\music\lib\tkinter\ttk.py", line 559, in __init__
tkinter.Widget.__init__(self, master, widgetname, kw=kw)
File "C:\Users\MyUsrname\.conda\envs\music\lib\tkinter\__init__.py", line 2292, in __init__
BaseWidget._setup(self, master, cnf)
File "C:\Users\MyUsrname\.conda\envs\music\lib\tkinter\__init__.py", line 2262, in _setup
self.tk = master.tk
AttributeError: 'str' object has no attribute 'tk'
separator = Separator(stems)
I assume you meant spleeter.separator.Separator (from [GitHub]: deezer/spleeter - Spleeter).
But (according to traceback), you ended up using [Python.Docs]: tkinter.ttk.Separator. And, that's due to (order is important too):
from spleeter.separator import Separator
# ...
from tkinter.ttk import * # !!! THIS IS THE ONE !!!
Note that importing everything from a module is generally considered bad practice (with few exceptions, I personally consider that people using it kind of don't know what they are doing), so don't do it unless you know what it does behind the scenes.
Besides reusability and structure, packages and modules also act as (nested) namespaces, avoiding name clashes. So (most times), only import the package (or the module), and refer to classes, functions as (package.)module.function_or_class_or_variable_name
Example:
from spleeter import separator
sep = separator.Separator("a:b:c:d")
from tkinter import ttk
lbl = ttk.Label(window)

Huge error message when using .config

I'm trying to learn tkinter and am making a calculator.
I am setting up the buttons and am now trying to change the size of one of them with:
Button_back = ttk.Button(Frame1, text='Back', command=printhi) #printhi is temporary.
Button_back.grid(column=0, row=0)
Button_back.config( height = 25, width = 25 )
When I try run it the error message is:
>Traceback (most recent call last): File "C:\Users\Luuk\Python
>PGMs\tkinter\2-1 - Calculator.py", line 75, in <module>
>Button_back.config( Height = 25, width = 25 )
>File "C:\Program Files (x86)\Python34\lib\tkinter\__init__.py", line 1270, in configure
>return self._configure('configure', cnf, kw) File "C:\Program Files (x86)\Python34\lib\tkinter\__init__.py", line 1261, in
> _configure
>self.tk.call(_flatten((self._w, cmd)) + self._options(cnf))
> _tkinter.TclError: unknown option "-height"
I have no idea what I'm doing wrong here, as per every webpage this is what should handle the width and height correctly
Your answer is half right...but there is a height option for a Tkinter Button, just not a ttk Button. If you absolutely need the height option, you can still use a regular Tkinter button, it just won't be as pretty. Also, you can print the dictionary of widget options if you're ever in this bind again by printing widget.config().
import tkinter as tk
import ttk
root = tk.Tk()
tk_button = tk.Button(root, text='tkinter button')
ttk_button = ttk.Button(root, text='ttk button')
for key in tk_button.config().iterkeys():
print('tkinter: ' + key)
for key in ttk_button.config().iterkeys():
print('ttk: ' + key)
tk_button.pack()
ttk_button.pack()
root.mainloop()
There is no such thing as 'height' for a button, only width... (Also for other things probably but this is what I know for sure now)
Found this after another half hour search:
http://www-acc.kek.jp/WWW-ACC-exp/KEKB/control/Activity/Python/TkIntro/introduction/button.htm

Non top-level opengl widget in tkinter

I have a existing tkinter gui to which I would like to add a openGL widget. However, it appears that the OpenGL widget only works if it is toplevel.
This works:
from OpenGL.Tk import *
from Tkinter import *
herp=Opengl(height=100,width=100)
herp.pack()
herp.mainloop()
But this does not:
from OpenGL.Tk import *
root=Tk()
b=Opengl(root,height=100,width=100)
b.pack()
root.mainloop()
Giving me the following error:
Traceback (most recent call last):
File "\\sith\user_files\2013-Softerns\new_gui_planning\LearningOpenGL\integration_3.py", line 4, in <module>
b=Opengl(root,height=100,width=100)
File "C:\Python27_32bit\lib\site-packages\OpenGL\Tk\__init__.py", line 267, in __init__
apply(RawOpengl.__init__, (self, master, cnf), kw)
File "C:\Python27_32bit\lib\site-packages\OpenGL\Tk\__init__.py", line 216, in __init__
Widget.__init__(self, master, 'togl', cnf, kw)
File "C:\Python27_32bit\lib\lib-tk\Tkinter.py", line 2036, in __init__
(widgetName, self._w) + extra + self._options(cnf))
TclError: invalid command name "togl"
Do I need to import togl?
The only other thing I could find on this is:
http://computer-programming-forum.com/56-python/ece79da9298c54de.htm
But their solution does not work for me.
Looks like the PyOpengl wrapper for togl is using a default root window.
You should be able to get a reference to it via the master attribute
of your Opengl widget.
from Tkinter import *
from OpenGL.Tk import *
b=Opengl(height=100,width=100)
root = b.master
f = Frame(root, width=100, bg='blue')
f.pack(side='left', fill='y')
b.pack(side='right', expand=1, fill='both')
root.mainloop()
on linux i install it using those commands , then the example above are worked for me :
sudo apt update
sudo apt install togl-demos

Categories