tags:

views:

1084

answers:

4

I'm trying to create a single instance Qt application and I'm at the point this works, but now I want to focus the already started instance when a second is started. QWidget::find(g_hWnd) should return the widget but it fails and crashes on w->show();

Any thoughts?

#pragma data_seg("Shared")
HWND g_hWnd = NULL;
#pragma data_seg()
#pragma comment(linker,"/section:Shared,rws")

int main(int argc, char *argv[])
{
    if (g_hWnd)
    {
     QWidget* w = QWidget::find(g_hWnd);
     w->show();
     return 0;
    }
    else
    {
     QApplication a(argc, argv);
     mainWindow w;
     w.show();
     g_hWnd = a.topLevelWidgets().at(0)->winId(); //or w.winId()?

     return a.exec();
    }
}

edit: I now see Trolltech released the QtSingleApplication class under LGPL.

+8  A: 

You should use the qtsingleapplication API

edit- It's a separate download see here for both LGPL and Commercial editions

Martin Beckett
QtSingleApplication isn't part of any version of Qt. It's an unsupported add-on they make available out of the goodness of their hearts. You can find it here: http://www.qtsoftware.com/products/appdev/add-on-products/catalog/4/Utilities/qtsingleapplication/
Parker
Oh wow, last time I checked it was only available for the commercial edition. I love Trolltech!
corné
corne, can you update your question to reflect the QtSingleApplication statement? Thanks.
swongu
A: 

This could be the problem you're having:

WId QWidget::winId () const

Returns the window system identifier of the widget.

Portable in principle, but if you use it you are probably about to do something non-portable. Be careful.

If a widget is non-native (alien) and winId() is invoked on it, that widget will be provided a native handle.

Note: We recommend that you do not store this value as it is likely to change at run-time.

Source

Chris Cameron
A: 

I doubt your method is going to work.

The best approach is still by running a local server (see QLocalServer) that listens from a specific socket. An newly launched instance will detect the running server and can pipe agreed command to e.g. set the focus, open a new file, etc.

A similar approach is to use named shared memory (see QSharedMemory). Same like before, if the shared memory exists already, the other side can control it by sending suitable commands.

Ariya Hidayat
A: 
#include <QtGui/QApplication>
#include "mainwindow.h"
#include <QMessageBox>
#include <QSharedMemory>


int main(int argc, char *argv[])
{ 
    QApplication a(argc, argv);
     MainWindow w;

    QSharedMemory shared("61BB200D-3579-453e-9044-");
    if(shared.create(512,QSharedMemory::ReadWrite)==true)
    {
        QMessageBox msgBox;
        msgBox.setText("I am first.");
        msgBox.exec();
    }
    else
    {
        QMessageBox msgBox;
        msgBox.setText("i am already running.");
        msgBox.exec();
        exit(0);
    }
    //shared.AlreadyExists()

    w.show();
    return a.exec();
}
Balkrishna Talele