0

私は wxPython を使用しており、シングル インスタンス アプリケーションを作成しようとしています。この程度なら問題ありません。私の問題は、既存のインスタンスにコマンドを渡すことです。
したがって、アプリケーションに関連付けられているファイルをダブルクリックすると、ファイルが読み取られて表示されるとしましょう。次に例を示します。

import wx
import sys
import os
import SocketServer
import socket
import threading
class MyFrame(wx.Frame):
    def __init__(self, parent, id, title):
        wx.Frame.__init__(self, parent, id, title, wx.DefaultPosition, wx.Size(320, 350))

        getfile = os.path.abspath(sys.argv[1])
        print getfile
        fopen = open (getfile, 'r')
        fread = fopen.read()

        panel = wx.Panel(self, -1)
        wx.StaticText(panel, -1, fread, (45, 25), style=wx.ALIGN_CENTRE)
        self.Centre()
class ThreadedTCPRequestHandler(SocketServer.BaseRequestHandler):
    def handle(self):
        data = self.request.recv(1024)
        cur_thread = threading.currentThread()

        # do something with the request
        print "work"
        # could instead of the length of the input, could return error codes, more
        # information (if the request was a query), etc.  Using a length function
        # as a simple example
        response = 'string length: %d' % len(data)

        print 'responding to',data,'with',response
        self.request.send(response)
class ThreadedTCPServer(SocketServer.ThreadingMixIn, SocketServer.TCPServer):
    stopped = False
    allow_reuse_address = True

    def serve_forever(self):
        while not self.stopped:
            self.handle_request()

    def force_stop(self):
        self.server_close()
        self.stopped = True

def client(ip, port, message):
    sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
    sock.connect((ip, port))
    sock.send(message)
    response = sock.recv(1024)
    print "Received: %s" % response
    sock.close()

def start_server(host, port):

    server = ThreadedTCPServer((host, port), ThreadedTCPRequestHandler)
    ip, port = server.server_address

    # Start a thread with the server -- that thread will then start one
    # more thread for each request
    server_thread = threading.Thread(target=server.serve_forever)
    # Exit the server thread when the main thread terminates
    server_thread.setDaemon(True)
    server_thread.start()

    return server
class MyApp(wx.App):
    def OnInit(self):
        frame = MyFrame(None, -1, 'test')
        frame.Show(True)
        self.SetTopWindow(frame)
        return True

def main():
    app = MyApp(0)
    app.MainLoop()

if __name__ == '__main__':
    HOST, PORT = socket.gethostname(), 61955

    server = None
    try:
        client(HOST, PORT, ' '.join(sys.argv))
        sys.exit()
    except socket.error:
        server = start_server(HOST, PORT)
        main()

これは問題なく動作しますが、ここでは単一インスタンス アプリケーションにしたいと考えています。これを実現するにはいくつかの方法があることを私は知っています。私の場合、定義済みのポートをリッスンすることがおそらく最良の選択肢であることがわかりました。しかし、そのようなオプションを使用しても、ファイルの情報、または少なくとも名前を元のインスタンスに渡して表示する方法がわかりません。

したがって、アプリケーションは次のようになります。

  • 単一インスタンス アプリケーション。
  • ダブルクリックしたファイルを読み取ることができるはずです。
  • インスタンスがすでに開いている場合は、情報またはファイル名を元のインスタンスに渡して、ファイルのデータを自動的に更新および表示できるようにします。

また、定義されたポートをリッスンするためのコードは含めませんでした。これについてはよくわからないためです。この件に関するヘルプも大歓迎です。

編集:「定義されたポートをリッスンする」で編集されたコードは、例から取られています。実行中のインスタンスに送信することに注意してくださいprint "work"。私の状況でそれを機能させる方法がわかりません(私の無知のため)。

4

2 に答える 2

2

「単一インスタンス」アプリケーションには 2 つの部分があります。

