[学习笔记]在ros humble里使用qt

张开发
2026/4/9 16:47:33 15 分钟阅读

分享文章

[学习笔记]在ros humble里使用qt
0. 示例:使用qt控制ros小海龟0.1 安装qt creator0.2 创建ROS包依赖只需要ros2的依赖即可qt的依赖单独添加。创建一个resource文件夹待会qt的ui文件放到这里ros2 pkg create qt_test --build-type ament_cmake--dependenciesrclcpp--dependenciesrclcpp std_msgs geometry_msgs --node-name qt_test_node--licenseApache-2.0mkdirresource0.3 使用Qt Designer创建UI界面打开qt designer选择Main Window窗口创建一个按钮(Push Botton)一个输入框(Line Edit)。在右边属性栏修改:将按钮的 objectName 改为 rotatetext 改为“开始旋转”将文本框的 objectName 改为angle;将工程保存到ros2包的resource目录下这将保存一个.ui文件关闭QT设计器。0.4 编写程序/* qt_test_node.hpp */#pragmaonce#includeQMainWindow//Qt头文件#includerclcpp/rclcpp.hpp#includegeometry_msgs/msg/twist.hpp// 包含小乌龟的Twist消息类型#includeui_test.h//*添加生成的头文件 这个文件在编译后的build路径里/* 前置声明 Ui::MainWindow 类。这样可以在头文件中使用 Ui::MainWindow *ui; 指针而无需在头文件中完全包含 ui_main_window.h */QT_BEGIN_NAMESPACEnamespaceUi{classMainWindow;}QT_END_NAMESPACE/* 创建自定义类MainWindow 继承自QT的类QMainWindow */classMainWindow:publicQMainWindow{Q_OBJECT/*QT模对象宏*/public:/* 声明构造函数 explicit防止类型隐式转换 传递ros节点指针便于在qt程序中调用ros通信函数 传递父母窗口指针 */explicitMainWindow(rclcpp::Node::SharedPtr node,QWidget*parentnullptr);~MainWindow();privateslots:voidonRotateButtonClicked();/* 按钮点击事件函数 */private:Ui::MainWindow*ui;/* ui窗口指针 */rclcpp::Node::SharedPtr ros_node_;/* ros节点指针 */rclcpp::Publishergeometry_msgs::msg::Twist::SharedPtr twist_publisher_;/* 角度发布者 */};//qt_test_node.cpp:#includeQApplication//Qt应用头文件#includeQString//Qt字符串类#includerclcpp/rclcpp.hpp#includesstream#includeqt_test_node.hppMainWindow::MainWindow(rclcpp::Node::SharedPtr node,QWidget*parent):QMainWindow(parent),ui(newUi::MainWindow),ros_node_(node){/* 新建ui窗口;传递ros节点 */ui-setupUi(this);/*创建构建并显示界面*/// 创建一个发布者向 /turtle1/cmd_vel 话题发布速度指令twist_publisher_ros_node_-create_publishergeometry_msgs::msg::Twist(/turtle1/cmd_vel,10);// 连接按钮的点击信号到我们的自定义槽函数/* 连接rotate按钮的 信号 到 名为的onRotateButtonClicked自定义槽函数. */connect(ui-rotate,QPushButton::clicked,this,MainWindow::onRotateButtonClicked);}MainWindow::~MainWindow(){deleteui;/* 释放ui指针指向的内存区域 */}/* 自定义槽函数 点击按钮时调用 */voidMainWindow::onRotateButtonClicked(){QString angle_textui-angle-text();/*获取angle构建的文本*/boolok;doubleangleangle_text.toDouble(ok);/*文本转换为浮点数 将结果输出到ok */if(ok){geometry_msgs::msg::Twist twist_msg;twist_msg.angular.zangle;// 设置旋转角速度twist_publisher_-publish(twist_msg);RCLCPP_INFO(ros_node_-get_logger(),Published rotate command with angular velocity: %f,angle);}else{RCLCPP_WARN(ros_node_-get_logger(),Invalid angle input: %s,angle_text.toStdString().c_str());}}intmain(intargc,char*argv[]){rclcpp::init(argc,argv);autonodestd::make_sharedrclcpp::Node(qt_turtle_control_node);// 初始化 ROS2QApplicationapp(argc,argv);// 初始化 Qt 应用MainWindowwindow(node);//创建主窗口对象window.show();//显示对象// 在单独的线程中运行 ROS2 的 spin 函数避免阻塞 Qt 的事件循环rclcpp::executors::SingleThreadedExecutor executor;executor.add_node(node);autospin_threadstd::thread([executor](){executor.spin();});// 进入 Qt 事件循环intresultapp.exec();// 程序退出前的清理工作rclcpp::shutdown();spin_thread.join();returnresult;}CMakeLists.txtcmake_minimum_required(VERSION3.8)project(qt_test)if(CMAKE_COMPILER_IS_GNUCXX OR CMAKE_CXX_COMPILER_ID MATCHESClang)add_compile_options(-Wall-Wextra-Wpedantic)endif()#finddependenciesfind_package(ament_cmake REQUIRED)find_package(rclcpp REQUIRED)find_package(std_msgs REQUIRED)find_package(geometry_msgs REQUIRED)find_package(Qt5 REQUIRED COMPONENTS Widgets)#新增加依赖set(CMAKE_AUTOMOC ON)#启用Qt的MOC元对象编译器qt5_wrap_ui(UI_HEADERS resource/test.ui)# 从.ui 文件生成对应的C头文件add_executable(qt_test_node src/qt_test_node.cpp include/qt_test_node.hpp # 必须添加 ${UI_HEADERS}# 必须添加)target_include_directories(qt_test_node PUBLIC $BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/include$INSTALL_INTERFACE:include${CMAKE_CURRENT_BINARY_DIR}#添加 以寻找build路径下的ui_test.h)target_compile_features(qt_test_node PUBLIC c_std_99 cxx_std_17)# Require C99andC17ament_target_dependencies(qt_test_noderclcppstd_msgsgeometry_msgs)target_link_libraries(qt_test_node Qt5::Widgets)#链接到QT库install(TARGETS qt_test_node DESTINATION lib/${PROJECT_NAME})if(BUILD_TESTING)find_package(ament_lint_auto REQUIRED)#thefollowing line skips the linter which checksforcopyrights#commentthe line when a copyrightandlicense is added to all source filesset(ament_cmake_copyright_FOUND TRUE)#thefollowing line skipscpplint(only works in a git repo)#commentthe line whenthispackage is in a git repoandwhen#acopyrightandlicense is added to all source filesset(ament_cmake_cpplint_FOUND TRUE)ament_lint_auto_find_test_dependencies()endif()ament_package()0.5 测试colcon buildsourceinstall/setup.bash终端1:source/opt/ros/humble/setup.bash ros2 run turtlesim turtlesim_node终端2:sourceinstall/setup.bash ros2 run qt_test qt_test_node

更多文章