tags:

views:

2792

answers:

7

I've got two applications I'm developing using Qt on windows. I want the user to be able to press a button in one application which makes the other application come to the foreground. (The programs communicate using QLocalSocket / named pipes)

Currently I'm using Qt's QWidget::activateWindow() which occasionally brings the application to the foreground but most of the time it just highlights the program on the taskbar.

Can someone please tell me how to do this, preferebly using Qt although failing that using the WIN32 API would be fine.


Unfortunately I couldn't find a way to do this only with Qt. I solved it using Chris Becke's suggestion of calling SetForegroundWindow from the currently active application.

+4  A: 

On top of the QWidget::activateWindow method, you should call QWidget::raise !

This is what is said here.

PierreBdR
Your link is to a local file, the URL you should use is http://doc.trolltech.com/4.4/qwidget.html#activateWindow
Terence Simpson
A: 

SetFocus() has nothing to do here.

A: 

I think the APIs you need are AllowSetForegroundWindow() and SetForegroundWindow(). I don't know what the equivalent Qt calls are.

Ferruccio
+2  A: 

Are you sure this is not a debugging issue? The deal is, if an application HAS the foreground, it is allowed to change the foreground.

Clicking a button on window A will give that windows thread foreground activation. If it calls SetForegroundWindow (or equivalent) on the other window, that window WILL be given the foreground.

If, on the other hand, it simply sends a message to the other app, which tries to SetForeground on itself, that will fail. AllowSetForegroundWindow is used in situations where a 'legacy' app needs to be given permission - by a foreground app - to take the foreground. Once again, AllowSet... only works if called from a thread that owns the current active foreground window.

Chris Becke
Thankyou! This advice helped me with a plain Windows Forms app that needed to pass control to another instance.
andypaxo
A: 

I have similar case. I have two QT Applications A and B, which communicate on a socket. I would like to bring a window of application B up, through a button on application A.

I found that sometimes the widget state is not set correctly, so in the event() function of my applicatons B's widget I did the following:

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

I'm sending a command from application A to B. On receiving it, application B calls following function on itself:

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

This works for me, on WinXp, with QT 3.3. My MainWidget is is derived from a QWidget.

I have found this also working with widget derived from QMainWindow, but with some issue, like if some other child windows are open. For such a case I store the positiosn of the child windows and hide them, then use the BringUpWidget function to bring my MainWindow widget, and then restore the child windows.

nurxb01
A: 

use showNormal() to go from an iconified state to a visible state

A: 

This is kind of cheesy but works for me:

            this->setWindowFlags(Qt::WindowStaysOnTopHint | Qt::FramelessWindowHint);
            this->show();
            this->setWindowFlags(Qt::FramelessWindowHint);
            this->show();

Or, if you don't have other flags,

            this->setWindowFlags(Qt::WindowStaysOnTopHint);
            this->show();
            this->setWindowFlags(0);
            this->show();

Edit to explain: WindowStaysOnTopHint will almost always force the window to the foreground. Afterwards, you don't really want the window to always stay on top, so reset to whatever the previous flags were.

ctd