Tkinter loading images in the frame - python

I am using Python 2.7 and want to load a .gif logo on the Tkinter frame but there is a problem that it open two windows all the time (one empty and one with logo).
Codes:
import Tkinter
root = Toplevel()
logo = PhotoImage(file="D:\\.....\\....\\****.gif")
w1 = Label(root, compound = CENTER, image = logo).pack(side="right")
root.mainloop()
how can I have only one window with my logo?

Every tkinter app needs a Tk() window a.k.a root for other widgets to exist. If you don't create it explicitly, it will be created implicitly. Your empty window is that implicitly created Tk() window and the other one is Toplevel() you created.
So you need to change this line
root = Toplevel()
to
root = Tk()
Additionally, please keep the reference of your image.
When you add a PhotoImage or other Image object to a Tkinter widget,
you must keep your own reference to the image object. If you don’t,
the image won’t always show up.
The problem is that the Tkinter/Tk interface doesn’t handle references
to Image objects properly; the Tk widget will hold a reference to the
internal object, but Tkinter does not. When Python’s garbage collector
discards the Tkinter object, Tkinter tells Tk to release the image.
But since the image is in use by a widget, Tk doesn’t destroy it. Not
completely. It just blanks the image, making it completely
transparent…

Related

Image on Tkinter button is not showing

I don't know why the image not showing.
Is this a device problem or some update in the Tkinter library?
from tkinter import *
root = Tk()
btn = Button(master=root,image=PhotoImage(file='Sample1.png'))
btn.pack()
root.mainloop()
Sample Image:
When a PhotoImage object is garbage-collected by Python (e.g. when you return from a function which stored an image in a local variable), the image is cleared even if it’s being displayed by a Tkinter widget.
Python garbage-collects any local objects at the end of the scope, even when being used by a Tkinter widget. To prevent this, you need to assign the image to some variable:
photoimage = PhotoImage(file='Sample1.png')
btn = Button(master=root,image=photoimage)
Related: Tkinter vanishing PhotoImage issue

tkinter - LabelFrame not displaying label

I am trying to create a LabelFrame in tkinter, however the "title" of the frame is not displayed, neither is the border around the LabelFrame.
Minimal example:
import tkinter as tk
root = tk.Tk()
root.title("Test")
root.geometry("400x400")
instance = tk.Label(root, text="SCTL:").pack()
labelframe = tk.LabelFrame(root, text="Title of Frame").pack()
instance2 = tk.Label(labelframe, text="some text").pack(padx=10, pady=10)
root.mainloop()
This example will get "some text" displayed, however "Title of Frame" will not.
I am using Python 3.8.8 and tkinter 8.6.10. Does anybody have an idea how I can get the title of the frame and its border to be displayed?
Thank you in advance!
So the problem here is that you are initializing and packing the labelframe in the same line as #jasonharper pointed out -: labelframe = tk.LabelFrame(root, text="Title of Frame").pack().
Note that this does not work, since the variable labelframe does not get assigned the newly initialized labelframe object but rather the return value of the called function pack.
This means that if we write the same in two different lines, one for object initialization and the other for packing, the problem disappears. Like so -:
labelframe = tk.LabelFrame(root, text="Title of Frame") # First initialize the object and store it in the variable.
labelframe.pack() # Then use the variable to pack it.
In general also if a tkinter widget is to be used for long term in a program I suggest not packing it in the same line as it's initialization, this not only looses the newly initialized object's reference but also can cause such problems.
But the same if is temporary then can be done in one line. Here you were using the LabelFrame in the next line and thus should have separately done the packing and the initialization.

Why can I not type in my Tkinter entry field [duplicate]

tl;dr: When the application calls tkinter.filedialog, entry fields do not properly focus.
Long explanation:
When initializing a tkinter application, the entry fields are enabled by default. Their state is tk.ENABLED, they can be focused on by scrolling through fields with tab, and, most importantly, they can be clicked on to select the field.
For some reason, this behavior is broken by calling tkinter.filedialog. If a method of tkinter.filedialog is called, such as askdirectory or askopenfile(), the entry field will still have the tk.ENABLED state, and the background will be properly styled, but clicking on the entry field will not insert the cursor or select the field. Typing, of course, does not register.
This can be worked around by toggling to a different window and toggling back. However, the file dialog windows (properly) return the user directly back to the main window, and so users are always presented with a main window that appears to be locked up.
See this example:
import tkinter as tk
from tkinter import filedialog
BR8K = True
root = tk.Tk()
if BR8K:
filedialog.askdirectory()
entry = tk.Entry(root, takefocus=True, highlightthickness=2)
entry.grid(sticky="WE")
root.mainloop()
Here, the code behaves properly if BR8K is False, and incorrectly if BR8K is True.
(Note: In a production environment, this would be object oriented. The issue persists in an object oriented environment.)
This is a known issues resulting from a dialog window being called prior to the mainloop() being reached for the first time.
The simplest way to fix this is to add update_idletask() before the dialog.
Try this:
import tkinter as tk
from tkinter import filedialog
BR8K = True
root = tk.Tk()
# By adding this you avoid the focus breaking issue of calling dialog before the mainloop() has had its first loop.
root.update_idletasks()
if BR8K:
filedialog.askdirectory()
entry = tk.Entry(root, takefocus=True, highlightthickness=2)
entry.grid(sticky="WE")
root.mainloop()

