QT - How to know if the widget changed screens? Is there a signal? - qt

I'm still a beginner at Qt (5.15.2) and I'm trying to implement a way to setMaximumWidth of the application MainWindow based on the current screen it's on.
For example: if the application is on screen 1 (1366x768) it should have maximumWidth of 1366, if it goes to screen 2 (1920x1080), then it should have maximumWidth of 1920, and the same logic applies to a N number of screens. Is there a signal that can help me with this? If there is not, is there a good way to simulate a screen change signal?
What I tried:
I've searched for a QScreen::screenChanged signal but I couldn't find one, so I assume it doesn't exist.
I've tried using QGuiApplication::primaryScreenChanged(), but it didn't work because it only works with primary screens, so when I merely change screens the signal doesn't get activated, only if I go to windows and change the primary screen to the one I'm currently on (which is not desirable).
I've also thought of using timeout signal that would activate a function that checks the current screen and sets the maximum width, it probably would work, but it doesn't seem like a good solution performance wise.
Edit: as for what would cause the screen change, it would be the user, either by dragging the window to another screen or using shortcut keys.

Related

QInputDialog to appear in the monitor I have focus

I have a 2-monitor setup and when I spawn a QInputDialog it always spawns in the left monitor, ie the one I generally dont use that much. Is there a way to indicate to appear in the monitor I have focus without incurring in any (x,y) positioning stuff.
Basically I dont care where it appears as long as it the monitor with focus.
You can use QDesktopWidget (http://doc.qt.io/qt-5/qdesktopwidget.html) to find out which screen your MainWindow is being displayed on. This is going to be the screen with "the focus", I assume.
You then use the screen number to find out the geometry of the screen and place place the QInputDialog in the screen's center - either before the dialog is shown or right afterwards.
I'm afraid this solution is using "(x,y) positioning stuff", but if you find a way to place the dialog without it, let me know.

How to draw over everything on the screen using Qt?

The basic idea is: I would like to draw over everything on the screen.
One way I can imagine this is creating a transparent full-screen window without window controls (minimise, maximise, etc.) or borders. Then drawing into that window which is transparent. The problem I can think of is that I will be unable to control windows which are behind our transparent window.
How could I do something similar to this, without the mentioned problem? I would also like it to work on multiple operating systems if possible.
Edit:
The user will not be drawing with the mouse or other means on the screen, but will be able to continue use his desktop like normal, without that my program interferes in any way (other than the drawing on the screen). My program will only display something on the screen, which the user will be unable to interact with (at least that's the plan).
Qt 5 implements it:
QWidget w;
w.setWindowFlags(Qt::WindowTransparentForInput);
Qt 4 didn't support this functionality yet - see QTBUG-13559. The bug report had a hint on what needed to be done for Windows.
The method you describe is the one to use; a transparent full-screen window.
If you're using the left mouse button to draw, you'll need a mechanism of switching modes to be able to select items through the window and send events to the operating system.

qt: after moving window off-screen, how to move it back to default position, including default positioning behaviour?

[qt 4.8]
To get correct window dimensions including its frame, I do the following (as described e.g. here, see comment from Daniel Hedberg).
mainWindow.move(-50000, -50000);
mainWindow.show();
// do something with the window dimensions
mainWindow.move(0, 0);
mainWindow.show()
This works fine, however, I have a problem with the move(0,0) call: It makes the window always appear at position (0,0), while I would like to have the default behaviour, this is, the application only suggests to the window manager that (0,0) is a good place to position the window, and the WM might decide to shift it if necessary to avoid overlapping. In other words, I would like to switch back to Qt's default behaviour as if there weren't a call to move at all.
How can I do that?
One solution is to store Windows original position and use that. For extra safety (in case screen resolution changes), check that entire window still fits on screen and move and even resize if it does not.
A hacky alternative would be to create and open empty, possibly transparent dummy window of the same size and see where it gets positioned. Then move the original there and close the dummy one. Reading your question carefully, I think this would do what you are after.
I don't know of a Qt way to ask Window Manager to reposition the window, so if you really need that, specify the OS etc details.
Looking into the source code of Qt, I can now partially answer my own question: To convert a call to move into a suggestion for positioning instead of a request, do this:
mainWindow.move(100, 100);
mainWindow.setAttribute(Qt::WA_Moved, false);
mainWindow.show();
I've tested the code under X11 using Qt 4.8.4, and hopefully it works with on other platforms too.
Unfortunately, this doesn't solve the very problem I have, namely to use show to get the (decorated) dimensions of an off-screen window which then gets moved to the screen, calling show again. It seems that the first call to show directly sets platform-specific window manager flags which aren't completely reset and reevaluated in the second call. Actually, I'm going to think that this is a bug in Qt, so I'll report it accordingly.

Resolution handling in QMainWindow

I've a QMainWwindow, and I've fixed its size.
i.e. I've set Minimum and maximum size of the window to the same number.
Could anyone tell me whether this will be a problem if I'm to use this in another screen with a different resolution, and if so, how am I to handle it?
Kindly advise, and also if there's another way ( perhaps more elegant) to set the size of the QMainWindow.
UPDATE :
I have a QMainWindow with a QTableView as a widget, amongst others. When I expand the main Window, the tableview does not, and it leaves an ungainly blank space, so I fixed the size.
If I were to make it resizeable, how do I expand the QTableView widget, alongwith the QMainWindow. I have a Central Widget, this widget has a vertical box layout, and to this layout I've added the 3 widgets, one with QGridlayout, one horizontal line, and the other QTableView. The QTableView, on its own, is not inside a layout.
I'd imagined this would be sufficient to expand the table too, once QMainWindow were expanded, or reduced, but it doesn't happen.
How do i go about it, i.e., expanding the QTableView as well?
Thanks.
It will be a problem if you fix the size to one that is larger than the screen can handle. There are various ways to scale the size of a window according to the screen size. I recommend using QApplication::desktop(), which will return the desktop widget (you may need to #include <QDesktopWidget>. Note that this widget can actually encompass multiple screens, so if you just want the current screen, you can just do:
QRect screenGeometry = QApplication::desktop()->screenGeometry();
You could alternatively use QDesktopWidget::availableGeometry().
It is worth mentioning that among Qt users, I think there is a general dislike of fixed size windows. Most recommend taking full advantage of the Qt layout system, which provides lots of flexibility for resizing windows. I'm not saying you should definitely do this, because all projects are different, but it could be worth looking into.

Fit QML file to screen

I have created an application with a screen resolution of 640 x 360 for the nokia n8. It includes a lot of flickables, labels, etc. I want it to run on the nokia e6 with a resolution of 640 x 480.
Up to now I have simply copied the the QML file and modified it for the new resolution but it's getting a little tiresome to do it for each update. I want to know if there is any simple way I can get it to automatically fit the output to any screen resolution? Or if there is something else I can do to simplify my task. I would prefer not to use anchors because it makes it too complicated to design the QML file.
How about using QApplication::desktop()->availableGeometry() to set the geometry of your application window?
From the docs:
QDesktopWidget::availableGeometry()
Returns the available geometry of the screen with index screen. What is available will be subrect of screenGeometry() based on what the platform decides is available (for example excludes the dock and menu bar on Mac OS X, or the task bar on Windows).
Addressing your comment below:
does it re size the entire screen
The const in QDesktopWidget::availableGeometry() const tells you that you can be pretty sure that the function doesn't alter anything. You'll need to do the resizing yourself.
Edit: The QML docs should give you the information you need to automatically change your application geometry. You could either change the geometry of the QML object from C++ or define your available screen geometry as a Q_PROPERTY and access it from QML. I'd recommend the former, as hooking up to the signal QDesktopWidget::workAreaResized might help you on mobile devices where your available geometery may change.
Actually you should avoid hardcoding the interface pixel by pixel and start using anchors. Ther will be some phones that have yet another screen resolution and then you have to create new QML for each of them. With anchors you can let the content fill all available space

Resources