Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

What are 'screen units' in tkinter?

I was reading the response in the link below and ran into 'screen units' but I couldn't find what exactly was referred to by 'screen units' in Jim Denney's response. I know they are not pixels.

How do I use Tkinter to create line-wrapped text that fills the width of the window?

like image 975
heretoinfinity Avatar asked Jan 20 '17 23:01

heretoinfinity


1 Answers

This is very briefly mentioned in the tkinter python documentation, though it doesn't use the phrase "screen unit":

distance Screen distances can be specified in either pixels or absolute distances. Pixels are given as numbers and absolute distances as strings, with the trailing character denoting units: c for centimetres, i for inches, m for millimetres, p for printer’s points. For example, 3.5 inches is expressed as "3.5i".

"Screen unit" is mentioned in the tcl/tk documentation. Tkinter is based on an embedded tcl/tk interpreter. Thus, the tcl/tk documentation contains the definition definition.

In some of the documentation you will find something like this:

RootX and rootY are specified in screen units (i.e. any form acceptable to Tk_GetPixels)

So, "screen units" are anything acceptable to Tk_GetPixels. The Tk_GetPixels man page says this:

These procedures take as argument a specification of distance on the screen (objPtr or string) and compute the corresponding distance either in integer pixels or floating-point millimeters. In either case, objPtr or string specifies a screen distance as a floating-point number followed by one of the following characters that indicates units:

<none> The number specifies a distance in pixels.

c The number specifies a distance in centimeters on the screen.

i The number specifies a distance in inches on the screen.

m The number specifies a distance in millimeters on the screen.

p The number specifies a distance in printer's points (1/72 inch) on the screen.

Thus, anywhere you can specify a "screen distance" you can use something like "42" (42 pixels), "42c" (42 centemeters), "42i" (42 inches), "42m" (42 millimeters), or "42p" (42 printers points).

Note that to convert these values to actual pixel values, tk will use the scaling factor, which is automatically set by the OS (sometimes incorrectly!) or by calling tk scaling. The tk scaling documentation says this:

tk scaling Sets and queries the current scaling factor used by Tk to convert between physical units (for example, points, inches, or millimeters) and pixels. The number argument is a floating point number that specifies the number of pixels per point on window's display. If the window argument is omitted, it defaults to the main window. If the number argument is omitted, the current value of the scaling factor is returned.

A “point” is a unit of measurement equal to 1/72 inch. A scaling factor of 1.0 corresponds to 1 pixel per point, which is equivalent to a standard 72 dpi monitor. A scaling factor of 1.25 would mean 1.25 pixels per point, which is the setting for a 90 dpi monitor; setting the scaling factor to 1.25 on a 72 dpi monitor would cause everything in the application to be displayed 1.25 times as large as normal. The initial value for the scaling factor is set when the application starts, based on properties of the installed monitor, but it can be changed at any time. Measurements made after the scaling factor is changed will use the new scaling factor, but it is undefined whether existing widgets will resize themselves dynamically to accommodate the new scaling factor.

There is no direct tkinter interface to tk scaling, but you can call it using the tk.call method of the root window.

For example, if you know you have a 100dpi monitor you can explicitly set the scaling factor like this:

import tkinter as tk
...
root = tk.Tk()
root.tk.call('tk', 'scaling', '-displayof', '.', 100.0/72.0)
like image 64
Bryan Oakley Avatar answered Nov 14 '22 21:11

Bryan Oakley