I have been developing an app for someone and we quickly realized that the app looks different between our laptops (and on my tablet its un-usable because of the ppi). I looked up what the problem was so I used starting_frame.tk.call('tk', 'scaling', factor)
to normalize the PPI across all devices. What I quickly realized, however, was the program will still be too big or too small depending on the screen ( i have a resolution set at root.geometry("1280x960")
. In order to combat all of these problems, I created the code below:
root = tk.Tk()
dpi = root.winfo_fpixels('1i')
factor = dpi / 72
width = root.winfo_screenwidth()
height = root.winfo_screenheight()
ratio_1 = width * height
ratio_2 = 1
r2_width = 4
r2_height = 3
while (ratio_1 / ratio_2) != 1.6875:
r2_height = r2_width / 1.33333333333
ratio_2 = r2_width * r2_height
r2_width = r2_width + 1
if (ratio_1/ratio_2) <= 1.6875:
break
if width + 1 == r2_width:
break
root.geometry(str(r2_width) + "x"+ str(int(r2_height)))
starting_frame = tk.Canvas(root)
factor_multiplier = (.40*factor) +.46
factor = factor/factor_multiplier
starting_frame.tk.call('tk', 'scaling', factor)
starting_frame.place(height=int(r2_height), width = r2_width)
Let me break this down:
dpi = root.winfo_fpixels('1i')
factor = dpi / 72
width = root.winfo_screenwidth()
height = root.winfo_screenheight()
this just grabs the ppi of the device and the screen res....
ratio_1 = width * height
ratio_2 = 1
r2_width = 4
r2_height = 3
while (ratio_1 / ratio_2) != 1.6875:
r2_height = r2_width / 1.33333333333
ratio_2 = r2_width * r2_height
r2_width = r2_width + 1
if (ratio_1/ratio_2) <= 1.6875:
break
if width + 1 == r2_width:
break
root.geometry(str(r2_width) + "x"+ str(int(r2_height)))
This basically takes my 16x9 display and finds a 4:3 resolution that is 88% or so the area of my screen res (i just think its a good size and is that my program is based around).
factor_multiplier = (.40*factor) +.46
factor = factor/factor_multiplier
this converts the ppi of any screen so that the size of the text and stuff is normalized across displays (I assumed a linear relation).
starting_frame.tk.call('tk', 'scaling', factor)
starting_frame.place(height=int(r2_height), width = r2_width)
this is just making a frame and stuff based on my calculated new ppi and res.
While this sorta works, and then all of my hard coded text positions are multiplied by my factor_multiplier
, it is a very sloppy and long way of doing this. please tell me there is a better way because I have been looking and I can't find anything that suits my needs.
You can the ctypes Python library. This following setting in the ctypes library sets DPI awareness.