找到单实例Qt应用程序的QWidget

时间:2009-04-23 19:33:26

标签: c++ windows qt

我正在尝试创建单个实例Qt应用程序,我正处于这样的工作,但现在我想在启动第二个时关注已经启动的实例。 QWidget :: find(g_hWnd)应该返回小部件,但它失败并在w-> show();

上崩溃

有什么想法吗?

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

编辑:我现在看到奇趣科技在LGPL下发布了QtSingleApplication课程。

4 个答案:

答案 0 :(得分:10)

您应该使用qtsingleapplication API

编辑 - 这是针对LGPL和商业版的单独下载see here

答案 1 :(得分:2)

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

答案 2 :(得分:0)

这可能是你遇到的问题:

  

与QWidget :: winId()const

     

返回窗口系统标识符   小部件。

     

原则上是便携式的,但如果你使用的话   你可能要去做   不便携的东西。小心。

     

如果小部件是非本机的(外来的)和   winId()被调用,即该小部件   将提供原生句柄。

     

注意:我们建议您不要这样做   尽可能存储此值   在运行时更改。

Source

答案 3 :(得分:0)

我怀疑你的方法会起作用。

最好的方法仍然是运行从特定套接字侦听的本地服务器(请参阅QLocalServer)。新启动的实例将检测正在运行的服务器并且可以将同意的命令通过例如设置焦点,打开新文件等。

类似的方法是使用命名共享内存(请参阅QSharedMemory)。与之前相同,如果共享内存已经存在,则另一方可以通过发送合适的命令来控制它。