PySimpleGUI / PySimpleGUI

Python GUIs for Humans! PySimpleGUI is the top-rated Python application development environment. Launched in 2018 and actively developed, maintained, and supported in 2024. Transforms tkinter, Qt, WxPython, and Remi into a simple, intuitive, and fun experience for both hobbyists and expert users.
https://www.PySimpleGUI.com
Other
13.35k stars 1.84k forks source link

[Enhancement] Make PySimpleGUI (tkinter version) DPI aware.... #1179

Open murphdawg02 opened 5 years ago

murphdawg02 commented 5 years ago

Hi - my question is related to the look and feel of the GUI. I apologize in advance for not necessarily using the correct terminology to describe this question.

When I build a TKInter GUI the resolution ends up matching the screen resolution of my monitor. In other words, it looks good (albeit incredibly time consuming to create). My resolution is set to 3k by 2k. It's a surface book 2 to be exact.

When I build an application using PySimpleGui, I can't help but describing the window and everything in it as looking less than ideal (but super easy to build!). The pixels look choppy and if I look super closely I can see the text being built by groups of square pixels (I know that's literally how resolution works, but I shouldn't be able to see it on a 3k by 2k screen!). I've tried around with several different font types and sizes so I'm curious if theres something else at play here.

I appreciate any help or guidance.

Thanks

image

Derek-OM commented 5 years ago

I am currently using 2 x 4K monitors (actually two 43" 4K TVs) and the resolution looks fine. I was very pleasantly surprised that PySimpleGUI seems to be unaffected by screen resolution unlike TKinter and QT, both of which gave me problems. I ended up switching one of the TVs to 1920 x 1080 resolution so that I could see what the finished result would be for QT - the interface will appear on a mobile device hooked up to a Raspberry Pi via VNC, so I had 3 different resolutions to cope with. I know it is possible to check & adjust the program, but switching the monitor resolution was the simplest way. I was also surprised to find that an image element defined in pixels was also unaffected by different screen resolutions. PS using 2 different resolutions really confused the mouse when trying to move from one screen to the other.

murphdawg02 commented 5 years ago

Thank you for your quick response, Derek. I'm glad to hear you're not having any problem with resolution which makes me think it's something on my end, and hopefully fixable. It's interesting you bring up image resolution - I added an image to my GUI to test out the resolution, and unfortunately I get the same problem. I added a high res PNG file and it turns out like below (excuse the poor sizing).

I have played around with monitor resolution, but that 1) doesn't seem to actually help and 2) probably isn't a long term solution for me. You mentioned it's possible to check and adjust the program - what were you referring to here?

Again, much thanks to anyone.

image

Derek-OM commented 5 years ago

I ran into the resolution problem when I started trying to display something designed for 2K on 4K using tkinter and/or QT. A screen designed on (or for) 2K was unreadable on 4K as the text no longer fitted the boxes and the boxes overlapped - a total mess, not just poor resolution. After many google queries I finally found some web sites explaining how to detect the resolution of the screen doing the display and suggestions for ways around it, but it was hopelessly complicated so I just gave up. By that time I had realised that the mobile devices were just acting as dumb terminals and it would be difficult (or impossible) to detect their screen sizes anyway. The image you posted does not look too bad on a 43" 4K TV seen from 4 feet away!

MikeTheWatchGuy commented 5 years ago

Are these problems all character based?

When I build an application using PySimpleGui, I can't help but describing the window and everything in it as looking less than ideal (but super easy to build!). The pixels look choppy and if I look super closely I can see the text being built by groups of square pixels (I know that's literally how resolution works, but I shouldn't be able to see it on a 3k by 2k screen!).

Have you tried at multiple resolutions to see what you think? Some of it likely comes to down fonts, but it's the generalized the window and everything in it as looking less than ideal that makes me think this has little to do with screen resolutions and more to do with tkinter's use of graphics.

Try Qt and see what you think of that. To do that you simply install pyside2, change the import statement in your PySimpleGUI code to import PySimpleGUIQt and it should, in theory, just run and you can compare the 2 packages. Some people prefer Qt.

