The Easiest Way of (inter) Thread-Communication for Python

Connecting VTK and ROS or ROS and GTK by using Python always causes some kind of trouble because there is a main-thread and some other thread. Whereby, everyone (ROS, VTK, GTK, ETC.) wants to be the main-thread and calling a function/method from another thread is mostly the main-problem. There is one pretty simple solution to all of these problems, namely publish-subscribe or in other words the Python pubsub module. Its usage is quite similar to the usage of pub/sub in ROS.

# -*- coding: utf-8 -*-

import sys, time
from pubsub import pub

from PyQt4 import QtGui
from PyQt4.QtCore import QThread

import roslib
import rospy
from std_msgs.msg import String

# ROS - Worker Thread
class RosThread(QThread):
	def __init__(self, topic, parent = None):
		QThread.__init__(self, parent)
		self.sub = rospy.Subscriber(topic, String, self.callback)

	def run(self):        

	def callback(self, msg):
		pub.sendMessage('update', )

# Qt - Worker Thread
class WorkerThread(QThread):
	def __init__(self, name, sleep, parent = None):
		QThread.__init__(self, parent)
		self.sleep = sleep  = name
	def run(self):        
			pub.sendMessage('update', string="update: "

# Minimal GUI
class Gui(QtGui.QWidget):    
	def __init__(self):
		super(Gui, self).__init__()

		self.button = QtGui.QPushButton('Change', self)
		self.button.move(20, 20)

		self.text = QtGui.QLabel(self)
		self.text.move(100, 22)

		self.setGeometry(300, 300, 290, 60)

        # Update the Gui from the GUI
	def showDialog(self):
		text, ok = QtGui.QInputDialog.getText(self, 'Change Label',  'String:')
		if ok:
        # callback method for pubsub    
	def setLabel(self, string):

# create a GUI
app = QtGui.QApplication(sys.argv)
gui = Gui()

# connect method 'gui.setLabel' with topic 'update'
pub.subscribe(gui.setLabel, 'update')

# create two simple Worker Threads
worker1 = WorkerThread("worker1", 5)
worker2 = WorkerThread("worker2", 2.5)

# create ROS-node
ros1 = RosThread("sub1")

# run main Thread

The example from above executes two Qt worker threads, one ROS thread, and of course one main thread that is responsible for the GUI.


The GUI consists of a single button and a label, which is updated by the user or the different threads. See line 67, the command ‘pub.subscribe(method, topic)’is everything to connect any method with a certain topic. Afterwards this methods can be called from any thread with command ‘pub.sendMessage(topic, data)’ see lines 24 and 35. Test messages to the ROS node can be send with the following shell-command:

$ rostopic pub sub1 std_msgs/String '{"data":"test"}'

The same works also with VTK, GTK, …


Readers Comments (1)

  1. I am truly happy to read this weblog posts which contains tons of valuable
    information, thanks for providing these information.


Leave a comment

Your email address will not be published.