Source code for rqt_ez_publisher.ez_publisher_widget
import rospy
from python_qt_binding import QtCore
from python_qt_binding import QtGui
from python_qt_binding import QtWidgets
from python_qt_binding.QtWidgets import QWidget
from rqt_ez_publisher import ez_publisher_model as ez_model
from rqt_ez_publisher import widget as ez_widget
from rqt_ez_publisher import publisher
[docs]class EzPublisherWidget(QWidget):
'''Main widget of this GUI'''
sig_sysmsg = QtCore.Signal(str)
def __init__(self, parent=None, modules=[]):
self._model = ez_model.EzPublisherModel(
publisher.TopicPublisherWithTimer, modules=modules)
self._sliders = []
QWidget.__init__(self, parent=parent)
self.setup_ui()
[docs] def add_slider_from_combo(self):
return self.add_slider_by_text(str(self._combo.currentText()))
[docs] def close_slider(self, widget, remove=True):
widget.hide()
if remove:
self._sliders.remove(widget)
self._main_vertical_layout.removeWidget(widget)
[docs] def get_next_index(self, topic_name, attributes):
array_index = 0
text = ez_model.make_text(topic_name, attributes, array_index)
while text in [x.get_text() for x in self._sliders]:
array_index += 1
text = ez_model.make_text(topic_name, attributes, array_index)
return array_index
[docs] def add_widget(self, output_type, topic_name, attributes, array_index,
position=None):
widget_class = None
type_class_dict = {float: ez_widget.DoubleValueWidget,
int: ez_widget.IntValueWidget,
'uint': ez_widget.UIntValueWidget,
bool: ez_widget.BoolValueWidget,
str: ez_widget.StringValueWidget}
for module in self._model.get_modules():
type_class_dict[
module.get_msg_string()] = module.get_widget_class()
if output_type in type_class_dict:
widget_class = type_class_dict[output_type]
else:
self.sig_sysmsg.emit('not supported type %s' % output_type)
return False
widget = widget_class(topic_name, attributes, array_index,
self._model.get_publisher(topic_name), self)
self._model.get_publisher(topic_name).set_manager(self)
self._sliders.append(widget)
if widget.add_button:
widget.add_button.clicked.connect(
lambda: self.add_widget(
output_type, topic_name, attributes,
self.get_next_index(topic_name, attributes),
self._main_vertical_layout.indexOf(widget) + 1))
if position:
self._main_vertical_layout.insertWidget(position, widget)
else:
self._main_vertical_layout.addWidget(widget)
return True
[docs] def move_down_widget(self, widget):
index = self._main_vertical_layout.indexOf(widget)
if index < self._main_vertical_layout.count() - 1:
self._main_vertical_layout.removeWidget(widget)
self._main_vertical_layout.insertWidget(index + 1, widget)
[docs] def move_up_widget(self, widget):
index = self._main_vertical_layout.indexOf(widget)
if index > 1:
self._main_vertical_layout.removeWidget(widget)
self._main_vertical_layout.insertWidget(index - 1, widget)
[docs] def add_slider_by_text(self, text):
if text.endswith('/header/seq'):
rospy.loginfo('header/seq is not created')
return
if text in [x.get_text() for x in self._sliders]:
self.sig_sysmsg.emit('%s is already exists' % text)
return
results = self._model.register_topic_by_text(text)
if not results:
self.sig_sysmsg.emit('%s does not exists' % text)
return
topic_name, attributes, builtin_type, is_array, array_index = results
if builtin_type:
if is_array and array_index is None:
# use index 0
array_index = 0
self.add_widget(builtin_type, topic_name, attributes, array_index)
else:
for string in self._model.expand_attribute(text, array_index):
self.add_slider_by_text(string)
[docs] def get_sliders_for_topic(self, topic):
return [x for x in self._sliders if x.get_topic_name() == topic]
[docs] def clear_sliders(self):
for widget in self._sliders:
self.close_slider(widget, False)
self._sliders = []
[docs] def update_combo_items(self):
self._combo.clear()
for topic in self._model.get_topic_names():
self._combo.addItem(topic)
[docs] def set_configurable(self, value):
self._reload_button.setVisible(value)
self._topic_label.setVisible(value)
self._clear_button.setVisible(value)
self._combo.setVisible(value)
for slider in self._sliders:
slider.set_configurable(value)
[docs] def setup_ui(self):
self._horizontal_layout = QtWidgets.QHBoxLayout()
self._reload_button = QtWidgets.QPushButton(parent=self)
self._reload_button.setMaximumWidth(30)
self._reload_button.setIcon(
self.style().standardIcon(QtWidgets.QStyle.SP_BrowserReload))
self._reload_button.clicked.connect(self.update_combo_items)
self._topic_label = QtWidgets.QLabel('topic(+data member) name')
self._clear_button = QtWidgets.QPushButton('all clear')
self._clear_button.setMaximumWidth(200)
self._clear_button.clicked.connect(self.clear_sliders)
self._combo = QtWidgets.QComboBox()
self._combo.setEditable(True)
self.update_combo_items()
self._combo.activated.connect(self.add_slider_from_combo)
self._horizontal_layout.addWidget(self._reload_button)
self._horizontal_layout.addWidget(self._topic_label)
self._horizontal_layout.addWidget(self._combo)
self._horizontal_layout.addWidget(self._clear_button)
self._main_vertical_layout = QtWidgets.QVBoxLayout()
self._main_vertical_layout.addLayout(self._horizontal_layout)
self._main_vertical_layout.setAlignment(
self._horizontal_layout, QtCore.Qt.AlignTop)
self.setLayout(self._main_vertical_layout)
[docs]def main():
import sys
app = QtWidgets.QApplication(sys.argv)
main_window = QtWidgets.QMainWindow()
main_widget = EzPublisherWidget()
main_window.setCentralWidget(main_widget)
main_window.show()
app.exec_()
if __name__ == '__main__':
rospy.init_node('ez_publisher')
main()