How to get the width of a window frame, before creating any windows?
EDIT: this app will run on Windows, Mac, and various Linux distros. I'm aware Linux has issues with this, but what about Windows? Mac?
Is there any way to get the width of the frame for a normal window, PRIOR to showing any windows? After showing a window, I know I can subtract the size()
from the frameSize()
, but that doesn't work until after the window is shown.
I've looked at QApplication::style()->pixelMetric()
, and I can get the height of the title bar using
QApplication::style()->pixelMetric(QStyle::PM_TitleBarHeight)
but I don't see any options to get the width of the rest of the border around the window.
The only solution I've found so far is to:
- set the window opacity to 0 (so the user doesn't see it),
- show the window
- then subtract
size()
fromframeSize()
Is there a better way?
Solution 1:
I posted a suggested solution in a different question at StackOverflow, but I'll post it here as well. You can move the window to somewhere far outside the screen before showing it and then query it for its geometry, and finally move it to where you want it (if that is what you need the geometry for). For instance to center a main window on the primary screen without flickering I do the following:
MainWindow mainWindow;
QRect primaryScreenGeometry(QApplication::desktop()->screenGeometry());
mainWindow.move(-50000,-50000);
mainWindow.show();
mainWindow.move((primaryScreenGeometry.width() - mainWindow.width()) / 2.0,
(primaryScreenGeometry.height() - mainWindow.height()) / 2.0);
I've only tested this code on Windows XP and Qt 4.8.x. Hopefully it works on other platforms as well.
Solution 2:
In case you haven't seen it, the Qt doc page Window and Dialog Widgets contains a lot of information about this.
You don't say what platform you are running on, but it it's X11, the answer seems to be 'No', there isn't a better way:
X11 Peculiarities
On X11, a window does not have a frame until the window manager decorates it. This happens asynchronously at some point in time after calling QWidget::show() and the first paint event the window receives, or it does not happen at all. Bear in mind that X11 is policy-free (others call it flexible). Thus you cannot make any safe assumption about the decoration frame your window will get. Basic rule: There's always one user who uses a window manager that breaks your assumption, and who will complain to you.
(I like your workaround of setting the opacity to 0: neat!)