I cannot for the life of me figure out how to use signals and slots to pass information to the GUI widget in an RQT plugin that is written in C++. The ROS Tutorial for creating a C++ RQT plugin doesn't even have any data widgets in the GUI, let alone any code to show how to use signals/slots to pipe data to a data widget: http://wiki.ros.org/rqt/Tutorials/Writing%20a%20C%2B%2B%20Plugin
After several hours of trial and error, I was able to figure out a solution for using signals/slots in a Python RQT plugin, but I can't seem to make the stretch to C++.
Here is the python example I created starting from the ROS Tutorial for creating a python RQT plugin (https://github.com/lucasw/rqt_mypkg) and then adding some of this code from ROS Answers where a user asked how to use signals/slots in python: http://answers.ros.org/question/224152/pyqt-signals-for-ros-callbacks-in-rqt-plugin/
my_module.py:
import os
import rospy
from qt_gui.plugin import Plugin
from python_qt_binding import loadUi
from python_qt_binding.QtGui import QWidget
from std_msgs.msg import Int32
from PyQt4.QtCore import SIGNAL
class MyPlugin(Plugin):
def __init__(self, context):
super(MyPlugin, self).__init__(context)
# Give QObjects reasonable names
self.setObjectName('MyPlugin')
# Process standalone plugin command-line arguments
from argparse import ArgumentParser
parser = ArgumentParser()
# Add argument(s) to the parser.
parser.add_argument("-q", "--quiet", action="store_true",
dest="quiet",
help="Put plugin in silent mode")
args, unknowns = parser.parse_known_args(context.argv())
if not args.quiet:
print 'arguments: ', args
print 'unknowns: ', unknowns
# Create QWidget
self._widget = QWidget()
# Get path to UI file which is a sibling of this file
# in this example the .ui and .py file are in the same folder
ui_file = os.path.join(os.path.dirname(os.path.realpath(__file__)), 'MyPlugin.ui')
# Extend the widget with all attributes and children from UI file
loadUi(ui_file, self._widget)
# Give QObjects reasonable names
self._widget.setObjectName('MyPluginUi')
# Show _widget.windowTitle on left-top of each plugin (when
# it's set in _widget). This is useful when you open multiple
# plugins at once. Also if you open multiple instances of your
# plugin at once, these lines add number to make it easy to
# tell from pane to pane.
if context.serial_number() > 1:
self._widget.setWindowTitle(self._widget.windowTitle() + (' (%d)' % context.serial_number()))
# Add widget to the user interface
context.add_widget(self._widget)
# kurt added these lines
self.sub = rospy.Subscriber('my_data', Int32, self.ros_msg_callback, queue_size=1)
self.connect(self, SIGNAL("changeUI(PyQt_PyObject)"), self.monitoring_slot)
# kurt added this callback
def ros_msg_callback(self, data):
self.emit(SIGNAL("changeUI(PyQt_PyObject)"), data)
pass
# kurt added this slot routine
def monitoring_slot(self, data):
self._widget.data_myData.setText(str(data))
self._widget.data_myData.setStyleSheet("color: black; background-color: red;")
pass
def shutdown_plugin(self):
# TODO unregister all publishers here
pass
def save_settings(self, plugin_settings, instance_settings):
# TODO save intrinsic configuration, usually using:
# instance_settings.set_value(k, v)
pass
def restore_settings(self, plugin_settings, instance_settings):
# TODO restore intrinsic configuration, usually using:
# v = instance_settings.value(k)
pass
#def trigger_configuration(self):
# Comment in to signal that the plugin has a way to configure
# This will enable a setting button (gear icon) in each dock widget title bar
# Usually used to open a modal configuration dialog
MyPlugin.ui:
Form 0 0 400 300 Form Label: 10 10 50 30 TBD 70 10 50 30 color: rgb(0, 255, 0); background-color: rgb(0, 0, 0);
↧