从代码解析QT开发ROS交互界面

1 篇文章 2 订阅

一、main.cpp

在这里插入图片描述

- QApplication

  1. 首先代码映入眼帘的就是QApplication app(argc, argv),这句是QApplication管理GUI程序的控制流和主要设置,QApplication包含窗口系统和其他来源处理过和发送过的主事件循环。它也处理应用程序的初始化和收尾工作,并提供对话管理。QApplication可以对系统和应用的大部分设置项进行设置。
  2. 对于用Qt写的任何一个GUI应用,不管这个应用有没有窗口或多少个窗口,有且只有一个QApplication对象
  3. 而对于用Qt写的非GUI应用,则有且只有一个QCoreApplication对象,并且这个应用不依赖QtGui库
    这个QApplication对象的指针可以通过instance()函数获取,它和一个全局指针qApp等价。

QApplication的主要功能是:

功能描述
使用所在桌面的参数调色板(palette())、字体(font())、双击间隔(doubleClickInterval())等信息初始化应用程序。当我们改变桌面的一些设置时,可以让应用程序的这些设置保持一致。
从底层窗口系统接收事件并通过sendEvent()postEvent()发送给需要的窗口。
通过解析命令行参数来设置程序内部状态
改变应用程序的外观在运行时,可以通过setStyle()函数来改变QApplication包含的一个QStyle对象。
制定程序的颜色策略详见setColorSpec()函数说明。
设置本地化的字符串通过translate()函数
还包含一些非常方便的类例如屏幕信息类(desktop())和剪切板类(clipboard())
包含所有窗口的信息可以知道程序在屏幕上的位置(widgetAt()),顶层窗口列表(topLevelWidgets()),关闭所有窗口(closeAllWindows())等等
能够管理鼠标光标样式参照setOverrideCursor()
提供刷新和同步通讯流的函数参看flushX()syncX()
提供全面的与用户交互界面当用户注销时,可以正常关闭;如果不能终止程序,它能取消关机进程;甚至可以保存程序全部状态。参看 isSessionRestored(),sessionId() and commitData() and saveState()

-既然QApplication做了这么多初始化工作,因此它必须在创建其他与用户界面相关的类之前创建。QApplication能够处理命令行参数,所以在想要处理命令行参数之前就要创建它。

头文件继承于
#includeQCoreApplication

- <ros_qt>::MainWindow

第二句就是ros_qt::MainWindow w(argc, argv),首先解释一下<ros_qt>,这是自己定义的一个命名空间(当然ros_qt的定义放在了头文件中了),如图所示:
在这里插入图片描述
其中w(argc, argv)就是创建了一个界面对象。

之后三句:

w.show(); //使用了`.show()`方法才能显示QT界面
app.connect(&app, SIGNAL(lastWindowClosed()), &app, SLOT(quit())); //使用`connect()`槽函数作用是获取到关闭窗口信号后处理上一个窗口的关闭,确保所有窗口都能正常退出。
 
int result = app.exec(); //使用`.exec()`方法来确保程序在不断循环,直到关闭窗口
  • 总结: main函数写法都比较简洁,主要作用是规定窗口对象及其属性以及让QT窗口能保持直到点击关闭或者退出。

二、qnode

