Optimising Python QT apps on retina displays - python

Qt interfaces currently look horrible on a retina display as they scale up.Its possible to use an Info.Plist for a complied application but does anyone have a solution for dynamic python such as interfaces created in PySide?

You didn't say what Qt version you're working with. Retina support is best in the latest release, Qt v5.1. but v5.0's is also pretty good. If you're still on Qt v4.8, you'll have to manually apply patches to enable high DPI.
High DPI mode is controlled by the following keys in the Info.Plist file:
<key>NSPrincipalClass</key>
<string>NSApplication</string>
<key>NSHighResolutionCapable</key>
<string>True</string>
Qt 5 uses the raster paint engine and implements high-dpi vector graphics by scaling the painter transform. If NSHighResolutionCapable is not set, the application will be rendered at the “normal” resolution which will simply be scaled up. This looks horrible on high resolution displays. On the other hand the high resolution mode is fully backwards compatible and is rendered nicely on lower resolution displays. I would leave it enabled all the time.
Once high DPI is enabled you still have to make sure that all your raster content (image resources) has a high-enough resolution to be displayed nicely. See the QT Blog post Retina display support for Mac OS, iOS and X11 for the full details.

I basically found out the solution: be sure you have QT >= 5 installed, since it has been introduced in that version, secondly I am now running python3.3.
Enjoy your retina

Related

Python PyQt6 (6.4.0) QML Difficulty in Applying Style to Qt.QWidgets

I am in the research/education phase now, and am not seeing a lot of info on the web about applying a Qml-based style to QWidgets. This implies it's difficult or not possible. I doubt it's impossible, but I am curious what the options are for doing that?
Ideally, what I want to do is use the system (user-chosen) theme in my application. I'm on Linux, and it uses GTK and GNOME for themes. I want to support Linux in general (maybe one day, other platforms), so would like to make the app theme cross-distro.
I don't know if this is a tall order. But, is it extremely involved to make PyQt6 QWidgets styled from a QML style? Can widgets use the system theme?

HIGH DPI Tkinter re scaling when I run it in Spyder and when I run it direct in terminal

this is probably not much of a coding question.
I developed an application in Tkinter which consists pretty much in a canvas where I load images on (matplots).
When I run it from Spyder or Jupyter notebook I obtain 143 DPI and when I run it directly in terminal I obtain 95 DPI instead.
The most weird thing is that once I run it from terminal it shows as if it was a 143 DPI application but when I load the image the app decides to resize completely and then change the DPI of my screen. So the whole thing resizes, buttons, pop up boxes and etc...
It is very important to me that I can run it from terminal, because afterwards I will transform it into a .exe application.
My first approach was to use the tkinter method .winfo_fpixel() and try to ratio the DPIs and multiply it to every dimension in the application.
Later I tried to find python.exe and pythonw.exe in order to change the compatibility with HIGH DPI Scale.
Do you thing there is a way to solve this without resizing everything?
I would like to insist that I'm 100% sure this has nothing to do with the code, therefore I might not post any coding samples.
Thanks.
obs: I use Windows 10
ps: I tried to run the app with two screens, what happened was really funny, when I use it on an adequate screen it runs normally, but when I slide it to the other screen and make any action/event it will resize it automatically.
selbie's answer is correct.
Also,You could use winapi to set DPI aware in python directly(this could work in tkinter):
import ctypes, tkinter
try: # >= win 8.1
ctypes.windll.shcore.SetProcessDpiAwareness(2)
except: # win 8.0 or less
ctypes.windll.user32.SetProcessDPIAware()
root = tkinter.Tk()
....
MSDN doc: SetProcessDpiAwareness, MSDN doc: SetProcessDPIAware
And this is another answer which mentioned about DPI awareness.
DPI is largely influenced by your PC's resolution settings - specifically the setting on "Scale and layout". 100% is 96 DPI and 150% is 144 DPI. I'm guessing it's just a rounding error from your app that's showing 95 and 143. Laptops tend to have higher resolution screens, so OEM's default to >100% setting so that you don't have to squint to see your apps. Whereas, your typical 1080p display defaults to 100% DPI. But when you "remote desktop" into a PC, Windows may re-adapt and re-stretch the DPI settings to match the local display if its DPI and resolution are different.
Windows will auto-scale most applications that haven't explicitly set their "DPI awareness" with the OS. That's typically fine for most application (although they can appear "blurry"). Applications can be compiled to be dpi aware are not stretched except in certain multi-monitor situations. This is especially likely for graphics applications. And that's where bugs like the one you are seeing tend to show up. You can often change this behavior by right clicking on the EXE, clicking Properties, and finding the setting the compatibility tab:
The most weird thing is that once I run it from terminal it shows as if it was a 143 DPI application but when I load the image the app decides to resize completely and then change the DPI of my screen. So the whole thing resizes, buttons, pop up boxes and etc...
When you remoted into your PC, the system DPI changed. Applications can get confused - especially if they aren't adapting to a changing DPI setting. Or worse, the application registers with Windows that it is DPI aware, but doesn't handle the corner case of when the monitor is swapped out - which is effectively what happens when you remoted into it. You can however, override this behavior with some combination of the Properties dialog above and the available APIs to control dpi-awareness.
I don't much about TKinter (Does it use the Python process or is it its own exe?). If you can compile it yourself, you can use the various Windows APIs and manifest settings to get the DPI behavior you want. My shot in the dark guess is that TKinter( is declaring itself per-monitor dpi-aware, but has a bug that doesn't account for the DPI changing on the fly. Typical fix for this situation is to just restart the application.
Everything you need to know at the links below:
https://learn.microsoft.com/en-us/windows/desktop/hidpi/high-dpi-desktop-application-development-on-windows
https://learn.microsoft.com/en-us/windows/desktop/api/shellscalingapi/nf-shellscalingapi-setprocessdpiawareness
https://msdn.microsoft.com/en-us/C9488338-D863-45DF-B5CB-7ED9B869A5E2
You can also read my previous answers regarding DPI awareness in Windows apps:
https://stackoverflow.com/search?q=user%3A104458+dpi

