Besoin de mettre l'application au premier plan sous Windows
Question
Je développe deux applications utilisant Qt sur Windows. Je veux que l'utilisateur puisse appuyer sur un bouton dans une application, ce qui fait passer l'autre application au premier plan. (Les programmes communiquent à l'aide de QLocalSocket et de canaux nommés.)
Actuellement, j'utilise QWidget :: activateWindow () de Qt, qui met occasionnellement l'application au premier plan, mais la plupart du temps, il met uniquement le programme en surbrillance dans la barre des tâches.
Quelqu'un peut-il me dire comment faire cela, de préférence en utilisant Qt, bien que ne pas utiliser l’API WIN32 serait acceptable.
Malheureusement, je ne pouvais pas trouver un moyen de faire cela uniquement avec Qt. Je l'ai résolu en utilisant la suggestion de Chris Becke d'appeler SetForegroundWindow à partir de l'application actuellement active.
La solution
Êtes-vous sûr que ce n'est pas un problème de débogage? Le contrat est le suivant: si une application a l'avant-plan, elle est autorisée à changer l'avant-plan.
En cliquant sur un bouton de la fenêtre A, l'activation au premier plan de Windows est activée. Si elle appelle SetForegroundWindow (ou l’équivalent) sur l’autre fenêtre, cette fenêtre aura le premier plan.
Si, par contre, il envoie simplement un message à l'autre application, qui tente de SetForeground sur elle-même, cela échouera. AllowSetForegroundWindow est utilisé dans les situations où une application "héritée" doit être autorisée - par une application au premier plan - à prendre le premier plan. Une fois encore, AllowSet ... ne fonctionne que s’il est appelé à partir d’un thread propriétaire de la fenêtre de premier plan active actuelle.
Autres conseils
En plus de la méthode QWidget :: activateWindow
, vous devriez appeler QWidget :: raise
!
C’est ce qui est dit ici .
J'ai un cas similaire.
J'ai deux applications Qt, A et B, qui communiquent sur un socket. Je voudrais faire apparaître une fenêtre de l'application B via un bouton de l'application A.
J'ai constaté que l'état du widget n'était parfois pas défini correctement. C'est pourquoi, dans la fonction event ()
du widget de mes applications B, j'ai procédé comme suit:
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);
}
J'envoie une commande de l'application A à B. À la réception, l'application B appelle la fonction suivante sur elle-même:
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();
}
Cela fonctionne pour moi, sur Windows XP, avec Qt 3.3. Mon MainWidget
est dérivé d'un QWidget
.
J'ai constaté que cela fonctionnait également avec un widget dérivé de QMainWindow
, mais avec quelques problèmes. Comme si d’autres fenêtres enfants étaient ouvertes.
Dans ce cas, je stocke la position des fenêtres enfants et les masque, puis j'utilise la fonction BringUpWidget
pour amener mon widget MainWindow
, puis je restaure les fenêtres enfants. .
C'est un peu ringard, mais ça marche pour moi:
this->setWindowFlags(Qt::WindowStaysOnTopHint | Qt::FramelessWindowHint);
this->show();
this->setWindowFlags(Qt::FramelessWindowHint);
this->show();
Ou, si vous n'avez pas d'autres drapeaux,
this->setWindowFlags(Qt::WindowStaysOnTopHint);
this->show();
this->setWindowFlags(0);
this->show();
WindowStaysOnTopHint forcera presque toujours la fenêtre au premier plan. Par la suite, vous ne voulez pas vraiment que la fenêtre reste toujours au premier plan, alors réinitialisez-le à l’aide des drapeaux précédents.
Je pense que les API dont vous avez besoin sont AllowSetForegroundWindow () et SetForegroundWindow () . Je ne sais pas ce que sont les appels Qt équivalents.
Utilisez showNormal () pour passer d’un état iconifié à un état visible.