Qt place new window correctly on screen, center over mouse, move into screen

|▌冷眼眸甩不掉的悲伤 提交于 2019-11-30 15:03:19

Edited to look more scientific: I have changed the arbitrary number of calls to processEvents with a loop that checks the return value.

Edited again: It seems that the new version is not safe: it can get stuck in the loop. So I've put a limit in the number of iterations.

Original:
Tell me about it. If I may be permitted to quote from my own code:

// BIG PAIN: We want to get the dialog box to caluclate its own size. But there is
// no simple way to do this. The following seems to work, but only if processEvents
// is called at least twice. God knows why:
setAttribute (Qt::WA_DontShowOnScreen, true) ; // Prevent screen flicker
show() ;

QEventLoop EventLoop (this) ;
for (int i = 0 ; i < 10 ; i++)
  if (!EventLoop.processEvents()) break ;

hide() ;
setAttribute (Qt::WA_DontShowOnScreen, false) ;

int x = 99 ; // whatever
int y = 99 ; // whatever

// Make sure it fits on the screen
QRect ScreenRect = qApp -> desktop() -> availableGeometry (ApplicationData -> mainWindow) ;

if (x + frameGeometry().width() > ScreenRect.right())
  x = ScreenRect.right() - frameGeometry().width() ;
if (x < ScreenRect.x()) x = ScreenRect.x() ;

if (y + frameGeometry().height() > ScreenRect.bottom())
  y = ScreenRect.bottom() - frameGeometry().height() ;
if (y < ScreenRect.y()) y = ScreenRect.y() ;

move (x, y) ;

Try this, with varying numbers of calls to processEvents. (In these calls, the various sub-widgets and sub-sub-widgets size themselves recursively.)

Regarding the problem of not being able to query a window for its size before its been shown, there is a simple workaround. You can move the window to somewhere far outside the screen before showing it. 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.

Have you tried activating the layout. It forces it to calculate sizes and positions

QLayout::activate()

after this call, your widgets should have their correct size.

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!