ROS Resources: Documentation | Support | Discussion Forum | Index | Service Status | ros @ Robotics Stack Exchange
Ask Your Question
5

PyQt Signals for ROS callbacks in RQT Plugin

asked 2016-01-15 02:46:14 -0500

Andreas Hermann gravatar image

Hi everyone,

while writing a RQT plugin I had a hard time to figure out, how to connect a rospy callback to a PyQt SLOT in order to update the UI in a correct way.

The ROS WIKI only tells you, that one should not directly modify Widgets in a callback, due to Thread-Safety but lacks an example... So I propose to add a link to an example plugin in the Wiki which shows how to connect a ROS callback to a qt SLOT and update widgets (unfortunately I don't know one).

Can someone point out a good plugin code as an example?

Thanks, Andreas

edit retag flag offensive close merge delete

1 Answer

Sort by » oldest newest most voted
4

answered 2016-01-15 02:49:26 -0500

Andreas Hermann gravatar image

I answer my own question, showing my solution how to pipe message data via Qt SIGNALS and SLOTS, which hopefully helps others. So after initializing the plugin, I subscibe to a toppic with a custom message type, and in the message callback I just emit a SIGNAL carrying the whole message. In the according SLOT I then update the UI Widgets with the message data. I had to use the most basic PyQt_PyObject as data format to transfer my custom message type.

def __init__(self, context):
    foo()
    bar()
    and_so_on()

    self.sub = rospy.Subscriber('monitoring_result', MyMessageType, self.monitoringCallback,  queue_size=1)
    self.connect(self, SIGNAL("changeUI(PyQt_PyObject)"), self.monitoringSlot)

def monitoringCallback(self, data):
    self.emit(SIGNAL("changeUI(PyQt_PyObject)"), data)

def monitoringSlot(self, data):
    self._widget.lcdGoalID.display(data.current_trajectory + 1)
    self._widget.progressBar.setValue(data.max_num_collisions)
    self._widget.progressBar.setRange(0, data.coll_threshold)

    p = self._widget.palette()
    self._widget.setAutoFillBackground(True);
    if data.severe_collision:
        p.setColor(self._widget.backgroundRole(), Qt.red)
    else:
        p.setColor(self._widget.backgroundRole(), Qt.green)
    self._widget.setPalette(p)
edit flag offensive delete link more

Comments

Thanks! but I get error: AttributeError: 'QWidget' object has no attribute 'emit' Please help me!

quanghai gravatar image quanghai  ( 2019-06-04 07:07:37 -0500 )edit

Yeah, after search in Gooogle, and I have found the topic can have our for this problem is here https://stackoverflow.com/questions/5... and https://doc.qt.io/archives/qt-4.8/sig... (for more information to understand) It.'s mean the first we find the signal, connect to function, and emit a signal to go to slot function. (yah, it mean that.)

Neo Nguyen gravatar image Neo Nguyen  ( 2021-05-29 05:05:15 -0500 )edit

Question Tools

2 followers

Stats

Asked: 2016-01-15 02:46:14 -0500

Seen: 2,200 times

Last updated: Jan 15 '16