user8083031
user8083031

Reputation:

Gdk-ERROR in Python gui with Multithreading


It is my first post, so if I am doing something wrong please be patient.
I am working on a very simple chat program written in python with a gtk interface, a user has the server and the other has the client. All is working, except that I cannot send or receive messages (although the connection is established). I have already looked for a solution in the forum but I did not find anything.
(Part of) the code for the GUI is:

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 ())

And in Client.py or Server.py (are the same lines):

class Client/Server:
    [...]
    def receive_message (self):
        try:
            msg0 = self.conn.recv (1024)
            msg = msg0.decode ("utf-8")
            return msg
        except: pass

The error I receive is:

(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)

I think it is a multithreading error because in the second thread I try to change the text of the Gtk.TextView but I am not sure (I am quite new with multithreading).

Thanks to all.

Upvotes: 1

Views: 1003

Answers (1)

andlabs
andlabs

Reputation: 11588

You cannot call GTK+ functions from a thread other than the one that called Gtk.main(). You must change your threads to send data to the main thread and have that modify the GUI instead, for instance by wrapping the call to insert_text() in receive() in a GLib.idle_add().

Upvotes: 2

Related Questions