What about other programs running on your computer? What about other GUIs? Does everything suffer from the "looks like sh*t syndrome"? If so, then an "alpha blend" setting could be wrong. This will cause characters to look rough, stuff to look fuzzy, etc.

timkostka commented 5 years ago

For PySimpleGUI, you can make your app DPI-aware by using the following code before you load any GUI elements:

import ctypes
import platform

def make_dpi_aware():
    if int(platform.release()) >= 8:
        ctypes.windll.shcore.SetProcessDpiAwareness(True)

And running this somewhere in your code:

make_dpi_aware()

This has some unfortunate side effects like the checkbox elements being shrunk. This is an underlying limitation of Tk. Text, however, and buttons look much better with a DPI-aware application.

murphdawg02 commented 5 years ago

Tim - thank you so much! This looks much better. Checkbox elements are indeed shrunk, but I think this looks much better. I'd recommend this solution highly!

leonarduz commented 4 years ago

For PySimpleGUI, you can make your app DPI-aware by using the following code before you load any GUI elements:

import ctypes
import platform

def make_dpi_aware():
    if int(platform.release()) >= 8:
        ctypes.windll.shcore.SetProcessDpiAwareness(True)

And running this somewhere in your code:

make_dpi_aware()

This has some unfortunate side effects like the checkbox elements being shrunk. This is an underlying limitation of Tk. Text, however, and buttons look much better with a DPI-aware application.

For PySimpleGUI, you can make your app DPI-aware by using the following code before you load any GUI elements:

import ctypes
import platform

def make_dpi_aware():
    if int(platform.release()) >= 8:
        ctypes.windll.shcore.SetProcessDpiAwareness(True)

And running this somewhere in your code:

make_dpi_aware()

This has some unfortunate side effects like the checkbox elements being shrunk. This is an underlying limitation of Tk. Text, however, and buttons look much better with a DPI-aware application.

Man u are amazing! Thank you so much

PySimpleGUI commented 4 years ago

Thank you everyone for the help.

I like the fix.

I need to verify it'll all work on 3.4 (the Raspberry Pi which holds back the project from going to 3.6 at least).

Oh, and @leonarduz thank you for adding this: image

Thank yous right back at everyone that's part of this fun experiment called PySimpleGUI. The community is really awesome people. It seems unusual for the Internet to be this way, but I like it!

PySimpleGUI commented 4 years ago

I think the approach I will take on this is to provide a method for Window that you can call to make your window dpi aware. Or maybe it belongs under set_options if it's a global system-wide thing.

I don't want to turn this on by default however, but do want to give you this capability since it does seem like it's helpful and perhaps would be used by a segment of users.

Schneider1 commented 3 years ago
import ctypes
import platform

def make_dpi_aware():
    if int(platform.release()) >= 8:
        ctypes.windll.shcore.SetProcessDpiAwareness(True)

@timkostka Thank you very much for this nice solution which I am now using in a pyqtgraph application. I noticed however that it didn't work on Windows 8 (and probably fails on everything except for Win10), because the int conversion of release string fails.

Is it really necessary to support Windows versions <8? I'd rather check if we are on windows at all, since ctypes.windll will fail otherwise:

import platform
import ctypes

if platform.system() == "Windows":
    ctypes.windll.shcore.SetProcessDpiAwareness(True) # Fix Bug on Windows when using multiple screens with different scaling
timkostka commented 3 years ago

I don't use PySimpleGUI anymore, but I do set DPI awareness in my applications. I believe this works on Win7, Win8, and Win10. I don't have either of Win7 or Win8 to test it on, however.

if platform.system() == "Windows":
    if platform.release() == "7":
        ctypes.windll.user32.SetProcessDPIAware()
    elif platform.release() == "8" or platform.release() == "10":
        ctypes.windll.shcore.SetProcessDpiAwareness(1)

Might want to see what platform.release() returns on Win8 to fix it.