0

wxPython を使用して単純な IRC サーバーとクライアント GUI を作成しています。私のアプリケーションでは、2 つのスレッドを実行していました。1 つは GUI 用で、もう 1 つは情報の送受信に必要なソケット接続用です。これまでのところ、クライアント アプリケーションを使用してサーバーに正常に接続していると思いますが、メッセージが処理されていません。別の TCP リスナー アプリケーションでクライアントを使用してみましたが、メッセージを正常に送信できました。問題は、GUI の設定方法にあると思います。サーバー側アプリケーションのコードは次のとおりです(スペースがぎこちなくて申し訳ありません)

問題は bootUp() 関数内にあると感じています..

#!/usr/bin/python

import wx
import socket
import threading
from threading import Thread

ip = ""
port = 0
backlog = 5

chatText = ""

class relayServerGUI(wx.Frame):
def __init__(self, parent, id):
    wx.Frame.__init__(self, parent, id, "Enter IP address", size = (600, 600))
    orciPanel = wx.Panel(self)
    relayChat = wx.TextCtrl(orciPanel, 0, chatText, (50, 50), (500, 500),style              = wx.TE_MULTILINE)
    portInput = wx.TextEntryDialog(None, "Enter Port: ", "")
    if portInput.ShowModal() == wx.ID_OK:
        global port
        port = int(portInput.GetValue())
        thread2()       

def relayInterpretor():
    socketRelay = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
    socketRelay.bind((ip, port))
    socketRelay.listen(backlog)
    client, address = socketRelay.accept()

    while 1:
                    relayData = client.recv(1024)
                    global chatText
                    chatText += (relayData)
                    client.send(relayData)


def bootUP():
if __name__ == "__main__":
    relayApplication = wx.PySimpleApp()
    relayFrame = relayServerGUI(parent = None, id = -1)
    relayFrame.Show()
    relayApplication.MainLoop()

    while 1:
        relayChat.Clear()
        relayChat.AppendText(chatText)

Thread(target = bootUP).start()
def thread2():
    Thread(target = relayInterpretor).start()

EDIT:relayChatは、理想的にはメッセージが表示される場所です。グローバル文字列変数である chatText をコピーするように設定したので、クロススレッドについて詳しく調べる必要はありません。

4

1 に答える 1

0

私は wx に精通しているわけではありませんが、この問題は特に wx に関連したものではないと思います。ここには 2 つの問題が考えられます。

まず、スレッド間で文字列を共有してテキストをrelayChatウィジェットに伝達しますが、これは通常非常に悪い方法です。イベントループがメインスレッドでイベントを取得し、ウィジェットを更新するハンドラーを実行するように、スレッドから wx でイベントを発行する方法が必要です。

第二に、イベントループ...

relayApplication.MainLoop()

それはブロッキングコールです。アプリケーションがイベント ループに入るため、次のコードは実行されません。

while 1:
    relayChat.Clear()
    relayChat.AppendText(chatText)

繰り返しますが、これは最初のポイントに戻ります。スレッド内のソケットが何らかのデータを受信すると、そのデータでイベントを発行する必要があるため、メイン GUI スレッドは、ウィジェットに追加されるハンドラーを適切に呼び出すことができます。

アップデート

カスタム wx イベントを発行する方法に関するこの質問を参照すると、おそらく次のように修正できます。

from wx.lib.newevent import NewEvent

ChatTextEvent, EVT_CHATTEXT = NewEvent()

class relayServerGUI(wx.Frame):
    def __init__(self, parent, id):
        ...
        # make sure to save a ref to your chat widget
        self.relayChat = wx.TextCtrl(orciPanel, 0, chatText, (50, 50), (500, 500),style              = wx.TE_MULTILINE)
        self.Bind(EVT_CHATTEXT, self.newChatTextEvent)
        ...
        thread2(self)

    def newChatTextEvent(self, event):
        self.relayChat.AppendText(event.data)


def relayInterpretor(wxObject):
   ...
   while 1:
      ...
      # wxObject needs to be an instance of relayServerGUI
      wx.PostEvent(wxObject, ChatTextEvent(data=relayData))

def thread2(wxObject):
    Thread(target = relayInterpretor, args=(wxObject,)).start()    

*注: 私はその構文について 100% ではありません。やってみて。少し調整が必要な場合があります。

于 2012-08-13T03:48:18.947 に答える