5

QtSolutionsのC++クラスのPythonバージョンはありQtSingleApplicationますか?

QtSingleApplicationは、アプリケーションの複数のインスタンスが同時に実行されないようにするために使用されます。

4

2 に答える 2

13

これが私自身の実装です。Python2.7およびPySide1.1でテストされています。

これは、 C++バージョンのQtSingleApplicationと本質的に同じインターフェイスを備えています。主な違いは、コンストラクターにアプリケーションの一意のIDを指定する必要があることです。(C ++バージョンは、デフォルトで実行可能ファイルへのパスを一意のIDとして使用します。実行可能ファイルはおそらくそうであるため、ここでは機能しませんpython.exe。)

from PySide.QtCore import *
from PySide.QtGui import *
from PySide.QtNetwork import *

class QtSingleApplication(QApplication):

    messageReceived = Signal(unicode)

    def __init__(self, id, *argv):

        super(QtSingleApplication, self).__init__(*argv)
        self._id = id
        self._activationWindow = None
        self._activateOnMessage = False

        # Is there another instance running?
        self._outSocket = QLocalSocket()
        self._outSocket.connectToServer(self._id)
        self._isRunning = self._outSocket.waitForConnected()

        if self._isRunning:
            # Yes, there is.
            self._outStream = QTextStream(self._outSocket)
            self._outStream.setCodec('UTF-8')
        else:
            # No, there isn't.
            self._outSocket = None
            self._outStream = None
            self._inSocket = None
            self._inStream = None
            self._server = QLocalServer()
            self._server.listen(self._id)
            self._server.newConnection.connect(self._onNewConnection)

    def isRunning(self):
        return self._isRunning

    def id(self):
        return self._id

    def activationWindow(self):
        return self._activationWindow

    def setActivationWindow(self, activationWindow, activateOnMessage = True):
        self._activationWindow = activationWindow
        self._activateOnMessage = activateOnMessage

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

    def sendMessage(self, msg):
        if not self._outStream:
            return False
        self._outStream << msg << '\n'
        self._outStream.flush()
        return self._outSocket.waitForBytesWritten()

    def _onNewConnection(self):
        if self._inSocket:
            self._inSocket.readyRead.disconnect(self._onReadyRead)
        self._inSocket = self._server.nextPendingConnection()
        if not self._inSocket:
            return
        self._inStream = QTextStream(self._inSocket)
        self._inStream.setCodec('UTF-8')
        self._inSocket.readyRead.connect(self._onReadyRead)
        if self._activateOnMessage:
            self.activateWindow()

    def _onReadyRead(self):
        while True:
            msg = self._inStream.readLine()
            if not msg: break
            self.messageReceived.emit(msg)

簡単なテストプログラムは次のとおりです。

import sys
from PySide.QtGui import *
from QtSingleApplication import QtSingleApplication

appGuid = 'F3FF80BA-BA05-4277-8063-82A6DB9245A2'
app = QtSingleApplication(appGuid, sys.argv)
if app.isRunning(): sys.exit(0)

w = QWidget()
w.show()
app.setActivationWindow(w)
sys.exit(app.exec_())
于 2012-10-03T16:02:03.327 に答える
3

このブログエントリをご覧ください。Pyside用ですが、PyQt4でも動作すると思います。

于 2012-10-03T17:04:57.647 に答える