我对Python很陌生,如果我的问题是业余的,我很抱歉。在
我试图做一个简单的程序,允许用户看到正在广播的UDP消息。为了使程序不被锁定,我当然需要创建一个单独的线程来监听广播。在
在我尝试实现线程之前,这个程序运行得很好。它只是等待UDP消息,并在接收到UDP消息时将其显示在TextView
中。当然,这锁定了主线程。在
这是我的代码:(是的,我知道我的代码有几个不相关的问题,但请忽略它们。e、 我从不关闭socket
。稍后我将讨论这些问题。)
import socket
import select
import sys
import threading
try:
import pygtk
pygtk.require("2.0")
except:
pass
try:
import gtk
except:
print("GTK not available!")
sys.exit(1)
class GUI:
def __init__(self):
self.builder = gtk.Builder()
self.builder.add_from_file("UDPListener.ui")
dic = {"on_mainWindow_destroy" : self.quit,
"on_listenButton_clicked" : self.startThread,
"on_stopListenButton_clicked" : self.stopListening}
self.builder.connect_signals(dic)
self.listenerThread = threading.Thread(target = self.listen)
def startThread(self, widget):
self.listenerThread.start()
def listen(self):
bufferSize = 1024
IPAddress = "0.0.0.0"
IPAddress: 0.0.0.0
portNumber = 50000
udpClient = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
textView = self.builder.get_object("messagesReceivedEntry").get_buffer()
textView.text = textView.get_text(textView.get_start_iter(),textView.get_end_iter())
textView.set_text("Listening...")
try:
udpClient.bind((IPAddress, portNumber))
udpClient.setblocking(0)
except:
print "Cannot connect."
try:
while True:
result = select.select([udpClient],[],[])
message = result[0][0].recv(bufferSize)
print message
except:
print "Cannot receive message"
def quit(self, widget):
sys.exit(0)
def stopListening(self, widget):
pass
gui = GUI()
gtk.main()
代码会运行,一切正常,但它从不打印任何消息(我自己广播)。在
更新:
多亏了J.F.Sebastian的回答,我修改了代码,包括以下内容:
^{pr2}$到目前为止,一切正常。在
我发现对于多线程gtk应用程序来说很好的模型是在主线程中运行所有GUI代码。gtk在后台线程中运行的惟一方法是
gobject.idle_add()
来安排在主线程中执行的gui回调。在在运行任何其他gtk代码之前,请将
gobject.threads_init()
放在模块顶部的某个地方。在Here's an example for Gtk 3但原理与Gtk 2相同。Another example。在
另一种方法是使用类似
gobject.io_add_watch()
的方法,避免使用多个线程。在相关问题 更多 >
编程相关推荐