This question already has answers here:
PyQt GUI size on high resolution screens
(3 answers)
Closed 3 years ago.
I've developed an application using PyQt on a computer that has a resolution of 3840x2160. I used QtDesigner to create almost all of my UI needs, then added the few other things I needed manually in python. Once I went to deploy the application, I realized that the target computer had a resolution of 1920x1080. Some widgets in the application (generally those that just had text/buttons) are fine, but once I start to get in to more complex layouts things don't appear as clearly. Specifically, QLabels and other QItems overlap each other, images are scaled disproportionately along their horizontal axis, and spacing between objects decreases. The following are a couple of images that illustrate the problem.
3480x2160 Screen (250% Scaling according to Windows Scale and Layout)
Note: This is what I see when I am developing.
3480x2160 Screen (100% Scaling according to Windows Scale and Layout)
1920x1080 Screen (100% Scaling according to Windows Scale and Layout)
I also noticed that Qt Designer itself has a similar problem when transitioning to a different screen resolution (see images attached).
High Resolution Screen - QtDesigner
Lower Resolution Screen - QtDesigner
What is the proper way to go about dealing with multiple screen resolutions in PyQt if I want to leverage QtDesigner? I know that I can retrieve the screen resolution with QDesktopWidget.screenGeometry, but is there any way to scale every parameter at once rather than manually changing each item? Will avoiding a particular "Size Policy" help at all with this?
If the issues is more with different dpi than resolution, you can tell Qt to use high dpi scaling/pixmaps by adding the following lines to your application before you create your QApplication (or any other Qt classes):
# Handle high resolution displays:
if hasattr(QtCore.Qt, 'AA_EnableHighDpiScaling'):
QtWidgets.QApplication.setAttribute(QtCore.Qt.AA_EnableHighDpiScaling, True)
if hasattr(QtCore.Qt, 'AA_UseHighDpiPixmaps'):
QtWidgets.QApplication.setAttribute(QtCore.Qt.AA_UseHighDpiPixmaps, True)
I have found that this makes my applications behave the same (or at least more similar) when switching between my laptop (high dpi, high resolution) and desktop (normal dpi, 1920x1080).
I don't use QtDesigner, so I have no idea how this suggestion plays with QtDesigner.
Related
I was wondering if there's a way to update the default window color when an image is buffering. Currently it's white.
For example, if I have a workspace open with just vscode, when I switch between workspaces there's a brief moment when the screen is white and I'd prefer the monitor be painted black while the image is buffering.
Sometime this issue also happens when moving windows around but it covers a smaller portion of the screen.
Just the color
There is a setting that may be precisely the answer to your question: change the buffer color to black (Check the section in the manual) Particularly, for i3 version 4.21, the config would be this:
client.background #000000
Getting a Composer
If that does not solve the issue, perhaps you could address it from a different perspective. i3wm is a window manager with no "composing" capability. This, among other things, sometimes produces a loss of performance in some graphical tasks, such as problems with smooth scrolling on the browser, and/or flashing colors before showing the rendering of the desktop. (In your case is white.)
So you could obtain a compositor for i3wm. Compton is an option that seems popular among the community. I haven't tried myself, but the lack of compositor may be the root of your problem. Here there is (an interesting related question) in i3wm FAQs. This is part of the answer:
i3 depends on an external application for compositing and Compton is an excellent choice if you want to improve rendering quality or apply hardware-accelerated translucency effects.
There are two issues I am aware of that affect stock compositing. One is screen tearing, which you may notice with animated effects such as Firefox's smooth scrolling. Another is a flash of partially rendered content when switching workspaces, or opening and closing windows. Using Compton should resolve those issues if it is configured correctly.
I have a kha app that runs perfecly on an iPad2 (1024/768px).
When I run the same project on a later iPad Mini with 2048/1516. My coordinates are all half the size, which kinda makes sense.
So when I double all the sizes of my objects and GFX it will work on the iPad mini, but will be too big for iPad2.
I looked into a backbuffer and a renderTarget as explained here:
https://www.youtube.com/watch?v=OV1PTo5XSCA
There is also the windowSize option in khafile, which seems to do nothing.
Surface x and y coodinates always seem to come in in real screen coodrdinates of the device.
What is the best way to write a resolution independent app?
Perfect would be a way that is either retina or non-retina, depending on the device, where the code stays the same.
According to https://github.com/Kode/Kha/wiki/Screen-Size-and-Scaling there's automated scaling for some targets. If you need other targets you have to manually scale everything to fit the screen.
The page mentions using this class for the task: https://github.com/Kode/Kha/blob/master/Sources/kha/Scaler.hx
Also you could take a look at how Wyngine does it:
https://github.com/laxa88/wyngine/search?utf8=%E2%9C%93&q=scale & https://github.com/laxa88/wyngine/blob/master/Wyngine.hx
You replied (to my comment) that scaling wasn't enough. So far it was enough for all of my games with the right display settings, but if you really need retina sized graphics you always have the option of using multiple graphics sets. Eg:
a set for retina resultion (eg iPad 3)
a default resolution (eg iPad 2) set at half retina size
a low res set for cheap android devices?
At startup of your app you check the screen size. You use that to choose the internal game size and the graphics set that fits the actual screen resolution the best. The internal game size as well as all X/Y positions for the selected graphics set can be calculated by applying the graphics sets scale factor to the raw base values.
Finally you use Scale.scale() to scale your game from the internal game size to fit devices like the iPad pro 12" and the wide variety of Android devices.
That approach is common with a lot of game engines, google should find you links like https://v-play.net/doc/vplay-different-screen-sizes/ that also explain screen ratios and how those can be handled.
Now that the new Macbook Pro is coming out with a Retina Display, there are a lot of resources out there on how to make Mac apps and now even websites "Retina Display Friendly". Even Google is updating Chrome for Retina Display...
Why is this necessary at all? From what I understand, Retina Display is just a higher resolution screen. Right?
I thought when you develop gui's for desktop software and develop websites, you are developing something that is supposed to work and scale properly with virtually any resolution... When you resize an app's window, or display it on a higher or lower resolution display, it is supposed to scale and display properly.
So why are these people coming out with guides on how to make something look good on a Retina Display? Shouldn't it already look fine by default? Is there something about Retina Display that I'm not understanding?
And for the record, I'm not talking about iPhone 4 Retina Display. Most iOS dev's make their apps with fixed position elements since they know the screen's won't change size/shape. So I understand the importance of developing an app to look good on the iPhone 4/s vs 3g/s.
With the Retina display apps don't actually scale like they're being resized, all the controls are resized to be twice as big. If an app would be scaled normally, not by scaling all the controls, etc. you wouldn't see anything, because everything would be too small. It's the same difference between a Retina and a lower-resolution display as on the iPhone 3GS / iPhone 4.
An example:
These images are actually the same size, just the pixel densities differ.
And here's how it looks not properly scaled (using some app to disable proper scaling):
http://cloudmancer.com/images/trueretina.jpg
I thought when you develop gui's for desktop software and develop websites, you are developing something that is supposed to work and scale properly with virtually any resolution... When you resize an app's window, or display it on a higher or lower resolution display, it is supposed to scale and display properly (StackOverflow, for example, uses a 960px-wide container).
From a web developer standpoint, you are often asked to develop fixed-width websites (ranging from normally 940 to 1000 pixels wide), and they don't get to scale at all. There are a lot of websites like this and many apps just aren't designed to increase in size.
Also, apps that do grow in size usually expect that a bigger resolution also means a bigger screen, so they simply stretch the main application panels and are done with it.
Now, consider static elements, like a 150x50 button that says 'Click me'. This button is not intended to become bigger and is perfectly acceptable on a regular 1440x900 display. Now the retina screen comes in with its 2580x1800 resolution. The app sees the resolution change but it thinks "Hey, that user must have a huge screen" so it keeps the button the same size.
The problem that now occurs is that the button, because both resolutions apply to the same 13" screen, is now appearing to be a fraction of the size of the original button. Depending on your user vision, he might not be able to read the text on it, and might have a hard time clicking it, depending on the mouse settings.
To fix that problem, Apple and Microsoft used two different solutions:
Microsoft decided to tell the app the display had a 2580x1800 resolutions, but that the user wanted to have everything scaled to 200 dpi. This means that, if an app does not follow the guidelines, it will look smaller. Many apps simply ignore the DPI settings (though this might change with Windows 8);
Apple decided to report to apps that the resolution of the monitor was 1440x900, but that it could display higher-resolution elements if asked to; This means that apps existing before the new retina settings will appear to be the same size as before for the end-user (with added benefits like crisper text if they use the default Apple APIs), but that they can decide to provide high-DPI images that will look much better on the display.
Both solutions requires apps to be aware that the display is high-DPI ('retina'), but the way Apple handled it means the static websites and apps mentioned earlier will keep looking just fine, except they wont have super-crisp, high-resolution images to use. And, to opt-in to the retina features, they have to provide 200x200 images for a 100x100 canvas, for example, and Apple will take care of the rest.
What is the recommended way of supporting multiple screen resolutions/aspect ratios across devices like iPad, iPhone, Windows Phones, and Android phones/tablets? Should I simply #if/#else specific code for each device? I don't know how well this would work. Especially for Android phones/tablets which come in all different sizes. Any pointers would be greatly appreciated.
Here is what we are doing for our game:
All menu or ui elements are positioned based on the screen size (we implement Horizontal and Vertical alignment)
All levels scroll, so on some devices you just see less of level of the level at a time
Our levels also zoom in on smaller devices where needed
Design fixed levels (ones that don't scroll) so that a bit of unused space is on the edges of the screen. This way it can get cropped on some devices no problem.
Make 3 sizes of images: small (3GS), medium (iPhone 4, Android, WP7, iPad), large iPad3
Position sprites/ui elements based on an images size
Take advantage of the #2x naming scheme for images
We made an iPhone-only and iPad-only version of the app, this helps in only having to put 2 sets of images in each app
Using the screen size for positioning is your best bet. Being able to center or dock to the bottom or right of the screen is also very helpful in general.
I could tell more, but I can't reveal specifics about our game yet.
I'm currently designing my first ever GUI for Windows. I'm using MFC and Visual Studio 2008. The monitor I have been designing my program on has 1680x1050 native resolution. If I compile and send my program to one of my coworkers to run on their computer (generally a laptop running at 1024x768), my program will not fit on their screen.
I have been trying to read up on how to design an MFC application so that it will run on all resolutions, but I keep finding misleading information. Everywhere I look it seems that DLUs are supposed to resize your application for you, and that the only time you should run into problems is when you have an actual bitmap whose resolution you need to worry about. But if this is the case, why will my program no longer fit on my screen when I set my monitor to a lower resolution? Instead of my program "shrinking" to take up the same amount of screen real estate that it uses at 1680x1050, it gets huge and grainy.
The "obvious" solution here is to set my resolution to 1024x768 and redesign my program to fit on the screen. Except that I've already squished everything on my dialogs as much as possible to try and get my program to fit on screen running at 1024x768. My dialog fonts are set to Microsoft Sans Serif 8 but still appear huge (much larger than 8 points) when running at 1024x768.
I know there HAS to be a way to make my program keep the same scaling... right? Or is this the wrong way to approach the problem? What is the correct/standard way to go about designing an MFC program so that it can run on many resolutions, say 800x600 and up?
I assume your application GUI is dialog based (the main window is a dialog)?
In that case you have a problem, because, as you discovered, MFC has no support for resizing a dialog correctly. Your options are:
Redesign your GUI to use a SDI or MDI GUI.
Use a dialog resize extension. There are many available, for some very good suggestions see this question. Another options are this one and this one.
Don't use MFC. wxWidgets has much better support for dialog resizing.
MFC is only a thin wrapper over the Windows API. They both make an assumption which is hardly ever true: if you have a higher resolution screen, you'll adjust the DPI or font size in Windows to get larger characters. Most of the time, a larger screen size means a larger physical monitor, or a laptop where you want to squeeze as much information into a small screen as possible; people value more information over greater detail. Thus the assumption fails.
If you can't squeeze your entire UI into the smallest size screen you need to support, you'll have to find another way to make it smaller. Without knowing anything about your UI, I might suggest using tabs to group the controls into pages.
I've had good luck making my windows resizable, so that people with larger screens can see more information at once. You need to do this the hard way, responding to the WM_SIZE message to the window and deciding which controls should be made larger and which ones should just move.
There is no automatic way to resize the content of your dialogs when resolution changes. So, you need to set some boundaries.
Option 1.
If you are developing your app for customers, pick one minimum resolution (like 1024x7678), redesign you dialogs so that everything fits. Maybe break up some into several, or use tab strip control.
Option 2.
Create separate dialog forms for each resolution you'd like to support, but use the same class to handle it. At runtime detect resolution and use the appropriate form.
Option 3.
Write your own resizing functionality, so that user could adjust the size of your dialogs to his liking.