Python Tkinter Notebook positioning widgets using ".place" - python-3.x

I am not able to figure out why widgets are not visible when ".place" is used. It works when ".pack" is used. My GUI needs precision positioning of widgets and hence I need to use ".place". Am I doing anything wrong?
Environment: Python: 3.9.6 Windows 10 (21H1)
import tkinter as objTK
from tkinter import ttk as objTTK
root = objTK.Tk()
root.title("Tab Widget")
tabControl = objTTK.Notebook(root)
objSummaryTab = objTTK.Frame(tabControl)
objSettingsTab = objTTK.Frame(tabControl)
tabControl.add(objSummaryTab, text ='Summary')
tabControl.add(objSettingsTab, text ='Settings')
lb1 = objTTK.Label(objSummaryTab, text ="Summary")
lb1.place(x=5, y=5)
lb2 = objTTK.Label(objSettingsTab, text ="Settings")
lb2.place(x=5, y=5)
tabControl.place(x=5, y=5)
root.bind("<Escape>", lambda _: root.destroy())
root.geometry("500x500")
root.mainloop()

This error is because place() does not automatically resize the widgets, like pack() and grid() do. You need to specify width and height arguments for tabControl: tabControl = objTTK.Notebook(root, width=100, height=100), for example. In this case, width and height are in pixels.

Related

How to take screenshot by ignoring the main window in tkinter? [duplicate]

I am trying to create a translucent window in Tkinter like the one in windows 11
How to do this? If we cannot do this can we capture a part of a screen and blur it using cv2 and use it as a continuously updating background?
No, this is not directly possible with tkinter. But:
If you use PIL, you can get the location of the window, and then take a screenshot, then blur it and then make it your app background. But this wont work if user tries to move/resize the application. But here is a rough code:
from tkinter import *
from PIL import ImageTk, ImageGrab, ImageFilter # pip install Pillow
root = Tk()
root.overrideredirect(1) # Hide the titlebar etc..
bg = Canvas(root)
bg.pack(fill='both',expand=1)
root.update()
# Get required size and then add pixels to remove title bar and window shadow
left = root.winfo_rootx()
top = root.winfo_rooty()
right = left + root.winfo_width()
bottom = top + root.winfo_height()
root.withdraw() # Hide the window
img = ImageGrab.grab((left,top,right,bottom)) # Get the bg image
root.deiconify() # Show the window
img = img.filter(ImageFilter.GaussianBlur(radius=5)) # Blur it
img = ImageTk.PhotoImage(img)
bg.create_image(0,0, image=img, anchor='nw') # Show in canvas
label = Label(root,text='This is a translucent looking app')
bg.create_window(bg.winfo_width()/2,bg.winfo_height()/2,window=label) # Position in the center
root.mainloop()
Output with tkinter:
tkinter is not the best choice if you are trying to go for a modern look, use PyQt and check qtacrylic
Output with PyQt:
For live blur (native Windows blur) use "BlurWindow":
python -m pip install BlurWindow
from tkinter import *
from ctypes import windll
from BlurWindow.blurWindow import blur
root = Tk()
root.config(bg='green')
root.wm_attributes("-transparent", 'green')
root.geometry('500x400')
root.update()
hWnd = windll.user32.GetForegroundWindow()
blur(hWnd)
def color(hex):
hWnd = windll.user32.GetForegroundWindow()
blur(hWnd,hexColor=hex)
e = Entry(width=9)
e.insert(0,'#12121240')
e.pack()
b = Button(text='Apply',command=lambda:[color(e.get())])
b.pack()
root.mainloop()

Treeview Image not displaying

having problems displaying an image using treeview. Found some other mentions on the net with a similar problem but the answers do not seem to work for me. I am using Win10 if that makes a difference
import ttkthemes
import tkinter as tk
from tkinter import ttk
from tkinter.messagebox import showinfo
from tkinter import PhotoImage
from PIL import Image, ImageTk
self = tk.Tk()
self.title('Tkinter PhotoImage Demo')
#self.image = Image.open("A4.bmp")
#self.python_image = ImageTk.PhotoImage(self.image)
#print(self.python_image)
#ttk.Label(self, image=self.python_image).pack()
# columns
columns = ('#1', '#2')
tree = ttk.Treeview(self, columns=columns, show='headings', height=20)
tree.tag_configure('oddrow', background='#ece0cf')
tree.tag_configure('evenrow', background='#e0e0e0')
style = ttk.Style()
style.theme_use('clam')
style.configure("Treeview",font=(None,12))
style.configure("Treeview.Heading", font=(None, 12))
# define headings
tree.heading('#1', text='Date')
tree.column("#1", minwidth=0, width=160)
tree.heading('#2', text='Logo')
tree.column("#2", minwidth=0, width=80)
# add a scrollbar
scrollbar = ttk.Scrollbar(self, orient=tk.VERTICAL, command=tree.yview)
tree.configure(yscroll=scrollbar.set)
scrollbar.grid(row=0, column=1, sticky='ns')
tree.grid(row=0, column=0, sticky='nsew')
logo="A4.bmp"
rowcol='oddrow'
im = Image.open(logo)
ph = ImageTk.PhotoImage(im)
print(ph)
tree.insert('', -1, values=("2021-03-25", logo), image=ph, tags=(rowcol,))
tree.grid(row=0, column=0, sticky='nsew')
self.update_idletasks()
self.update()
If it helps the value of ph is: pyimage1
The commented out code at the start displays the image just fine, so the issue seems to be on adding the image itself into the tree.insert.... bit of coding
Whilst I have your attention and as related but very minor questions, is there also a way to add a second image into treeview? Plus is there a way to display some values, then an image, then some more values, then another image and finally more values, or do the images have to be at the start or end of the rows?

