title: 搭建qt+ros的开发环境(二)
date: 2020-07-08 19:52:00
tags: 记录
通过上一篇博客创建的gui_pkg,这里要做的是在QT视图中显示ROS话题发布与接收的消息以及加上一个按键测试。
系统:ubuntu14
软件:Qt5.9.1Creator
继续上一篇记录的内容,两条命令创建了两个package.
catkin_create_pkg topic_pkg std_msgs roscpp
catkin_create_qt_pkg gui_pkg
在main_window.ui
文件加入List View、Push Button、Label
控件,List View
名字改为view_logging
,Push Button
改名为sent_cmd
。记得编译一下,这样控件才会加到main_window.h
文件。如图:
在qnode.hpp
文件加入代码,这里记得增加头文件#include "std_msgs/String.h"
。
/**
* @file /include/gui_pkg/qnode.hpp
*
* @brief Communications central!
*
* @date February 2011
**/
/*****************************************************************************
** Ifdefs
*****************************************************************************/
#ifndef gui_pkg_QNODE_HPP_
#define gui_pkg_QNODE_HPP_
/*****************************************************************************
** Includes
*****************************************************************************/
#include <ros/ros.h>
#include <string>
#include <QThread>
#include <QStringListModel>
#include "std_msgs/String.h" //add
/*****************************************************************************
** Namespaces
*****************************************************************************/
namespace gui_pkg {
/*****************************************************************************
** Class
*****************************************************************************/
class QNode : public QThread {
Q_OBJECT
public:
QNode(int argc, char** argv );
virtual ~QNode();
bool init();
bool init(const std::string &master_url, const std::string &host_url);
void run();
void Callback(const std_msgs::String::ConstPtr& msg); //add
void sent_cmd(); //add
/*********************
** Logging
**********************/
enum LogLevel {
Debug,
Info,
Warn,
Error,
Fatal
};
QStringListModel* loggingModel() { return &logging_model; }
void log( const LogLevel &level, const std::string &msg);
QStringListModel* loggingModel_sub() { return &logging_model_sub; } //add
void log_sub( const LogLevel &level, const std::string &msg); //add
Q_SIGNALS:
void loggingUpdated();
void rosShutdown();
void loggingUpdated_sub(); //add
private:
int init_argc;
char** init_argv;
ros::Publisher chatter_publisher;
QStringListModel logging_model;
ros::Subscriber chatter_subscriber; //add
QStringListModel logging_model_sub; //add
};
} // namespace gui_pkg
#endif /* gui_pkg_QNODE_HPP_ */
在main_window.hpp
文件加入代码
/**
* @file /include/gui_pkg/main_window.hpp
*
* @brief Qt based gui for gui_pkg.
*
* @date November 2010
**/
#ifndef gui_pkg_MAIN_WINDOW_H
#define gui_pkg_MAIN_WINDOW_H
/*****************************************************************************
** Includes
*****************************************************************************/
#include <QtGui/QMainWindow>
#include "ui_main_window.h"
#include "qnode.hpp"
/*****************************************************************************
** Namespace
*****************************************************************************/
namespace gui_pkg {
/*****************************************************************************
** Interface [MainWindow]
*****************************************************************************/
/**
* @brief Qt central, all operations relating to the view part here.
*/
class MainWindow : public QMainWindow {
Q_OBJECT
public:
MainWindow(int argc, char** argv, QWidget *parent = 0);
~MainWindow();
void ReadSettings(); // Load up qt program settings at startup
void WriteSettings(); // Save qt program settings when closing
void closeEvent(QCloseEvent *event); // Overloaded function
void showNoMasterMessage();
public Q_SLOTS:
/******************************************
** Auto-connections (connectSlotsByName())
*******************************************/
void on_actionAbout_triggered();
void on_button_connect_clicked(bool check );
void on_checkbox_use_environment_stateChanged(int state);
void pub_cmd(); //add
/******************************************
** Manual connections
*******************************************/
void updateLoggingView(); // no idea why this can't connect automatically
void updateLoggingView_sub(); //add
private:
Ui::MainWindowDesign ui;
QNode qnode;
};
} // namespace gui_pkg
#endif // gui_pkg_MAIN_WINDOW_H
在qnode.cpp
文件加入代码,这里注意回调函数。
chatter_publisher = n.advertise<std_msgs::String>("chatter", 1000);
chatter_subscriber = n.subscribe("chatter", 1000,&QNode::Callback,this); //add
void QNode::log_sub( const LogLevel &level, const std::string &msg) //add
{
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::String::ConstPtr& submsg) //add
{
log_sub(Info,std::string("Success sub:")+submsg->data.c_str());
}
void QNode::sent_cmd() //add
{
if(ros::ok()){
std_msgs::String msg;
std::stringstream ss;
ss << "clicked the button";
msg.data = ss.str();
chatter_publisher.publish(msg);
log(Info, std::string("I sent:")+msg.data);
ros::spinOnce();
}
}
在main_window.cpp
文件加入代码。
MainWindow::MainWindow(int argc, char** argv, QWidget *parent)
: QMainWindow(parent)
, qnode(argc,argv)
{
ui.view_logging_sub->setModel(qnode.loggingModel_sub()); //add
QObject::connect(&qnode, SIGNAL(loggingUpdated_sub()), this, SLOT(updateLoggingView_sub())); //add
QObject::connect(ui.sent_cmd,SIGNAL(clicked()),this,SLOT(pub_cmd()));//add
}
void MainWindow::updateLoggingView_sub() { //add
ui.view_logging_sub->scrollToBottom();
}
void MainWindow::pub_cmd(){ //add
qnode.sent_cmd();
}
最后是运行效果:
参考链接:
https://blog.csdn.net/qq_16481211/article/details/90707043
https://blog.csdn.net/qq_16481211/article/details/90708055
https://blog.csdn.net/u014610460/article/details/79355533
https://blog.csdn.net/Ricardo_lun/article/details/80025024