主要修改5个文件。分别是main_windown.hpp;main_windown.cpp;main_windown.ui;qnode.hpp;qnode.cpp。
直接上代码。
添加控件;添加订阅者部分的代码。
1 main_windown.hpp
#ifndef ros_gui_pub_MAIN_WINDOW_H
#define ros_gui_pub_MAIN_WINDOW_H
#include <QtGui/QMainWindow>
#include "ui_main_window.h"
#include "qnode.hpp"
namespace ros_gui_pub {
class MainWindow : public QMainWindow {
Q_OBJECT
public:
MainWindow(int argc, char** argv, QWidget *parent = 0);
~MainWindow();
void showNoMasterMessage();
public Q_SLOTS:
void on_button_connect_clicked(bool check );
void updateLoggingView(); // no idea why this can't connect automatically
void updateLoggingView_sub();
private:
Ui::MainWindowDesign ui;
QNode qnode;
};
} // namespace ros_gui_pub
#endif // ros_gui_pub_MAIN_WINDOW_H
1 main_windown.cpp
#include <QtGui>
#include <QMessageBox>
#include <iostream>
#include "../include/ros_gui_pub/main_window.hpp"
namespace ros_gui_pub {
using namespace Qt;
MainWindow::MainWindow(int argc, char** argv, QWidget *parent)
: QMainWindow(parent)
, qnode(argc,argv)
{
ui.setupUi(this); // Calling this incidentally connects all ui's triggers to on_...() callbacks in this class.
setWindowIcon(QIcon(":/images/icon.png"));
ui.view_logging->setModel(qnode.loggingModel());
ui.view_logging_sub->setModel(qnode.loggingModel_sub());
QObject::connect(&qnode, SIGNAL(loggingUpdated()), this, SLOT(updateLoggingView()));
QObject::connect(&qnode, SIGNAL(loggingUpdated_sub()), this, SLOT(updateLoggingView_sub()));
}
MainWindow::~MainWindow() {}
void MainWindow::showNoMasterMessage() {
QMessageBox msgBox;
msgBox.setText("Couldn't find the ros master.");
msgBox.exec();
close();
}
void MainWindow::on_button_connect_clicked(bool check ) {
if ( !qnode.init() ) {
showNoMasterMessage();
} else {
ui.button_connect->setEnabled(false);
}
}
void MainWindow::updateLoggingView() {
ui.view_logging->scrollToBottom();
}
void MainWindow::updateLoggingView_sub() {
ui.view_logging_sub->scrollToBottom();
}
} // namespace ros_gui_pub
3 qnode.hpp
#ifndef ros_gui_pub_QNODE_HPP_
#define ros_gui_pub_QNODE_HPP_
#ifndef Q_MOC_RUN
#include <ros/ros.h>
#include <std_msgs/String.h>
#endif
#include <string>
#include <QThread>
#include <QStringListModel>
namespace ros_gui_pub {
class QNode : public QThread {
Q_OBJECT
public:
QNode(int argc, char** argv );
virtual ~QNode();
bool init();
void run();
enum LogLevel {
Debug,
Info,
Warn,
Error,
Fatal
};
QStringListModel* loggingModel() { return &logging_model; }
QStringListModel* loggingModel_sub() { return &logging_model_sub; }
void log( const LogLevel &level, const std::string &msg);
void log_sub( const LogLevel &level_sub, const std::string &msg_sub);
void Callback(const std_msgs::StringConstPtr& submsg);
Q_SIGNALS:
void loggingUpdated();
void loggingUpdated_sub();
void rosShutdown();
private:
int init_argc;
char** init_argv;
ros::Publisher chatter_publisher;
ros::Subscriber chatter_sublisher;
QStringListModel logging_model;
QStringListModel logging_model_sub;
};
} // namespace ros_gui_pub
#endif /* ros_gui_pub_QNODE_HPP_ */
4 qnode.cpp
#include <ros/ros.h>
#include <ros/network.h>
#include <string>
#include <std_msgs/String.h>
#include <sstream>
#include "../include/ros_gui_pub/qnode.hpp"
namespace ros_gui_pub {
QNode::QNode(int argc, char** argv ) :
init_argc(argc),
init_argv(argv)
{}
QNode::~QNode() {
}
bool QNode::init() {
ros::init(init_argc,init_argv,"ros_gui_pub");
if ( ! ros::master::check() ) {
return false;
}
ros::start(); // explicitly needed since our nodehandle is going out of scope.
ros::NodeHandle n;
// Add your ros communications here.
chatter_publisher = n.advertise<std_msgs::String>("chatter", 1000);
chatter_sublisher = n.subscribe("chatter",1000,&QNode::Callback,this);
start();
return true;
}
void QNode::run() {
ros::Rate loop_rate(1);
int count = 0;
while ( ros::ok() ) {
// ROS_INFO("PUB 111");
std_msgs::String msg;
std::stringstream ss;
ss << "hello world " << count;
msg.data = ss.str();
chatter_publisher.publish(msg);
log(Info,std::string("I sent: ")+msg.data);
ros::spinOnce();
loop_rate.sleep();
++count;
}
std::cout << "Ros shutdown, proceeding to close the gui." << std::endl;
Q_EMIT rosShutdown(); // used to signal the gui for a shutdown (useful to roslaunch)
}
void QNode::log( const LogLevel &level, const std::string &msg) {
logging_model.insertRows(logging_model.rowCount(),1);
std::stringstream logging_model_msg;
switch ( level ) {
case(Debug) : {
ROS_DEBUG_STREAM(msg);
logging_model_msg << "[DEBUG] [" << ros::Time::now() << "]: " << msg;
break;
}
case(Info) : {
ROS_INFO_STREAM(msg);
logging_model_msg << "[INFO] [" << ros::Time::now() << "]: " << msg;
break;
}
case(Warn) : {
ROS_WARN_STREAM(msg);
logging_model_msg << "[INFO] [" << ros::Time::now() << "]: " << msg;
break;
}
case(Error) : {
ROS_ERROR_STREAM(msg);
logging_model_msg << "[ERROR] [" << ros::Time::now() << "]: " << msg;
break;
}
case(Fatal) : {
ROS_FATAL_STREAM(msg);
logging_model_msg << "[FATAL] [" << ros::Time::now() << "]: " << msg;
break;
}
}
QVariant new_row(QString(logging_model_msg.str().c_str()));
logging_model.setData(logging_model.index(logging_model.rowCount()-1),new_row);
Q_EMIT loggingUpdated(); // used to readjust the scrollbar
}
void QNode::log_sub( const LogLevel &level, const std::string &msg) {
logging_model_sub.insertRows(logging_model_sub.rowCount(),1);
std::stringstream logging_model_msg;
switch ( level ) {
case(Debug) : {
ROS_DEBUG_STREAM(msg);
logging_model_msg << "[DEBUG] [" << ros::Time::now() << "]: " << msg;
break;
}
case(Info) : {
ROS_INFO_STREAM(msg);
logging_model_msg << "[INFO] [" << ros::Time::now() << "]: " << msg;
break;
}
case(Warn) : {
ROS_WARN_STREAM(msg);
logging_model_msg << "[INFO] [" << ros::Time::now() << "]: " << msg;
break;
}
case(Error) : {
ROS_ERROR_STREAM(msg);
logging_model_msg << "[ERROR] [" << ros::Time::now() << "]: " << msg;
break;
}
case(Fatal) : {
ROS_FATAL_STREAM(msg);
logging_model_msg << "[FATAL] [" << ros::Time::now() << "]: " << msg;
break;
}
}
QVariant new_row(QString(logging_model_msg.str().c_str()));
logging_model_sub.setData(logging_model_sub.index(logging_model_sub.rowCount()-1),new_row);
Q_EMIT loggingUpdated_sub(); // used to readjust the scrollbar
}
void QNode::Callback(const std_msgs::StringConstPtr& submsg)
{
log_sub(Info,std::string("Success Sub: ") + submsg->data.c_str());
// ROS_INFO("SUB 111");
}
} // namespace ros_gui_pub
5 main_window.ui
注意添加控件名称是 : view_logging_sub