Qt правильно разместить новое окно на экране, отцентрировать мышь, перейти на экран - PullRequest
5 голосов
/ 24 марта 2011

После многих месяцев попыток, поиска, просмотра кода и т. Д. Я не могу найти решение для правильного позиционирования нового окна в QT.В моем самом простом случае я просто хочу получить окончательный размер окна и отцентрировать его под мышью.Он будет сдвинут, чтобы гарантировать, что ни одна часть окна не находится за пределами экрана.Я не хочу, чтобы окно появлялось и затем перемещалось в такое положение, которое вызывает визуальный шум, особенно при включенном рабочем столе FX.

Проблемы, с которыми я столкнулся, не все из которых имеют правильные решения:

  1. frameGeometry не всегда заполняется до того, как окно было показано раньше.

  2. frameGeometry иногда просто совершенно неверна, особенно в Windows 7.

  3. Перед отображением невозможно узнать, будет ли применен sizeHint или size или что-то еще между ними.То есть политика размера не выглядит предсказуемой.

Обратите внимание, что я знаю, как сохранить / восстановить геометрию ранее созданного окна.Несмотря на недостатки QT и здесь, у меня есть рабочее решение.

Также обратите внимание, что я не могу использовать расположение оконного менеджера по умолчанию.Для не-MDI-приложений на установке с несколькими мониторами их расположение ужасно (часто даже не на том же мониторе, что и мышь).

Я также хотел бы избегать подклассирования всех виджетов и диалогов, простореализовать решение, так как оно не будет общим.Если это единственный возможный способ, я бы хотел рассмотреть его (если фильтры событий также не подходят).

У кого-нибудь есть хорошие работоспособные решения?

Ответы [ 3 ]

6 голосов
/ 24 марта 2011

Отредактировано , чтобы выглядеть более научным: я изменила произвольное количество вызовов на processEvents с помощью цикла, который проверяет возвращаемое значение.

Отредактировано снова: Кажется, что новая версия небезопасна: она может застрять в цикле.Поэтому я ограничил число итераций.

Оригинал:
Расскажите мне об этом.Если мне будет разрешено цитировать из моего собственного кода:

// 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) ;

Попробуйте сделать это с различными номерами вызовов на processEvents.(В этих вызовах различные вспомогательные виджеты и вспомогательные виджеты сами рекурсивно изменяют размер.)

1 голос
/ 17 декабря 2012

Что касается проблемы невозможности запросить окно о его размере до того, как оно было показано, существует простой обходной путь. Вы можете переместить окно куда-нибудь далеко за пределы экрана, прежде чем показывать его. Например, чтобы центрировать главное окно на основном экране без мерцания, я делаю следующее:

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);

Я тестировал этот код только на Windows XP и Qt 4.8.x. Надеюсь, это работает и на других платформах.

0 голосов
/ 26 августа 2011

Вы пытались активировать макет. Это заставляет его рассчитывать размеры и позиции

QLayout :: Activate ()

после этого вызова ваши виджеты должны иметь правильный размер.

...