Tkinter Widget Size Issues

EDIT: I found the solution! My xorg settings were all wacky because I have an ultrawide monitor, and it had no idea what size (and therefore dpi) my monitor was. Explicitly setting the display and font dpi in X's settings fixed the rendering in all GUI's.
ORIGINAL:
When I run any tkinter program, many of the widgets render at around 1/2 size, especially text. Why is this happening? My window manager is Window Maker, and I'm running the latest version of Tcl/Tk.
Any help will be greatly appreciated!
My code:
import tkinter as tk
window = tk.Tk()
label = tk.Label(text="Name")
entry = tk.Entry()
button = tk.Button(text="Submit")
label.pack()
entry.pack()
button.pack()
window.mainloop()
Window manager: Window Maker 0.95.0
Tk: tk 8.6.10-2
Screenshot:
In tkinter you can only change the size of a label with the font atribute, and same goes for the text inside the button. The button size can be changed with the width and height atribute.
from tkinter import *
window = Tk()
label = Label(text="Name", font='Helvetica 15')
entry = Entry()
button = Button(text="Submit",font ='Helvetica 15', height="3", width="10")
label.pack(pady = 5) # add pady inside the pack
entry.pack()
button.pack(pady = 5)
window.mainloop()

Can't change button font size in tkinter

I can't seem to change the size of my font in tkinter! No matter which size I choose, the button text displays the same. If I deleted the whole stlye line, it's displayed smaller.
Similarly, the font always looks the same, no matter what I choose.
I want to finetune the size and the font, can you please help me=?
import tkinter
import tkinter.ttk as ttk
from tkinter import font
root = tkinter.Tk()
frame = ttk.Frame(root)
frame.grid(column=0, row=0)
style = ttk.Style(root)
ttk.Button(frame, text="Open file", command=None).grid(column=0, row=1)
ttk.Style().configure("TButton", font=font.Font(family='wasy10', size=80)) #I can choose any value here instead of "80" and any font like "Helvetica" - nothing will change
root.mainloop()
You do not need to import font. ttk style has its own font argument.
Just put the style in the first option and the font size in the 2nd option.
I would also use the variable name to edit the style. Instead of calling:
ttk.Style().configure()
Do this:
style.configure()
Take a look at the below.
import tkinter
import tkinter.ttk as ttk
root = tkinter.Tk()
frame = ttk.Frame(root)
frame.grid(column=0, row=0)
style = ttk.Style(root)
style.configure("TButton", font=('wasy10', 80))
ttk.Button(frame, text="Open file", command=None, style="TButton").grid(column=0, row=1)
root.mainloop()
On the advice of Bryan Oakley in the comments here is a 2nd option that is close to what you are trying to do with fort.
This option saves a referent to the font object and then uses it to update the style.
import tkinter
import tkinter.ttk as ttk
from tkinter import font
root = tkinter.Tk()
frame = ttk.Frame(root)
frame.grid(column=0, row=0)
style = ttk.Style(root)
font = font.Font(family="wasy10", size=80)
style.configure("TButton", font=font)
ttk.Button(frame, text="Open file", command=None, style="TButton").grid(column=0, row=1)
root.mainloop()

Bold text on tkinter canvas

How? I've tried several variations of
self.textindex = self.canvastext.create_text(0,696,font=('freemono bold',9), anchor='nw', fill='black', text='Longitude: ' + str(px))
or
self.textindex = self.canvastext.create_text(0,696,font=('bold', 'freemono bold',9), anchor='nw', fill='black', text='Longitude: ' + str(px))
etc, to either have the font type revert back to the default font or to give me errors.
I actually want some type of font that is block style font, every character has the same width, so I can setup up nice column style formatting on parts of the screen. I don't see on any programs I run, Times Roman(I think that is the right name) pop up so I'm guessing Linux Mint doesn't come standard with it:)..hence using freemono. I would stick with the default font, which is already bold, trying to format it on the screen is a lot more difficult though and I'm in kinda for the looks given how nicely this program is turning out right now.
The best way is to create a font object. For example:
# python2
import Tkinter as tk
import tkFont as tkfont
# python3
# import tkinter as tk
# from tkinter import font as tkfont
root = tk.Tk()
canvas = tk.Canvas(root, width=400, height=400, background="bisque")
canvas.pack(fill="both", expand=True)
normal_font = tkfont.Font(family="Helvetica", size=12)
bold_font = tkfont.Font(family="Helvetica", size=12, weight="bold")
canvas.create_text(50,50, text="This is normal", font=normal_font)
canvas.create_text(50,100, text="This is bold", font=bold_font)
root.mainloop()
this worked for me (Python 3):
canvas.create_text(x, y, font=('freemono', 11, 'bold'), anchor='sw', text=s)
And in addition to Bryan's answer: if you're using tkinter (as opposed to Tkinter) your code is:
from tkinter import font
...
myfont = font.Font(family='freemono', size=11, weight="bold")
canvas.create_text(x, y, font=myfont, anchor='sw', text=s)
instead of changing the weight of the letters, you could change the font of the letters by saying (font="Ariel") but with the font that is thick enough for you. Hope this helped :)

Resources