Приложение для одного экземпляра - передача команд - PullRequest
0 голосов
/ 02 апреля 2011

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

Ответы [ 2 ]

2 голосов
/ 09 апреля 2011

Это решение:

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

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

2 голосов
/ 02 апреля 2011

Приложение «Один экземпляр» состоит из двух частей.

«Клиент», который дважды щелкает и запускается. Если сервер не работает, он запускает сервер. Он передает команды на сервер. И останавливается. Оставив сервер запущенным.

«Сервер», который запускается каждым клиентом. Это делает «прослушивание определенного порта». Или, возможно, чтение из именованного канала (который иногда срабатывает лучше).

Сервер выполняет реальную работу. Клиент передает ему команды.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...