2013-08-18 1 views
3

Я хочу, чтобы только один экземпляр моего приложения запускался в каждый момент. но когда пользователь пытается открыть его во второй раз, я хочу, чтобы первое окно было перенесено на передний план (его можно было просто свести к минимуму или свести к минимуму до угла панели задач, а пользователь не знает, как его открыть)pyqt4 - singleapplication - вывести исходное окно в попытке открыть приложение во второй раз

У меня есть этот код, который выполняет задание обнаружения, и он не позволяет второму экземпляру. У меня проблемы с частью, что он должен открыть исходное окно. Я прокомментировал некоторые из моих попыток.

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

Я сделал эту работу на Windows, с помощью Win32 API (я не совсем уверен, но, вероятно, эквивалентные вызовы на MacOS/Unix).

Добавьте следующий импорт в приложение,

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

Реальное решение Qt существует для этого как http://qt.gitorious.org/qt-solutions/qt-solutions/trees/master/qtsingleapplication. Вместо использования вызовов win32 api они создают QLocalServer. Этот класс позволяет принимать входящие локальные соединения сокетов. По сути, они прослушивают входящие соединения в этом сокете, выполняют некоторую проверку и затем принимают такие сообщения, как «принести на передний план». Похоже, что это было портировано по адресу http://stackoverflow.com/questions/8786136/pyqt-how-to-detect-and-close-ui-if-its-already-running – goran

+0

, но в этом случае я не хочу по-настоящему общаться. Я просто хочу версию qt вашей идеи. используя qt, чтобы получить вилку и снова открыть ее. Я попытался, но я не могу заставить его работать. – 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

@TatakaiWasumi Спасибо за информацию. Я использую только Qt с C++, поэтому я действительно не знаю. Я оставляю это здесь, поскольку он может быть полезен кому-то, не стесняйтесь редактировать, если найдете исправление. – Boris