I am using some libraries that are using tkinter, and the font is so tiny I can't read it (a few pixels only). Here is a minimum working example:
from tkinter import *
root = Tk()
myLabel = Label(root, text = 'Hello, world!')
myLabel.pack()
root.mainloop()
The working example produces the tiny hello world in the window to the right: mwe tiny font
The rest of the image is showing the gitk gui as a size reference.
Is there a way to set the default font size in tkinter without changing the code? It could also be a problem with dpi settings?
I am on Arch linux, i3wm, using the nvidia proprietary driver
Add this line to the beginning of your code. change helevicta by the font you want to use, change 20 by the font size you want to use and change bold by any formatting options you want (you don't have to include any, and if you do, you can add more than one.) This line will set the font for any labels in the root window.
root.option_add("*Label.Font", "helvetica 20 bold")
I found a workaround to my problem.
Tkinter has an automatic way to determine the monitor size and it will set a tk scale variable accordingly. In my case the scaling value does the opposite of what it is supposed to do - larger scaling value leads to smaller font size. I still don't know why that is the case.
I ran strace on my minimum working example and found out that tkinter tries to read the file ~/.Tk.tcl and I can therefore use this file as a configuration file.
Putting tk scaling 1.0 into ~/.Tk.tcl solved the problem for me. You can experiment with the scaling value to increase/decrease the overall scaling of the gui components.
Looking at strace it also tries to read ~/.Tk.py, ~/.example.tcl and ~/.example.py.
Yes you can set default font for tkinter widgets. Refer to this thread
https://stackoverflow.com/questions/15462647/modify-the-default-font-in-python-tkinter#:~:text=2%20Answers&text=Tkinter%20has%20several%20built%2Din,them%20will%20change%20as%20well.
Related
im doing an tkinter app in a computer, im using the grid() method to place the widgets. At first of the program i use this code to make the window size like the screen size:
an = self.root.winfo_screenwidth()
al = self.root.winfo_screenheight()
self.tam = '%dx%d'%(an,al)
self.root.geometry(self.tam)
And it works, but this app will be used through a remote desktop with different devices (different screen sizes).
How can I do that the widgets fill on the window like the original design? Thanks
Without any concrete examples of your code, there's no way to give more specific advice than to say that the solution is to design your program so that it resizes well.
Tkinter excels at making widgets fit, so as long as you use the options at your disposal (fill and expand for pack, row and column weights and other options for grid), and you don't hard-code any widths and heights, your GUI will easily work on a variety of systems.
Concrete pieces of advice:
don't use place except in very rare circumstances. While place supports relative positioning and sizing, it requires more work than pack and grid
design the GUI to work on the smallest display possible, and then make sure that when you manually resize the window it behaves properly
When using grid, make sure you always have at least one row and one column with a non-zero weight so that it knows how to allocate extra space
When using pack make sure you use expand and fill properly
Don't turn off the ability for the user to resize the window
import tkinter as tk
import ctypes
ctypes.windll.shcore.SetProcessDpiAwareness(1)
root = tk.Tk()
root.geometry("200x150")
label = tk.Label(root, text = "Hello World")
label.pack(padx = 5, pady = 5)
root.mainloop()
As you can see the difference between both the windows but the quality is enhanced, now how can I get the resolution as before without changing it using geometry attribute?
In Windows and others, exist an option to change the Scaling size, 100% by default, to improve the usability in smaller screens with high resolution, mostly laptops:
Display settings in Windows
This setting changes the size of each element including all windows frames, not only Tk. The best wave is to increase the window resolution. But if you are looking to rescale in base this windows settings, will be harder.
I recommend checking about win32con, pywintypes, win32api. Also this another question:
How can I change Windows 10 Display Scaling Programmatically using C#
windll.shcore.SetProcessDpiAwareness(1) will change the windows resolution, including the menu size text, at least your screen settings are on 100%. Is good to recommend using this to change only inside elements, but it will not change the window size:
root.tk.call('tk', 'scaling', 1.0)
Searching for the best way to clear the Tkinter icon, I found Removing the TK icon on a Tkinter window. But all the answers given there seemed unsatisfactory to me: I wished to do it in a platform-independent way, without additional files and without (compressed) inline data.
However, the solution I found – and that's why I didn't post this a an answer – has a small flaw that I would like to understand.
import tkinter as tk
from PIL import Image, ImageTk
root = tk.Tk()
photo = ImageTk.PhotoImage(Image.new('RGBA', (1,1), (0,0,0,1)))
root.iconphoto(False, photo)
root.mainloop()
The alpha value I'm using here is 1 instead of 0, so there is no full transparency even if probably no one will be able to see the difference. If I use 0 to get full transparency as documented, a small black square (larger than 1x1) is shown instead.
I wasn't able to find any information about what causes this strange (but maybe acceptable?) behavior. And so I would be happy if any of you could give me an explanation.
A Tkinter Checkbutton widget can have a text or an image/bitmap. When using text the width and height configurations of the widget refer to characters, rather than pixels, but when using an image/bitmap they refer to pixels. I'm using a Checkbutton widget with no image nor text - just a plain checkbox. Is there a simple way to have it sized in pixels?
Note: I am familiar with the hack of wrapping it in a Frame, but am hoping this is avoidable here, as the widget itself does support by-pixel sizing.
If there's no simple way of instructing the widget to use "image mode" in these circumstances, what's a simple way of feeding it an empty bitmap (if that would at all work)?
In case it matters: I'm using Python 3.4.3 on Ubuntu 15.04.
Give it a 1x1 image (one pixel wide, one pixel tall). That will cause the size attribute to be based on pixels, and the image you give it will be virtually invisible.
import tkinter as tk
...
img = tk.PhotoImage(width=1, height=1)
cb = tk.Checkbutton(root, width=40, height=40)
...
I’m writing a cross-platform text parser that, among other things, word wraps text so that another cross-platform program (which I don’t control) can properly render the text in a variable-length font. Word wrapping requires getting the pixel-width of the text, but width varies depending on which OS I run my program on. The following code, for example, says the word "Wings" has length 31 on OS X 10.10, but on Windows XP, it says 30.
from Tkinter import Tk
import tkFont
root = Tk()
font = tkFont.Font(family="Times New Roman", size=-12)
# Note the negative value of size, showing the font size is the same.
print font.measure("Wings”)
This means that text wrapped on one platform won’t be displayed properly when the other program is run on the other platform. If I word wrap on XP and display on OS X, the text that I wrapped assuming it was 30 pixels is now 31 pixels. That one extra pixel could cause an error in how the wrapped text displays on the other program, and that was from just one word. Longer words cause more pixel differences, which makes the word wrapper less accurate.
I’m aware that the Tkinter widths should be different because the different OS's render the font differently. Since the font I’m using in my actual program is wider in Windows than OS X, I’d like to have Tkinter use the Windows measurement, even if I’m on OS X. This seems to be the only way to get a cross-platform font measurement that doesn’t risk word wrapping too late. How can I go about doing this? If I can’t, how else could I get a cross-platform width measurement that's consistent, reasonably accurate, and not too small?
EDIT:
The program that reads the output of my program expects a string of text for it to display, and I cannot control how it displays it, or convince it to accept an image. The only thing I can control is that string.