windows 查找单实例Qt应用程序的QWidget

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/783212/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-15 12:20:49  来源:igfitidea点击:

Find QWidget of single instance Qt application

c++windowsqt

提问by corné

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

我正在尝试创建一个单实例 Qt 应用程序,我现在可以使用了,但是现在我想在启动第二个实例时关注已经启动的实例。QWidget::find(g_hWnd) 应该返回小部件,但它在 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 QtSingleApplicationclass under LGPL.

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

回答by Martin Beckett

You should use the qtsingleapplicationAPI

您应该使用qtsingleapplicationAPI

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

编辑 - LGPL 和商业版本的单独下载 请参见此处

回答by Balkrishna Talele

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

回答by Balkrishna Talele

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.

WId QWidget::winId () const

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

原则上是可移植的,但如果你使用它,你可能会做一些不可移植的事情。当心。

如果小部件是非本地的(外来的)并且在其上调用了 winId(),则将为该小部件提供一个本地句柄。

注意:我们建议您不要存储此值,因为它可能会在运行时更改。

Source

来源

回答by Ariya Hidayat

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.

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

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.

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