qnode在ROS交互界面开发起到了非常重要的作用,使用qnode提前设好的规则可以更快速更方便地进行节点的:初始化、定义、属性修改、log日志记录设定。首先来看一下qnode.h如何编写:

  1 /*****************************************************************************
  2 ** Ifdefs
  3 *****************************************************************************/
  4 
  5 #ifndef ros_qt_QNODE_HPP_
  6 #define ros_qt_QNODE_HPP_
  7 
  8 /*****************************************************************************
  9 ** Includes
 10 *****************************************************************************/
 11 #include <ros/ros.h>
 13 #include <string>
 14 #include <std_msgs/Float64.h>
 15 #include <std_msgs/Int32.h>
 16 #include <QThread>
 17 #include <QStringListModel>
 18 #include <cv_bridge/cv_bridge.h>
 19 #include <image_transport/image_transport.h>
 20 #include <sensor_msgs/image_encodings.h>
 21 #include <sensor_msgs/Image.h>
 22 #include <geometry_msgs/Twist.h>
 23 
 24 #include <opencv2/opencv.hpp>
 25 #include <QImage>
 26 
 27 /*****************************************************************************
 28 ** 自定义信号参数类型
 29 *****************************************************************************/
 30 
 31 
 32 /*****************************************************************************
 33 ** Namespaces
 34 *****************************************************************************/
 35 
 36 namespace ros_qt {
 37 
 38 /*****************************************************************************
 39 ** Class
 40 *****************************************************************************/
 41 
 42 class QNode : public QThread {
 43     Q_OBJECT
 44 public:
 45     QNode(int argc, char** argv );
 46     virtual ~QNode();
 47     bool init();
 48     bool init(const std::string &master_url, const std::string &host_url);
 49     void run();
 50     void myCallback(const std_msgs::Float64& message_holder);
 51     void Comp_videoCallback(const sensor_msgs::CompressedImageConstPtr& msg);
 52     void Image_videoCallback(const sensor_msgs::Image& msg);
 53     void sound_SensorCallback_F(const std_msgs::Int32& msg);
 54     void sound_SensorCallback_R(const std_msgs::Int32& msg);
 55     void speed_Callback_L(const std_msgs::Int32& msg);
 56     void speed_Callback_R(const std_msgs::Int32& msg);
 57     void angle_Callback_X(const std_msgs::Int32& msg);
 58     void angle_Callback_Y(const std_msgs::Int32& msg);
 59     void lidarDistance_Callback(const std_msgs::Int32& msg);
 60     void odomeData_Callback(const std_msgs::Int32& msg);
 61     void move_base(char k, float speed_linear, float speed_trun);
 62 
 63     /*********************
 64     ** Logging
 65     **********************/
 66     enum LogLevel {
 67              Debug,
 68              Info,
 69              Warn,
 70              Error,
 71              Fatal
 72      };
 73 
 74     QStringListModel* loggingModel() { return &logging_model; }
 75     void log_Float64( const LogLevel &level, const std_msgs::Float64 &msg);
 76     void log_Int32( const LogLevel &level, const std_msgs::Int32 &msg);
 77 
 78 Q_SIGNALS:
 79     void loggingUpdated();
 80     void rosShutdown();
 81     void Show_image(QImage);
 82     void Show_soundSensor_F(qint32);
 83     void Show_soundSensor_R(qint32);
 84     void Show_speedData_L(qint32);
 85     void Show_speedData_R(qint32);
 86     void Show_angleData_X(qint32);
 87     void Show_angleData_Y(qint32);
 88     void Show_lidarDistance(qint32);
 89     void Show_odomeData(qint32);
 90 
 91 private:
 92     int init_argc;
 93     char** init_argv;
 94     /************* Subscriber ********************/
 95     ros::Subscriber chatter_subscriber;
 96     ros::Subscriber video_subscriber;
 97     ros::Subscriber sound_subscriber_F;
 98     ros::Subscriber sound_subscriber_R;
 99     ros::Subscriber speed_subscriber_L;
100     ros::Subscriber speed_subscriber_R;
101     ros::Subscriber angle_subscriber_X;
102     ros::Subscriber angle_subscriber_Y;
103     ros::Subscriber lidarDistance_subscriber;
104     ros::Subscriber odomeData_subscriber;
105 
106     /************* Publisher ********************/
107     ros::Publisher cmd_pub;
108 
109     QStringListModel logging_model;
110     QImage Mat2QImage(cv::Mat const &src);
111 };
112 
113 }  // namespace ros_qt
114 
115 #endif /* ros_qt_QNODE_HPP_ */

解析:

  • 在qnode.h头文件中添加自定义回调函数定义,如图所示:
    在这里插入图片描述

  • 添加自定义QT信号函数,如图所示:
    在这里插入图片描述

  • 添加自定义ROS节点接收话题对象,如图所示:
    在这里插入图片描述

  • 添加自定义ROS节点发布话题对象,如图所示:
    在这里插入图片描述

  • 总结:qnode.h主要是定义了节点初始化、属性、回调函数、信号函数、发布话题对象、接收话题对象,主类名为QNode派生于QTheard,以后需要添加自定义的节点、信号只需要在对应部分添加定义即可。

Tips:固然qnode.h实现于qnode.cpp

三、ROS-QT界面设计

前面小节讲了QT程序的基本定义和使用以及如何添加qnode的节点定义、信号、发布、订阅,接下来讲解如何设计ROS的QT界面并使用。

1、使用Qt Designer设计界面

安装了QT后可以使用Qt Designer的自带控件进行界面绘制,并在编译运行后自动生成main_window.ui文件和ui_main_window.h文件。
打开Qt Designer后如图所示,使用左侧自带控件即可绘制ui界面,创建的时候尽量取好窗口名,防止后续编程乱套:
在这里插入图片描述
在绘制ui界面的时候可以根据右侧的属性编辑器对控件进行修改,包括尺寸、标题、派生对象、文字格式等等。
在这里插入图片描述

绘制完成后,需要记住自己控件的名字,方便以后编程使用,如果不记得自己的控件名了,可以在对象查看器选中后在属性编辑器上查看,如图所示:
在这里插入图片描述

2、加入QT ui到ROS功能包

绘制完成并运行后会生成两个文件,一个三ui_main_window.h,一个是main_window.ui,需要将这两个文件添加到ROS功能包中:

# 进入功能包
cd <功能包名字>

# 创建ui目录
mkdir ui

# 拷贝ui文件到ui目录中
cp <main_window.ui文件路径> ui

# 拷贝ui_main_window.h到头文件目录
cp <ui_main_window.h头文件目录> include

放置完成后如图所示:

在这里插入图片描述
其中resources就是放ui设计的时候使用的图片等需要一些加载的源文件,如果没有就可以不用添加。

3、实现控件功能

设计好界面ui后,就需要根据自己的ui_main_window.h实现控件的功能,在src中添加main_window.cpp实现功能。
在这里插入图片描述

  • 6
    点赞
  • 44
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

JR_Sim

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值