使用多线程的 Python gui 中的 Gdk-ERROR
Gdk-ERROR in Python gui with Multithreading
这是我的第一个post,所以如果我做错了什么,请耐心等待。
我正在开发一个用 python 编写的带有 gtk 界面的非常简单的聊天程序,一个用户有服务器,另一个有客户端。一切正常,除了我无法发送或接收消息(尽管已建立连接)。我已经在论坛中寻找解决方案,但没有找到任何东西。
GUI 的(部分)代码是:
gi.require_version ('Gtk', '3.0')
from gi.repository import Gtk, Gdk, GObject, GLib
class GUI:
def __init__ (self, is_server):
GObject.threads_init ()
[...]
self.buffer1 = Gtk.TextBuffer ()
self.text_box = Gtk.TextView (buffer=self.buffer1)
self.text_box.set_editable (False)
[...]
self.th = threading.Thread (target = self.receive)
self.th.daemon = True
self.th.start ()
Gtk.main ()
def receive (self):
while (True):
try:
msg = self.socket.receive_message ()
if (msg != ""): self.insert_text (msg)
except: pass
def insert_text (self, text):
self.text_box.set_editable (True)
end_iter = self.buffer1.get_end_iter ()
try: self.buffer1.insert (end_iter, text + "\n")
except: pass
self.text_box.set_editable (False)
adj = self.scr.get_vadjustment ()
adj.set_value (adj.get_upper ())
并且在Client.py或Server.py中(是相同的行):
class Client/Server:
[...]
def receive_message (self):
try:
msg0 = self.conn.recv (1024)
msg = msg0.decode ("utf-8")
return msg
except: pass
我收到的错误是:
(Chat.py:61330): Gdk-ERROR **: The program 'Chat.py' received an X Window System error.
This probably reflects a bug in the program.
The error was 'BadRequest (invalid request code or no such operation)'.
(Details: rerial 892 error_code 1 request_code 0 (core protocol) minor_code 0)
(Note to programmers: normally, X errors are reported asynchronously;
that is, you will receive the error a while after causing it.
To debug your program, run it with the GDK_SYNCHRONIZE environment
variable to change this behavior. You can get a meaningful
backtrace from your debugger if you break on the gdk_x_error() function.)
Trace/BPT trap (code dumped)
我认为这是一个多线程错误,因为在第二个线程中我尝试更改 Gtk.TextView 的文本,但我不确定(我对多线程很陌生)。
感谢大家。
您不能从调用 Gtk.main()
的线程以外的线程调用 GTK+ 函数。您必须更改您的线程以将数据发送到主线程并修改 GUI,例如通过将对 insert_text()
的调用包装在 receive()
中的 GLib.idle_add()
.
这是我的第一个post,所以如果我做错了什么,请耐心等待。
我正在开发一个用 python 编写的带有 gtk 界面的非常简单的聊天程序,一个用户有服务器,另一个有客户端。一切正常,除了我无法发送或接收消息(尽管已建立连接)。我已经在论坛中寻找解决方案,但没有找到任何东西。
GUI 的(部分)代码是:
gi.require_version ('Gtk', '3.0')
from gi.repository import Gtk, Gdk, GObject, GLib
class GUI:
def __init__ (self, is_server):
GObject.threads_init ()
[...]
self.buffer1 = Gtk.TextBuffer ()
self.text_box = Gtk.TextView (buffer=self.buffer1)
self.text_box.set_editable (False)
[...]
self.th = threading.Thread (target = self.receive)
self.th.daemon = True
self.th.start ()
Gtk.main ()
def receive (self):
while (True):
try:
msg = self.socket.receive_message ()
if (msg != ""): self.insert_text (msg)
except: pass
def insert_text (self, text):
self.text_box.set_editable (True)
end_iter = self.buffer1.get_end_iter ()
try: self.buffer1.insert (end_iter, text + "\n")
except: pass
self.text_box.set_editable (False)
adj = self.scr.get_vadjustment ()
adj.set_value (adj.get_upper ())
并且在Client.py或Server.py中(是相同的行):
class Client/Server:
[...]
def receive_message (self):
try:
msg0 = self.conn.recv (1024)
msg = msg0.decode ("utf-8")
return msg
except: pass
我收到的错误是:
(Chat.py:61330): Gdk-ERROR **: The program 'Chat.py' received an X Window System error.
This probably reflects a bug in the program.
The error was 'BadRequest (invalid request code or no such operation)'.
(Details: rerial 892 error_code 1 request_code 0 (core protocol) minor_code 0)
(Note to programmers: normally, X errors are reported asynchronously;
that is, you will receive the error a while after causing it.
To debug your program, run it with the GDK_SYNCHRONIZE environment
variable to change this behavior. You can get a meaningful
backtrace from your debugger if you break on the gdk_x_error() function.)
Trace/BPT trap (code dumped)
我认为这是一个多线程错误,因为在第二个线程中我尝试更改 Gtk.TextView 的文本,但我不确定(我对多线程很陌生)。
感谢大家。
您不能从调用 Gtk.main()
的线程以外的线程调用 GTK+ 函数。您必须更改您的线程以将数据发送到主线程并修改 GUI,例如通过将对 insert_text()
的调用包装在 receive()
中的 GLib.idle_add()
.