appearance of my GUI in several OS

I would like to check the appearance of my GUI while coding, for several OS where it should be distributed.
How can I do ?
The problem is that the ‘previsualisation’ proposed by QT Designer is very different from the appearance of the distributed release. I even have spots in tabs that appear with same font and size in ‘previsualisation’ but have different sizes on Windows... I work with: python 3.5, a GUI designed with QT Designer, developed on mac OS 10.11 and shared with Windows 7 and Windows 10 systems (installed with a recent pyinstaller)
The preview uses some approximation of the final style drawn completely by Qt, but the style used "for real" in most platform plug-ins either employs real, native widgets, or emulates them asking for theme parts straight from the machine where it's running. So, it's not possible to have a completely faithful preview unless you use a style that is always drawn completely by Qt (such as Fusion).
Long story short: to see how your application will really look on different platforms you'll have to test it "for real".
ok. For the moment, I developed a ui file for each OS and test the appearance "for real". That's awkward and, moreover, in a given ui file, some strings that have exactly the same apparent properties in Qt Designer may appear differently in the final release

PyQt5 Resize app for different displays

I am using PyQt5 and Python 3.6.4 to design a ui for a program. It was made on a 720p monitor however now using the same code on a 4k monitor, everything is tiny apart from the text. How would I go about resizing the whole app to look the same on all monitors: (720p, 1080p, 4k, etc.)
The program is to be run on windows through an executable created through compiling the python code.
Cheers
Simple 1 line fix for any who need
os.environ["QT_AUTO_SCREEN_SCALE_FACTOR"] = "1"
This is somewhat system dependent, so it would help if you mentioned your target platform(s).
Because PyQt5 is just a wrapper around Qt5, I think High DPI Displays from the Qt manual applies. Citing the relevant bit (but you should read the whole thing):
In order to get an application designed for low DPI values running on a high resolution monitors quickly, consider one of the scaling options (let the application run as DPI Unaware on Windows or set the environment variable QT_AUTO_SCREEN_SCALE_FACTOR to "1". These options may incur some scaling or painting artifacts, though.
In the longer term, the application should be adapted to run unmodified:
Always use the qreal versions of the QPainter drawing API.
Size windows and dialogs in relation to the screen size.
Replace hard-coded sizes in layouts and drawing code by values calculated from font metrics or screen size.
In a shell, you would do something like:
$ export QT_AUTO_SCREEN_SCALE_FACTOR=1
$ python my_application.py

Qt: How to render 3D animation shapes over a camera video stream?

I have a task to create an augmented reality application which has a GUI similar to this one (the overlay route and the FollowMe concept). The interesting part of the task is that the application should be done on a desktop OS (Debian/Ubuntu) with the help of the Qt framework. Python is the preferred language for the application.
So, the big difference to the aforementioned mobile app is that my application will use a USB camera plugged into a PC.
I have tried a few different approaches and none of them seems to satisfy the requirements:
this example does not work;
this solution uses a 'two layers' approach, but when I try to render the upper widget it fully covers the bottom widget;
this solution works, but it has 2 disadvantages: OpenCV's main usage is not video stream rendering (wrong tool, I guess GStreamer could fit better) and also it renders only simple 4-point shapes and it does not allow any complex polygons with holes;
I have also skimmed through the Nokia's Qt camerality source code, but it seems that this problem is solved on Symbian in a completely different way which is inapplicable on PC (embedded camera API vs a generic USB camera on PC).
I tend to think that the problem can be divided into two questions:
What is the best way to render a camera video stream in a Qt PC application?
What is the best way to overlay an animated 3D image (probably OpenGL generated) over a camera video stream in a Qt PC application?
If you are targeting a desktop I would use openGL for the whole process.
Use a quad in the background with a texture streaming the video (ie draw each video frame to the openGL texture) then render all your 3D model in openGL ontop of this.
Generaly all the video player frameworks (phonon, directshow etc) all work well as long as you ONLY want to do the simplest "show video in a box" task - as soon as you try and mix them with anything else it's harder than just drawing the images.
(Of course I may be wrong and I would love it if phonon allowed showing a video in an openGL quad with a couple of lines of code!)

Categories