2009-04-23 39 views
2

我試圖創建一個實例Qt應用程序的QWidget的,我在這工作了點,但現在我想集中已經啓動的情況下,當第二個開始。 QWidget :: find(g_hWnd)應該返回小部件,但它失敗並在w-> show()上崩潰;查找單個實例的Qt應用程序

有什麼想法?

#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類。

+0

您是否嘗試過同時調試兩次,以確定第二個應用程序中的g_hWnd與第一個應用程序匹配? – GManNickG 2009-04-23 19:44:52

+0

它們不匹配,但仍檢測到已有實例正在運行。 – 2009-04-23 19:51:36

回答

0

這可能是你遇到的問題單獨下載see here

WID的QWidget :: winId()const的

返回小部件的窗口系統標識符 。

原則上便攜,但如果您使用的是 ,那麼您可能要做的事情是 ,這是非便攜式的。小心。

如果插件是非天然(外來)和 winId()被調用就可以了,該小工具 將提供一個本機句柄。

注意:我們建議您不要 存儲此值,因爲它可能會在運行時更改爲 。

Source

0

我懷疑你的方法去上班。

最好的辦法仍是通過運行一個本地服務器(見QLocalServer),採用特定的套接字監聽。新啓動的實例將檢測正在運行的服務器並且可以將同意的命令傳送給例如設置焦點,打開一個新的文件,等等

一種類似的方法是使用命名共享存儲器(見QSharedMemory)。和之前一樣,如果共享內存已經存在,另一方可以通過發送適當的命令來控制它。

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