0

我正在使用 wxPython 编写一个简单的 IRC 服务器和客户端 GUI。在我的应用程序中,我运行了两个线程:一个用于 GUI,一个用于发送和接收信息所需的套接字连接。到目前为止,我相信我已经成功地使用客户端应用程序连接到服务器,但是我没有看到任何消息被处理。我尝试将我的客户端与另一个 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()

编辑:relayChat 是理想情况下显示消息的地方。我将它设置为复制 chatText,一个全局字符串变量,因此我不必深入研究跨线程。

4

1 回答 1

0

我对 wx 不是很流利,但我认为这个问题无论如何都与 wx 无关。我在这里看到两个可能的问题。

首先,您在线程之间共享一个字符串以将文本传递给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 回答