Необходимо вывести приложение на передний план в Windows
Вопрос
У меня есть два приложения, которые я разрабатываю с использованием Qt для Windows.Я хочу, чтобы пользователь мог нажать кнопку в одном приложении, чтобы другое приложение вышло на передний план.(Программы взаимодействуют с помощью QLocalSocket и именованных каналов.)
В настоящее время я использую QWidget::activateWindow() из Qt, который иногда выводит приложение на передний план, но большую часть времени он просто выделяет программу на панели задач.
Может кто-нибудь сказать мне, как это сделать, желательно с использованием Qt, хотя в противном случае использование WIN32 API будет в порядке.
К сожалению, я не смог найти способа сделать это только с помощью Qt.Я решил эту проблему, используя предложение Криса Беке вызвать SetForegroundWindow из активного в данный момент приложения.
Решение
Вы уверены, что это не проблема отладки?Дело в том, что если приложение ИМЕЕТ передний план, ему разрешено изменять передний план.
Нажатие кнопки в окне A приведет к активации переднего плана этого потока Windows.Если он вызывает SetForegroundWindow (или эквивалент) в другом окне, этому окну БУДЕТ предоставлен передний план.
Если, с другой стороны, оно просто отправит сообщение другому приложению, которое попытается установить Foreground на себя, это не удастся.AllowSetForegroundWindow используется в ситуациях, когда «устаревшему» приложению необходимо предоставить разрешение от приложения переднего плана на переход на передний план.Еще раз, AllowSet...работает только в том случае, если вызывается из потока, которому принадлежит текущее активное окно переднего плана.
Другие советы
На верхней части QWidget::activateWindow
метод, вам следует вызвать QWidget::raise
!
Вот что сказано здесь.
У меня аналогичный случай.
У меня есть два приложения Qt, A и B, которые обмениваются данными через сокет.Я хотел бы открыть окно приложения Б через кнопку приложения А.
Я обнаружил, что иногда состояние виджета устанавливается неправильно, поэтому в event()
функции виджета моего приложения B я сделал следующее:
bool MyWidgetB:event ( QEvent * e )
{
QEvent::Type type = e->type ();
// Somehow the correct state of window is not getting set,
// so doing it manually
if( e->type() == QEvent::Hide)
{
this->setWindowState(WindowMinimized);
}
else if( e->type() == QEvent::Show )
{
this->setWindowState((this->windowState() & ~WindowMinimized) |
WindowActive);
}
return QWidget::event(e);
}
Я отправляю команду из приложения A в приложение B.Получив его, приложение B вызывает для себя следующую функцию:
void BringUpWidget(QWidget* pWidget)
{
pWidget ->showMinimized(); // This is to bring up the window if not minimized
// but beneath some other window
pWidget ->setWindowState(Qt::WindowActive);
pWidget ->showNormal();
}
Это работает для меня, на Windows XP, с Qt 3.3.Мой MainWidget
это происходит от QWidget
.
Я обнаружил, что это также работает с виджетом, полученным из QMainWindow
, но с некоторыми проблемами.Например, если открыты какие-то другие дочерние окна.
В таком случае я сохраняю положение дочерних окон и скрываю их, а затем использую метод BringUpWidget
функция, чтобы принести мой MainWindow
виджет, а затем восстановите дочерние окна.
Это немного банально, но у меня это работает:
this->setWindowFlags(Qt::WindowStaysOnTopHint | Qt::FramelessWindowHint);
this->show();
this->setWindowFlags(Qt::FramelessWindowHint);
this->show();
Или, если у вас нет других флагов,
this->setWindowFlags(Qt::WindowStaysOnTopHint);
this->show();
this->setWindowFlags(0);
this->show();
WindowStaysOnTopHint почти всегда переводит окно на передний план.После этого вы на самом деле не хотите, чтобы окно всегда оставалось сверху, поэтому сбросьте все предыдущие флаги.
Я думаю, что API, которые вам нужны, Алловсетфореграундвиндов() и Установитьфореграундвиндов().Я не знаю, что такое эквивалентные вызовы Qt.
Используйте showNormal() для перехода из состояния значка в видимое состояние.