ダブルクリックして実行を開始する「クライアント」。サーバーが実行されていない場合は、サーバーを起動します。コマンドをサーバーに渡します。そして止まる。サーバーを実行したままにします。

各クライアントによって開始される「サーバー」。「定義されたポートをリッスン」します。または、名前付きパイプから読み取ることもできます (場合によってはうまくいく場合もあります)。

サーバーが実際の作業を行います。クライアントはそれにコマンドを渡します。

于 2011-04-02T02:12:50.033 に答える
2

これが解決策です:

import wx
import sys
import os
import SocketServer
import socket
import threading
class MyFrame(wx.Frame):
    def __init__(self, parent, id, title):
        wx.Frame.__init__(self, parent, id, title, wx.DefaultPosition, wx.Size(320, 350))

        getfile = os.path.abspath(sys.argv[1])
        print getfile
        fopen = open (getfile, 'r')
        fread = fopen.read()

        panel = wx.Panel(self, -1)
        self.static = wx.StaticText(panel, -1, fread, (45, 25), style=wx.ALIGN_CENTRE)
        self.Centre()
class ThreadedTCPRequestHandler(SocketServer.BaseRequestHandler):
    def handle(self):
        data = self.request.recv(1024)
        cur_thread = threading.currentThread()

        data = data.split()
        gfile = os.path.abspath(data[-1])
        fopen = open(gfile, 'r')
        fread = fopen.read()
        self.server.app.static.SetLabel(fread)
        #Note to the self.server.app
        response = 'string length: %d' % len(data)

        print 'responding to',data,'with',response
        self.request.send(response)
class ThreadedTCPServer(SocketServer.ThreadingMixIn, SocketServer.TCPServer):
    stopped = False
    allow_reuse_address = True

    def serve_forever(self):
        while not self.stopped:
            self.handle_request()

    def force_stop(self):
        self.server_close()
        self.stopped = True

def client(ip, port, message):
    sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
    sock.connect((ip, port))
    sock.send(message)
    response = sock.recv(1024)
    print "Received: %s" % response
    sock.close()

def start_server(host, port):

    server = ThreadedTCPServer((host, port), ThreadedTCPRequestHandler)
    ip, port = server.server_address

    # Start a thread with the server -- that thread will then start one
    # more thread for each request
    server_thread = threading.Thread(target=server.serve_forever)
    # Exit the server thread when the main thread terminates
    server_thread.setDaemon(True)
    server_thread.start()

    return server
class MyApp(wx.App):
    def OnInit(self):
        frame = MyFrame(None, -1, 'test')
        frame.Show(True)
        server.app = frame
        #Note the server.app
        self.SetTopWindow(frame)
        return True

def main():
    app = MyApp(0)
    app.MainLoop()

if __name__ == '__main__':
    HOST, PORT = socket.gethostname(), 61955

    server = None
    try:
        client(HOST, PORT, ' '.join(sys.argv))
        sys.exit()
    except socket.error:
        server = start_server(HOST, PORT)
        main()

基本的に、server.app をフレームにバインドする必要がありました。

class MyApp(wx.App):
    def OnInit(self):
        frame = MyFrame(None, -1, 'test')
        frame.Show(True)
        server.app = frame
        #Note the server.app

だから私は後で呼び出すことができます:

data = self.request.recv(1024)
cur_thread = threading.currentThread()

data = data.split()
gfile = os.path.abspath(data[-1])
fopen = open(gfile, 'r')
fread = fopen.read()
self.server.app.static.SetLabel(fread)

ここで重要なのは self.server.app ですが、実行中のインスタンスにコマンドを渡す必要がありました。そして、data私のためにこれを行います。ファイル test.app を使用して既に開いているアプリケーションを開くと、データ値は次のようになります。

\pathtoyourapplication\application.py test.app

だから私はその場所をつかんで読んだ、そしてそれは私の愚かさのためにほとんど終わった.

于 2011-04-09T01:31:49.213 に答える