display_topics.cpp
Go to the documentation of this file.
2 
3 namespace topics_rviz_plugin
4 {
5 DisplayTopics::DisplayTopics(QWidget* parent) :
6  rviz::Panel(parent)
7 {
8  qRegisterMetaType<QMessageBox::Icon>();
9  setEnabled(false);
10  setName("Topics RViz plugin");
11  setObjectName(getName());
12 
13  connect(this, SIGNAL(displayMessageBox(const QString, const QString, const QString, const QMessageBox::Icon)), this,
14  SLOT(displayMessageBoxHandler(const QString, const QString, const QString, const QMessageBox::Icon)));
15 
16  layout_ = new QVBoxLayout();
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);
25 
26  QPushButton *configure = new QPushButton("Configure");
27  configure->setIcon(QIcon::fromTheme("preferences-system"));
28  connect(configure, SIGNAL(clicked()), this, SLOT(configure()));
29  layout_->addWidget(configure);
30 
31  table_ = new QTableWidget;
32  table_->insertColumn(0);
33  table_->insertColumn(0);
34  QStringList labels;
35  labels.push_back("Topic");
36  labels.push_back("Value");
37  table_->setHorizontalHeaderLabels(labels);
38  table_->setShowGrid(false);
39  layout_->addWidget(table_);
40  Q_EMIT setEnabled(true);
41 
42  connect(table_->horizontalHeader(), SIGNAL(sectionResized(int, int, int)), this, SIGNAL(configChanged()));
43  connect(table_->verticalHeader(), SIGNAL(sectionResized(int, int, int)), this, SIGNAL(configChanged()));
44 }
45 
47 {
48  nh_.shutdown();
49 }
50 
51 void DisplayTopics::load(const rviz::Config& config)
52 {
53  rviz::Panel::load(config);
54 
55  unsigned i(0);
56  while (1)
57  {
58  QString topic_name;
59  QString topic_type;
60 
61  if (!config.mapGetString("topic_" + QString::number(i) + "_name", &topic_name))
62  break;
63 
64  if (!config.mapGetString("topic_" + QString::number(i) + "_type", &topic_type))
65  break;
66 
67  displayed_topics_.insert(std::pair<std::string, std::string>(topic_name.toStdString(), topic_type.toStdString()));
68  ++i;
69  }
70 
71  if (!displayed_topics_.empty())
73 
74  QString table_header_state_str;
75  if (config.mapGetString("horizontal_table_header", &table_header_state_str))
76  {
77  table_->horizontalHeader()->restoreState(QByteArray::fromHex(qPrintable(table_header_state_str)));
78  }
79 
80  if (config.mapGetString("vertical_table_header", &table_header_state_str))
81  {
82  table_->verticalHeader()->restoreState(QByteArray::fromHex(qPrintable(table_header_state_str)));
83  }
84 }
85 
87  {
88  rviz::Panel::save(config);
89  unsigned i(0);
90  for (auto topic : displayed_topics_)
91  {
92  config.mapSetValue("topic_" + QString::number(i) + "_name", QString::fromStdString(topic.first));
93  config.mapSetValue("topic_" + QString::number(i) + "_type", QString::fromStdString(topic.second));
94  ++i;
95  }
96 
97  QByteArray table_header_state(table_->horizontalHeader()->saveState());
98  // Must be saved as hex
99  config.mapSetValue("horizontal_table_header", table_header_state.toHex());
100 
101  table_header_state = table_->verticalHeader()->saveState();
102  // Must be saved as hex
103  config.mapSetValue("vertical_table_header", table_header_state.toHex());
104 }
105 
107 {
108  Q_EMIT setEnabled(false);
109 
111  if (!ros::master::getTopics(topics))
112  {
113  Q_EMIT displayMessageBox("Error getting topics", "Could not retrieve the topics names.", "",
114  QMessageBox::Icon::Critical);
115  Q_EMIT setEnabled(true);
116  return;
117  }
118 
119  ros::master::V_TopicInfo supported_topics;
120  for (auto topic : topics)
121  {
122  if (topic.datatype == "std_msgs/Bool" ||
123  topic.datatype == "std_msgs/Int8" ||
124  topic.datatype == "std_msgs/UInt8" ||
125  topic.datatype == "std_msgs/Int16" ||
126  topic.datatype == "std_msgs/UInt16" ||
127  topic.datatype == "std_msgs/Int32" ||
128  topic.datatype == "std_msgs/UInt32" ||
129  topic.datatype == "std_msgs/Int64" ||
130  topic.datatype == "std_msgs/UInt64" ||
131  topic.datatype == "std_msgs/Float32" ||
132  topic.datatype == "std_msgs/Float64" ||
133  topic.datatype == "std_msgs/String" ||
134  topic.datatype == "std_msgs/Time" ||
135  topic.datatype == "std_msgs/Duration")
136  supported_topics.push_back(topic);
137  }
138 
139  if (supported_topics.empty())
140  {
141  Q_EMIT setEnabled(false);
142 
143  QDialog *no_topics_dialog = new QDialog(this);
144  no_topics_dialog->setWindowTitle("No supported topic");
145  QVBoxLayout *layout = new QVBoxLayout;
146  no_topics_dialog->setLayout(layout);
147  layout->addWidget(
148  new QLabel("Error with topics, no supported topics found.\n"
149  "- Ok will clear the topics displayed\n- Cancel will not change the displayed topics"));
150 
151  QDialogButtonBox *button_box = new QDialogButtonBox(QDialogButtonBox::Ok
152  | QDialogButtonBox::Cancel);
153  no_topics_dialog->layout()->addWidget(button_box);
154 
155  connect(button_box, &QDialogButtonBox::accepted, no_topics_dialog, &QDialog::accept);
156  connect(button_box, &QDialogButtonBox::rejected, no_topics_dialog, &QDialog::reject);
157 
158  if (!no_topics_dialog->exec())
159  {
160  Q_EMIT setEnabled(true);
161  return;
162  }
163 
164  displayed_topics_.clear();
165  Q_EMIT configChanged();
167  Q_EMIT setEnabled(true);
168  return;
169  }
170 
171  QDialog *pick_topics_dialog = new QDialog(this);
172  pick_topics_dialog->setWindowTitle("Pick displayed topics");
173  QVBoxLayout *layout = new QVBoxLayout;
174  pick_topics_dialog->setLayout(layout);
175  layout->addWidget(new QLabel("Only supported built-in types are displayed"));
176 
177  std::vector<QCheckBox *> topic_buttons;
178  for (auto topic : supported_topics)
179  {
180  QCheckBox *radio_button = new QCheckBox;
181 
182  if (displayed_topics_.find(topic.name) != displayed_topics_.end())
183  radio_button->setChecked(true);
184 
185  topic_buttons.push_back(radio_button);
186  radio_button->setText(QString::fromStdString(topic.name));
187  radio_button->setToolTip(QString::fromStdString(topic.datatype));
188  pick_topics_dialog->layout()->addWidget(radio_button);
189  }
190 
191  QDialogButtonBox *button_box = new QDialogButtonBox(QDialogButtonBox::Ok
192  | QDialogButtonBox::Cancel);
193  pick_topics_dialog->layout()->addWidget(button_box);
194 
195  connect(button_box, &QDialogButtonBox::accepted, pick_topics_dialog, &QDialog::accept);
196  connect(button_box, &QDialogButtonBox::rejected, pick_topics_dialog, &QDialog::reject);
197 
198  if (!pick_topics_dialog->exec())
199  {
200  Q_EMIT setEnabled(true);
201  return;
202  }
203 
204  Q_EMIT configChanged();
205 
206  displayed_topics_.clear();
207  for (auto button : topic_buttons)
208  {
209  if (!button->isChecked())
210  continue;
211 
212  displayed_topics_.insert(std::pair<std::string, std::string>(button->text().toStdString(),
213  button->toolTip().toStdString()));
214  }
215 
217  Q_EMIT setEnabled(true);
218 }
219 
221 {
222  table_->setRowCount(0);
223  table_->setRowCount(displayed_topics_.size());
224 
225  topic_infos_.clear();
226  for (auto topic : displayed_topics_)
227  {
228  std::shared_ptr<TopicInfo> topic_info(new TopicInfo(topic.first, topic.second));
229  topic_infos_.push_back(topic_info);
230  }
231 
232  unsigned i(0);
233  for (auto topic_info : topic_infos_)
234  {
235  table_->setCellWidget(i, 0, topic_info->label_.get());
236  table_->setCellWidget(i, 1, topic_info->display_.get());
237  ++i;
238  }
239 }
240 
242  const QString message,
243  const QString info_msg,
244  const QMessageBox::Icon icon)
245 {
246  const bool old(isEnabled());
247  Q_EMIT setEnabled(false);
248  QMessageBox msg_box;
249  msg_box.setWindowTitle(title);
250  msg_box.setText(message);
251  msg_box.setInformativeText(info_msg);
252  msg_box.setIcon(icon);
253  msg_box.setStandardButtons(QMessageBox::Ok);
254  msg_box.exec();
255  Q_EMIT setEnabled(old);
256 }
257 
258 }
259 
void displayMessageBoxHandler(const QString title, const QString message, const QString info_msg="", const QMessageBox::Icon icon=QMessageBox::Icon::Information)
ROSCPP_DECL bool getTopics(V_TopicInfo &topics)
std::vector< std::shared_ptr< TopicInfo > > topic_infos_
void configChanged()
std::vector< TopicInfo > V_TopicInfo
virtual void save(rviz::Config config) const
bool mapGetString(const QString &key, QString *value_out) const
void mapSetValue(const QString &key, QVariant value)
virtual void setName(const QString &name)
virtual void load(const rviz::Config &config)
std::map< std::string, std::string > displayed_topics_
virtual QString getName() const
DisplayTopics(QWidget *parent=NULL)
void displayMessageBox(const QString, const QString, const QString, const QMessageBox::Icon)
virtual void save(Config config) const
virtual void load(const Config &config)
#define PLUGINLIB_EXPORT_CLASS(class_type, base_class_type)


topics_rviz_plugin
Author(s): Victor Lamoine - Institut Maupertuis
autogenerated on Mon Jun 10 2019 15:34:43