ROS与QT的那些事--2 实现订阅者SUB_常驻客栈的博客-程序员秘密

技术标签: ROS与QT的那些事  知识分享  qt  ROS  订阅者  ROS机器人  

主要修改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
在这里插入图片描述

演示

在这里插入图片描述

版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
本文链接:https://blog.csdn.net/qq_50808730/article/details/125584383

智能推荐

kubernetes Service:让客户端发现pod并与之通信_yaohong_kenny的博客-程序员秘密

5.1.Service介绍5.1.1.Serice简介5.1.1.1什么是Service  service是k8s中的一个重要概念,主要是提供负载均衡和服务自动发现。  Service 是由 kube-proxy 组件,加上 iptables 来共同实现的。5.1.1.2.Service的创建  创建Service的方法有两种:  1.通过kubectl e...

source insight项目导入和使用教程_source insight导入代码工程_Alex_designer的博客-程序员秘密

一、引入已存在的源代码项目1、Project下创建新项目2、取一个项目名和一个项目存放文件路径(方便存放索引和一些设置)3、选择你准备查看或修改的项目源代码选择源代码文件夹 点击右边【add All】弹出提示include top level sub-directories表示将添加第一层子目录中 的文件Recursively add lowersub-directories” 、 表示递归的加入底层的子目录中 的文件两...

MySQL大数据量分页查询方法及其优化_平凡的L同学的博客-程序员秘密

原文地址:http://www.cnblogs.com/geningchao/p/6649907.html---方法1: 直接使用数据库提供的SQL语句---语句样式: MySQL中,可用如下方法: SELECT * FROM 表名称 LIMIT M,N---适应场景: 适用于数据量较少的情况(元组百/千级)---原因/缺点: 全表扫描,速度会很慢 且 有的数据库结果集返回不稳定(

2021年Flutter中使用flutter_swiper实现轮播图_swiper可以用于扇形开发吗_duanshuiLu点抗母的博客-程序员秘密

1. 安装插件配置flutter_swiper插件。dependencies: flutter: sdk: flutter flutter_localizations: sdk: flutter date_format: ^1.0.6 flutter_cupertino_date_picker: ^1.0.26+2 # 配置轮播图插件 flutter_swiper: ^1.1.6在pubspec.yaml中配置保存后,在VS Code环境中会自动下载依.

selenium 静默模式运行(mac)_weixin_37997371的博客-程序员秘密

Firefox:貌似比Chrome麻烦,这里推荐macfrom selenium import webdriverdef get_driver_result(url, xpath): option = webdriver.ChromeOptions() option.add_argument('headless') driver = webdriver.Chr...

JMeter学习-009-JMeter 后置处理器实例之 - 正则表达式提取器(二)多参数获取_weixin_30722589的博客-程序员秘密

前文简述了通过后置处理器 - 正则表达式提取器 获取 HTTP请求 响应结果中的特定数据,未看过的亲,敬请参阅JMeter学习-008-JMeter 后置处理器实例之 - 正则表达式提取器(一)。此文主要对正则表达式提取器的 正则表达式、模板、匹配数字,三者的关系,做进一步的讲解。截取商品列表响应结果数据中的一段商品数据如下所示:...

随便推点

第一周C++初步——标准C++String类_豆腐西红柿的博客-程序员秘密

文章目录前言一、标准C++String类是什么?二、使用方法1.C++基本语句2.string类的函数和操作:3.string库函数整体代码实现总结前言第一学期学习了C语言 ,接下来学习C++,两者相似,又有不同,接下来给大家分享这周我对C++的初步了解提示:以下是本篇文章正文内容,下面案例可供参考一、标准C++String类是什么?string类是<string> 头文件定义的由一个变量类型、一个宏和各种操作字符数组的函数,等同于C语言里的<string.h>头文件二、使用方法1.C+.

解决:SVN提交数据失败问题(提示 svn:MKACTIVITY ... 403 Forbidden )_svn mksql 错误_voyager512的博客-程序员秘密

原来是文件的BOM信息捣乱,用UltraEdit重新打开再保存一下就可以了! 附带一篇文章:Subversion是否可以控制中文目录的访问权限?作者: PCplayer    时间: 2006-7-1 18:57     标题: Subversion是否可以控制中文目录的访问权限?可以!经常有朋友问到Subversion是否可以对中文目录进行权限控制,如果可以,该如何配置。经过测试,发现s

chkconfig命令详解_洪文聊架构的博客-程序员秘密

功能说明:chkconfig命令主要用来更新(启动或停止)和查询系统服务的运行级信息。谨记chkconfig不是立即自动禁止或激活一个服务,它只是简单的改变了符号连接。(理解:开机是否启动)语法:chkconfig [--add][--del][--list][系统服务]或chkconfig [--level等级代号>][系统服务][on/off/reset]补充说明:这个是r

python的hmac模块_python中hmac_berry2q的博客-程序员秘密

message = b'Hello, world!'key = b'secret'h = hmac.new(key, message, digestmod='MD5')# 如果消息很长,可以多次调用h.update(msg)print h.hexdigest()其中的key是我们自己生成的,message是要加密的信息,如果消息太长,后续可以通过h.update(msg)来多次添加要加密的信息,加密模式默认为md5。注意:key和message需要传入bytes类型的数据。import ha

2017-12-14-PHP之$_SERVER详解_PFinal社区-【南丞】的博客-程序员秘密

layout title date author desc in_head post PHP之$_SERVER详解 2017-12-14 22:28:02 +0800 南丞 $_SERVER 是一个包含了诸如头信息(header)、路径(path)、以及脚本位置(script locations)等等信息的数组。 ...

结合高斯变异和维数决策逻辑的哈里斯鹰优化算法_心️升明月的博客-程序员秘密

文章目录一、理论基础1、哈里斯鹰优化算法(HHO)2、结合高斯变异和维数决策逻辑的哈里斯鹰优化算法(GCHHO)(1)高斯变异(2)布谷鸟搜索中的维数决策逻辑(3)提出的GCHHO二、仿真实验与结果分析三、参考文献一、理论基础1、哈里斯鹰优化算法(HHO)请参考这里。2、结合高斯变异和维数决策逻辑的哈里斯鹰优化算法(GCHHO)本节将说明如何改进原始HHO以增强原始算法的搜索性能。原始算法的缺点主要是由于探索和开发之间的不平衡导致搜索性能下降。因此,引入了两种机制来改善这种平衡,即高斯变异机制和布

推荐文章

热门文章

相关标签