MS Word-like multi document application

Plattformunabhängige GUIs mit wxWidgets.
Antworten
tommy_3
User
Beiträge: 6
Registriert: Dienstag 29. Juli 2008, 23:10

Hallo Leute,

ich möchte eine WinXP-Applikation mittels wxPython erstellen die mehrere Projekte gleichzeitig in unterschiedlichen Frames darstellen kann. Genau wie in Word sollen beim öffnen einer Datei, die Daten in einem neuen Frame dargestellt werden (Frame ist immer dieselbe Klasse; kein MDI wie z.B. In Excel!). Soweit so gut.
Nun stehe ich allerdings vor dem folgenden Problem. Wie kann ich bewerkstelligen, dass bei einem Doppelklick auf eine Datei im Explorer (Dateien sind mit meiner Applikation verknüpft; py2exe) diese Datei in meiner bereits laufenden Applikation geöffnet wird und nicht als neuer Prozess (Task).
Ich habe etwas mit dem Python package win32 herumexperimentiert und kann immerhin schon den laufenden Prozess finden. Besteht die Möglichkeit der Applikation Werte zu übergeben?
Mein Ziel ist es in der laufenden Applikation einen Event zu generieren wobei als Wert der Pfad der Datei übergeben wird. Weiters ist mir in den Sinn gekommen Python socket zu verwenden, alledings fehlt hier die Unterstützung für wxPython unter Windows. Oder?

Wenn mir jemand bei diesem Problem weiterhelfen könnte wäre ich sehr dankbar! Vor allem würde ich mich über ein Beispielprogramm freuen.

Vorab vielen Dank für Eure Antworten!
Tommy
Leonidas
Python-Forum Veteran
Beiträge: 16025
Registriert: Freitag 20. Juni 2003, 16:30
Kontaktdaten:

tommy_3 hat geschrieben:Mein Ziel ist es in der laufenden Applikation einen Event zu generieren wobei als Wert der Pfad der Datei übergeben wird. Weiters ist mir in den Sinn gekommen Python socket zu verwenden, alledings fehlt hier die Unterstützung für wxPython unter Windows. Oder?
Nein, warum sollte es fehlen. Auch wenn du wxPython verwendest, kannst du allerhand RPC-Mechanismen verwenden, womöglich kannst du auch einen COM-Server bieten, so wie Word selbst.
My god, it's full of CARs! | Leonidasvoice vs (former) Modvoice
tommy_3
User
Beiträge: 6
Registriert: Dienstag 29. Juli 2008, 23:10

Vielen Dank für Deine Antwort!
Das Schlagwort 'RPC' hat mir gefehlt. Ich werde googeln und sehen ob ich Beispielcode finden kann.
Mit der fehlenden Unterstützung meinte ich übrigens wxSocket für Windows. Python socket funktioniert natürlich aber ich müsste mich selber um die Event-Generierung kümmern.

Schöne Grüße,
Tommy
tommy_3
User
Beiträge: 6
Registriert: Dienstag 29. Juli 2008, 23:10

Hallo Leute,

ich habe eine Lösung gefunden die für mich einwandfrei funktioniert und die ich Euch nicht vorenthalten möchte.

Die Lösung basiert auf Python socket. In einem Thread der im Hintergrund läuft lese ich die Daten vom socket ein generiere einen wxEvent sobald etwas empfangen wird.
Der code für das Hauptprogramm (Server) sieht wie folgt aus:

Code: Alles auswählen

import  thread
from socket import *
import  wx
import  wx.lib.newevent

host = "localhost"
port = 21567
buf = 1024
addr = (host,port)

(SocketStreamEvent, EVT_SOCKET) = wx.lib.newevent.NewEvent()

class SocketThread:
    def __init__(self, win):
        self.win = win
        self.UDPSock = socket(AF_INET,SOCK_DGRAM)
        self.UDPSock.bind(addr)

    def Start(self):
        self.keepGoing = self.running = True
        thread.start_new_thread(self.Run, ())

    def Stop(self):
        self.keepGoing = False
        
    def Clear(self):
        self.UDPSock.close()

    def IsRunning(self):
        return self.running

    def Run(self):
        while self.keepGoing:
            data,addr = self.UDPSock.recvfrom(buf)
            if data:
                evt = SocketStreamEvent(stream = data)
                wx.PostEvent(self.win, evt)
        self.running = False

class TestFrame(wx.Frame):
    def __init__(self, *args, **kwds):
        wx.Frame.__init__(self, *args, **kwds)
        self.Show()
        thread = SocketThread(self)
        thread.Start()
        self.Bind(EVT_SOCKET, self.OnUpdate)

    def OnUpdate(self, evt):
        print evt.stream

class thread_test(wx.App):
    def OnInit(self):
        frame = TestFrame(None)
        self.SetTopWindow(frame)
        return True

app = thread_test(0)
app.MainLoop()

Der Code für einen Client zum Testen:

Code: Alles auswählen

from socket import *

host = "localhost"
port = 21567
buf = 1024
addr = (host,port)

UDPSock = socket(AF_INET,SOCK_DGRAM)

def_msg = "===Enter message to send to server===";
print "\n",def_msg

while (1):
	data = raw_input('>> ')
	if not data:
		break
	else:
		if(UDPSock.sendto(data,addr)):
			print "Sending message '",data,"'....."

UDPSock.close()
Vielleicht ist der Code für den einen oder anderen unter Euch brauchbar.

Schöne Grüße,
Tommy
derdon
User
Beiträge: 1316
Registriert: Freitag 24. Oktober 2008, 14:32

statt

Code: Alles auswählen

while (1):
    pass
schreibt man besser

Code: Alles auswählen

while True:
    pass
Benutzeravatar
HWK
User
Beiträge: 1295
Registriert: Mittwoch 7. Juni 2006, 20:44

Da Dein Programm unter Windows XP laufen soll, wäre ein COM-Server vielleicht einfacher. Hier findest Du ein einfaches Beispiel, wobei der Aufruf des Servers natürlich nicht über VBA erfolgen muss, sondern auch aus Python heraus geschehen kann.
MfG
HWK
Antworten