Tkinter filedialog breaks entry widgets

tl;dr: When the application calls tkinter.filedialog, entry fields do not properly focus.
Long explanation:
When initializing a tkinter application, the entry fields are enabled by default. Their state is tk.ENABLED, they can be focused on by scrolling through fields with tab, and, most importantly, they can be clicked on to select the field.
For some reason, this behavior is broken by calling tkinter.filedialog. If a method of tkinter.filedialog is called, such as askdirectory or askopenfile(), the entry field will still have the tk.ENABLED state, and the background will be properly styled, but clicking on the entry field will not insert the cursor or select the field. Typing, of course, does not register.
This can be worked around by toggling to a different window and toggling back. However, the file dialog windows (properly) return the user directly back to the main window, and so users are always presented with a main window that appears to be locked up.
See this example:
import tkinter as tk
from tkinter import filedialog
BR8K = True
root = tk.Tk()
if BR8K:
filedialog.askdirectory()
entry = tk.Entry(root, takefocus=True, highlightthickness=2)
entry.grid(sticky="WE")
root.mainloop()
Here, the code behaves properly if BR8K is False, and incorrectly if BR8K is True.
(Note: In a production environment, this would be object oriented. The issue persists in an object oriented environment.)
This is a known issues resulting from a dialog window being called prior to the mainloop() being reached for the first time.
The simplest way to fix this is to add update_idletask() before the dialog.
Try this:
import tkinter as tk
from tkinter import filedialog
BR8K = True
root = tk.Tk()
# By adding this you avoid the focus breaking issue of calling dialog before the mainloop() has had its first loop.
root.update_idletasks()
if BR8K:
filedialog.askdirectory()
entry = tk.Entry(root, takefocus=True, highlightthickness=2)
entry.grid(sticky="WE")
root.mainloop()

Using TCL extensions to set native window style in Tkinter

pythonware.com/library/tkinter/introduction/…
documents a overrideredirect method
that will remove thetitlebar and
borders, if that is not enough you
must set the native window style, I'm
not sure if Tkinter gives you that
kind of low-level access, if not, try
the something like
twapi.magicsplat.com/ui.html#set_window_style
TCL extension
In an earlier post I got this as a reply on how to get a border in Tkinter similar to the one pictured below. I am not familiar with Tcl and it's extensions. So how would go about doing this? The end goal is basicaly to get the border below on a Tkinter window.
Edit :
I used the following on Windows 7 and it didn't seem to change the style. It's probably missing something. Any help would be appreciated, this could be really cool!
import string, win32ui, win32con
import Tkinter as tk
root = tk.Tk()
frame = win32ui.CreateWindowFromHandle(string.atoi(root.wm_frame(), 0))
frame.ModifyStyle(win32con.WS_CAPTION, 0, win32con.SWP_FRAMECHANGED)
root.mainloop()
You can do this using a combination of the Python win32 api packages and Tkinter. What you need to know is that a Tk window is the client section of a Win32 window. The window manager interactions are handled using a wrapper that is the parent of Tk window itself. If you have a Tkinter window 'w' then you can create a PyWin32 window for the frame or just manipulate it directly. You can get the frame hwnd using w.wm_frame() and parsing the hex string returned or by using GetParent on the winfo_id value from the Tk window (although wm_frame is likely to be more reliable).
import string, win32ui, win32con
from Tkinter import *
w = Tk()
frame = win32ui.CreateWindowFromHandle(string.atoi(w.wm_frame(), 0))
frame.ModifyStyle(win32con.WS_CAPTION, 0, win32con.SWP_FRAMECHANGED)
This removes the WS_CAPTION style and notifies the window that its frame is modified which forces a geometry recalculation so that the change propagates to the Tk child window.
EDIT ---
The following arranges to ensure we modify the window style after the window has been fully created and mapped to the display.
import string, win32ui, win32con
from Tkinter import *
def decaption(event):
w = event.widget
frame = win32ui.CreateWindowFromHandle(string.atoi(w.wm_frame(), 0))
frame.ModifyStyle(win32con.WS_CAPTION, 0, win32con.SWP_FRAMECHANGED)
w.bind("<Map>", None)
root = Tk()
root.bind("<Map>", decaption)
root.mainloop()
One solution is to draw your own border. Use overrideredirect to remove all decorations, grid/pack/place a canvas that fills the window, then draw or use bitmaps to get the visual effect you want. You'll have to add your own bindings for moving and resizing tne window, but that's not too difficult.

Categories

Resources