How to update a Gtk window from ROS subscriber callback?

asked 2016-12-23 20:51:30 -0500

Pi Robot gravatar image

This is as much a Gtk question as a ROS question but since the crux of the problem involves a ROS subscriber callback, I thought I would try asking it here.

I am not skilled at Gtk programming and I am trying to modify this existing Python code for xdot.py so that I can update the DOT graph being displayed using a ROS subscriber callback. The issue I am facing (I think), is that rospy runs the subscriber callback in its own thread but that Gtk fires up a main() process that I somehow have to get to communicate with this thread and I don't know how to hook the two together.

More details...

My node subscribes to a String topic (/dot_string) that contains a representation of the DOT graph I want to display. So the subscriber part of my code looks like this:

import rospy
from std_msgs.msg import String

rospy.Subscriber('/dot_string', String, self.update_dot_graph)

def update_dot_graph(self, msg)
    self.dot_string = msg.data

All I want to do is use this string data to update the graph being displayed by the xdot.py program.

The existing code for xdot.py periodically reads a text file containing the DOT graph using gobject.timeout_add(100, self.update) where the update() function is shown below:

def update(self):
    if self.openfilename is not None:
        current_mtime = os.stat(self.openfilename).st_mtime
        if current_mtime != self.last_mtime:
            self.last_mtime = current_mtime
            self.reload()
    return True

The reload() function opens the text file to read the DOT data:

def reload(self):
        if self.openfilename is not None:
            try:
                fp = file(self.openfilename, 'rt')
                self.set_dotcode(fp.read(), self.openfilename)
                fp.close()
            except IOError:
                pass

However, this can be changed to set the dot code from a string:

def reload(self):
    try:
        self.set_dotcode(self.dot_string)
    except:
        pass

The catch is that I can't get the rospy subscriber callback to actually run since the Gtk main() process blocks it from getting started.

Does anyone know the magic to connect the subscriber callback to the Gtk update?

edit retag flag offensive close merge delete