10 setObjectName(
"Topics RViz plugin");
13 qRegisterMetaType<QMessageBox::Icon>();
17 QWidget *scroll_widget =
new QWidget;
18 scroll_widget->setLayout(
layout_);
19 QScrollArea *scroll_area =
new QScrollArea;
20 scroll_area->setWidget(scroll_widget);
21 scroll_area->setWidgetResizable(
true);
22 scroll_area->setFrameShape(QFrame::NoFrame);
23 QVBoxLayout *main_layout =
new QVBoxLayout(
this);
24 main_layout->addWidget(scroll_area);
26 QPushButton *
topics =
new QPushButton(
"Topics");
29 QPushButton *
settings =
new QPushButton(
"Settings");
30 settings->setIcon(QIcon::fromTheme(
"preferences-system"));
33 QHBoxLayout *buttons =
new QHBoxLayout;
34 buttons->addWidget(topics);
35 buttons->addWidget(settings);
42 labels.push_back(
"Topic");
43 labels.push_back(
"Value");
44 table_->setHorizontalHeaderLabels(labels);
45 table_->setShowGrid(
false);
67 int refresh_rate_ms(0);
69 if (!config.
mapGetString(
"topic_" + QString::number(i) +
"_name", &topic_name))
72 if (!config.
mapGetString(
"topic_" + QString::number(i) +
"_type", &topic_type))
76 config.
mapGetInt(
"topic_" + QString::number(i) +
"_refresh_rate", &refresh_rate_ms);
79 details.
type = topic_type.toStdString();
82 displayed_topics_.insert(std::pair<std::string, TopicDetails>(topic_name.toStdString(), details));
87 if (config.
mapGetBool(
"short_topic_names", &tmp_bool))
95 QString table_header_state_str;
96 if (config.
mapGetString(
"horizontal_table_header", &table_header_state_str))
98 table_->horizontalHeader()->restoreState(QByteArray::fromHex(qPrintable(table_header_state_str)));
101 if (config.
mapGetString(
"vertical_table_header", &table_header_state_str))
103 table_->verticalHeader()->restoreState(QByteArray::fromHex(qPrintable(table_header_state_str)));
113 config.
mapSetValue(
"topic_" + QString::number(i) +
"_name", QString::fromStdString(topic.first));
114 config.
mapSetValue(
"topic_" + QString::number(i) +
"_type", QString::fromStdString(topic.second.type));
115 config.
mapSetValue(
"topic_" + QString::number(i) +
"_refresh_rate", topic.second.refresh_rate.toNSec() / 1e6);
119 QByteArray table_header_state(
table_->horizontalHeader()->saveState());
121 config.
mapSetValue(
"horizontal_table_header", table_header_state.toHex());
123 table_header_state =
table_->verticalHeader()->saveState();
125 config.
mapSetValue(
"vertical_table_header", table_header_state.toHex());
137 Q_EMIT
displayMessageBox(
"Error getting topics",
"Could not retrieve the topics names.",
"",
138 QMessageBox::Icon::Critical);
144 for (
auto topic : topics)
146 if (topic.datatype ==
"std_msgs/Bool" ||
147 topic.datatype ==
"std_msgs/Int8" ||
148 topic.datatype ==
"std_msgs/UInt8" ||
149 topic.datatype ==
"std_msgs/Int16" ||
150 topic.datatype ==
"std_msgs/UInt16" ||
151 topic.datatype ==
"std_msgs/Int32" ||
152 topic.datatype ==
"std_msgs/UInt32" ||
153 topic.datatype ==
"std_msgs/Int64" ||
154 topic.datatype ==
"std_msgs/UInt64" ||
155 topic.datatype ==
"std_msgs/Float32" ||
156 topic.datatype ==
"std_msgs/Float64" ||
157 topic.datatype ==
"std_msgs/String" ||
158 topic.datatype ==
"std_msgs/Time" ||
159 topic.datatype ==
"std_msgs/Duration")
160 supported_topics.emplace_back(topic);
163 if (supported_topics.empty())
167 QDialog *no_topics_dialog =
new QDialog(
this);
168 no_topics_dialog->setWindowTitle(
"No supported topic");
169 QVBoxLayout *layout =
new QVBoxLayout;
170 no_topics_dialog->setLayout(layout);
172 new QLabel(
"Error with topics, no supported topics found.\n" 173 "- Ok will clear the topics displayed\n- Cancel will not change the displayed topics"));
175 QDialogButtonBox *button_box =
new QDialogButtonBox(QDialogButtonBox::Ok | QDialogButtonBox::Cancel);
176 no_topics_dialog->layout()->addWidget(button_box);
178 connect(button_box, &QDialogButtonBox::accepted, no_topics_dialog, &QDialog::accept);
179 connect(button_box, &QDialogButtonBox::rejected, no_topics_dialog, &QDialog::reject);
181 if (!no_topics_dialog->exec())
194 QDialog *pick_topics_dialog =
new QDialog(
this);
195 pick_topics_dialog->setWindowTitle(
"Pick displayed topics");
197 QGridLayout *layout =
new QGridLayout();
198 QWidget *scroll_widget =
new QWidget;
199 scroll_widget->setLayout(layout);
200 QScrollArea *scroll_area =
new QScrollArea;
201 scroll_area->setWidget(scroll_widget);
202 scroll_area->setWidgetResizable(
true);
203 scroll_area->setFrameShape(QFrame::NoFrame);
204 QVBoxLayout *dialog_layout =
new QVBoxLayout(pick_topics_dialog);
205 dialog_layout->addWidget(scroll_area);
207 unsigned row(0), col(0);
209 layout->addWidget(
new QLabel(
"Only supported built-in types are displayed"), row ,col);
213 return a.
name < b.name;
216 std::vector<QCheckBox *> topic_buttons;
217 for (
auto topic : supported_topics)
219 QCheckBox *radio_button =
new QCheckBox;
222 radio_button->setChecked(
true);
224 topic_buttons.emplace_back(radio_button);
225 radio_button->setText(QString::fromStdString(topic.name));
226 radio_button->setObjectName(QString::fromStdString(topic.name));
227 radio_button->setToolTip(QString::fromStdString(topic.datatype));
228 layout->addWidget(radio_button, row, col);
237 QDialogButtonBox *button_box =
new QDialogButtonBox(QDialogButtonBox::Ok | QDialogButtonBox::Cancel);
238 layout->addWidget(button_box, layout->rowCount() + 1, col);
240 connect(button_box, &QDialogButtonBox::accepted, pick_topics_dialog, &QDialog::accept);
241 connect(button_box, &QDialogButtonBox::rejected, pick_topics_dialog, &QDialog::reject);
243 if (!pick_topics_dialog->exec())
253 for (
auto button : topic_buttons)
255 if (!button->isChecked())
261 for (
auto &topic: displayed_topics_old)
263 if (topic.first == button->objectName().toStdString())
264 details= topic.second;
267 details.
type = button->toolTip().toStdString();
268 displayed_topics_.insert(std::pair<std::string, TopicDetails>(button->objectName().toStdString(),
281 QDialog *dialog(
new QDialog(
this));
282 dialog->setWindowTitle(
"Display topics - Settings");
283 QVBoxLayout *layout =
new QVBoxLayout(dialog);
285 QCheckBox *short_topic_names(
new QCheckBox(
"Short topic names"));
287 layout->addWidget(short_topic_names);
290 layout->addStretch(1);
291 QLabel* maximum_refresh_rate(
new QLabel(
"<b>Maximum refresh rate</b>"));
292 layout->addWidget(maximum_refresh_rate);
294 QGridLayout *grid(
new QGridLayout);
296 std::vector<QSpinBox *> topic_spinboxes;
299 QLabel *topic_name(
new QLabel(QString::fromStdString(topic.first)));
300 topic_name->setToolTip(QString::fromStdString(topic.second.type));
301 grid->addWidget(topic_name, i, 0);
302 QSpinBox *refresh_rate(
new QSpinBox);
303 topic_spinboxes.emplace_back(refresh_rate);
304 refresh_rate->setObjectName(QString::fromStdString(topic.first));
305 refresh_rate->setToolTip(
"If set to zero the displayed value is updated every time a value is received.");
306 refresh_rate->setSingleStep(100);
307 refresh_rate->setRange(0, 10000);
308 refresh_rate->setSuffix(
" ms");
309 grid->addWidget(refresh_rate, i, 1);
315 if (topic_info->topic_name_ != topic.first)
317 refresh_rate->setValue(topic_info->maximumRefreshRate().toSec() * 1e3);
322 layout->addLayout(grid);
323 layout->addStretch(1);
325 QDialogButtonBox *button_box =
new QDialogButtonBox(QDialogButtonBox::Ok | QDialogButtonBox::Cancel);
326 layout->addWidget(button_box);
328 connect(button_box, &QDialogButtonBox::accepted, dialog, &QDialog::accept);
329 connect(button_box, &QDialogButtonBox::rejected, dialog, &QDialog::reject);
340 for (
auto &spinbox: topic_spinboxes)
342 for (
auto &topic: displayed_topics_)
344 if (topic.first != spinbox->objectName().toStdString())
348 topic.second.refresh_rate = d;
366 std::shared_ptr<TopicInfo> topic_info(
new TopicInfo(topic.first, topic.second.type, topic.second.refresh_rate));
377 QString topic_name(topic_info->label_.get()->text());
378 int n = topic_name.lastIndexOf(
"/");
380 topic_name.remove(0, n + 1);
382 QLabel *topic_label(
new QLabel(topic_name));
383 table_->setCellWidget(i, 0, topic_label);
386 table_->setCellWidget(i, 0, topic_info->label_.get());
387 table_->setCellWidget(i, 1, topic_info->display_.get());
395 const QMessageBox::Icon icon)
397 const bool old_state(isEnabled());
400 msg_box.setWindowTitle(title);
401 msg_box.setText(text);
402 msg_box.setInformativeText(info);
403 msg_box.setIcon(icon);
404 msg_box.setStandardButtons(QMessageBox::Ok);
406 setEnabled(old_state);
void updateTopicsDisplayed()
ROSCPP_DECL bool getTopics(V_TopicInfo &topics)
std::vector< std::shared_ptr< TopicInfo > > topic_infos_
virtual void save(Config config) const
bool mapGetString(const QString &key, QString *value_out) const
std::vector< TopicInfo > V_TopicInfo
void mapSetValue(const QString &key, QVariant value)
virtual void setName(const QString &name)
virtual void load(const rviz::Config &config)
virtual void save(rviz::Config config) const
DisplayTopics(QWidget *parent=NULL)
void displayMessageBox(const QString, const QString, const QString, const QMessageBox::Icon)
bool mapGetBool(const QString &key, bool *value_out) const
void displayMessageBoxHandler(const QString title, const QString text, const QString info="", const QMessageBox::Icon icon=QMessageBox::Icon::Information)
virtual void load(const Config &config)
bool mapGetInt(const QString &key, int *value_out) const
#define PLUGINLIB_EXPORT_CLASS(class_type, base_class_type)
std::map< std::string, TopicDetails > displayed_topics_
ros::Duration refresh_rate