2013-08-18 77 views
3

我只希望每次運行我的應用程序的一個實例。但是當用戶第二次嘗試打開它時,我希望將第一個窗口置於前面(可以將其最小化或最小化到任務欄的角落,並且用戶不知道如何打開它)pyqt4 - 單一應用程序 - 調出原始窗口以嘗試第二次打開應用程序

我有這個代碼做檢測工作,它不允許第二個實例。我無法打開原始窗口。我已經評論了我的一些嘗試。

import sys 
from PyQt4 import QtGui, QtCore 
import sys 

class SingleApplication(QtGui.QApplication): 
    def __init__(self, argv, key): 
     QtGui.QApplication.__init__(self, argv) 
     self._activationWindow=None 
     self._memory = QtCore.QSharedMemory(self) 
     self._memory.setKey(key) 
     if self._memory.attach(): 
      self._running = True 
     else: 
      self._running = False 
      if not self._memory.create(1): 
       raise RuntimeError(
        self._memory.errorString().toLocal8Bit().data()) 
    def isRunning(self): 
     return self._running 

    def activationWindow(self): 
     return self._activationWindow 

    def setActivationWindow(self, activationWindow): 
     self._activationWindow = activationWindow 

    def activateWindow(self): 
     if not self._activationWindow: 
      return 
     self._activationWindow.setWindowState(
      self._activationWindow.windowState() & ~QtCore.Qt.WindowMinimized) 
     self._activationWindow.raise_() 
     self._activationWindow.activateWindow() 

class Window(QtGui.QWidget): 
    def __init__(self): 
     QtGui.QWidget.__init__(self) 
     self.label = QtGui.QLabel(self) 
     self.label.setText("Hello") 
     layout = QtGui.QVBoxLayout(self) 
     layout.addWidget(self.label) 

if __name__ == '__main__': 

    key = 'random _ text' 

    app = SingleApplication(sys.argv, key) 
    if app.isRunning(): 
     #app.activateWindow() 
     sys.exit(1) 

    window = Window() 
    #app.setActivationWindow(window) 
    #print app.topLevelWidgets()[0].winId() 
    window.show() 

    sys.exit(app.exec_()) 

回答

1

我已經使用win32 API(我不完全確定,但可能在macos/unix上有相同的調用)在Windows上做這項工作。

添加以下導入到你的應用程序,

import win32gui 

設置窗口的標題,以一個固定的名稱(而不是這樣做,你可以其whndl存儲在共享內存)

window = Window() 
window.setWindowTitle('Single Application Example') 
window.show() 

然後將您的activateWindow方法更改爲如下所示:

def activateWindow(self): 
    # needs to look for a named window ... 
    whndl = win32gui.FindWindowEx(0, 0, None, "Single Application Example") 

    if whndl is 0: 
     return #couldn't find the name window ... 

    #this requests the window to come to the foreground 
    win32gui.SetForegroundWindow(whndl) 
+0

我認爲應該有這個PyQt的解決方案,將工作在不同的操作系統之間。 – Kiarash

+0

作爲http://qt.gitorious.org/qt-solutions/qt-solutions/trees/master/qtsingleapplication存在一個純粹的Qt解決方案。他們不使用win32 API調用,而是創建一個QLocalServer。這個類可以接受傳入的本地套接字連接。實質上,他們在此套接字上監聽傳入連接,進行一些驗證,然後接受諸如「帶到前面」之類的消息。它看起來像已經移植到http://stackoverflow.com/questions/8786136/pyqt-how-to-detect-and-close-ui-if-its-already-running – goran

+0

但在這種情況下,我不想要真正的溝通。我只想要你的想法的一個qt版本。使用qt來獲取wid並再次打開它。我做了嘗試,但我無法使它工作。 – Kiarash

0

你可能會被解決方案有興趣提出here

舉例來說,我會嘗試:

app = SingleApplication(sys.argv, key) 
if app.isRunning(): 
    window = app.activationWindow() 
    window.showNormal() 
    window.raise() 
    app.activateWindow() 
    sys.exit(1) 

window = Window() 
app.setActivationWindow(window) 
window.setWindowFlags(Popup) 
window.show() 
+0

此代碼根本無法在Python 2.7 – answerSeeker

+0

@Tata​​kaiWasumi感謝您的信息。我只用Qt和C++,所以我實際上不知道。我在這裏離開它,因爲它對別人可能仍然有用,如果你找到修復,隨時編輯。 – Boris

相關問題