0
$\begingroup$

Rosanswers logo

My existing solution simply designs the GUI in qtcreator and then use the uic to generate the dotnect_window.h (link to plugin) which I might have to modify to derive from class ... : public rviz::Panel. How to automate this / do it all?

For example rqt_image_view already uses an .ui file, but it is rqt standalone. So I started with the RViz plugin teleop and added code from rqt_image_view . Maybe I could use the uncommented qt4/5_wrap_ui as a start? Just to give an idea:

cmake_minimum_required(VERSION 2.8.3)
project(rviz_dotnect_plugin)

# ros packages
find_package(catkin REQUIRED COMPONENTS
  rviz
)

catkin_package(
   # INCLUDE_DIRS
   # LIBRARIES ${PROJECT_NAME}
   CATKIN_DEPENDS rviz
   # DEPENDS
)
include_directories(
  ${catkin_INCLUDE_DIRS}
  include
)

link_directories(
  ${catkin_LIBRARY_DIRS}
)

# Bundle headers .h
set(HEADER_FILES
  include/drive_widget.h
  include/teleop_panel.h
)

# Automatically enable Qt's Meta-Object Compiler moc generation
set(CMAKE_AUTOMOC ON)

# Avoid keyword definition to avaid conflicts with boost or xapian etc
# e.g. http://muddyazian.blogspot.de/2012/04/getting-qt-app-working-with-boost-using.html
add_definitions(-DQT_NO_KEYWORDS)

# Use same QT version as rviz and specify headers run through MOC.
# MOC generated .cpp files are included automatically as headers.
if(rviz_QT_VERSION VERSION_LESS "5")
  message(STATUS "Using Qt4 based on the rviz_QT_VERSION: ${rviz_QT_VERSION}")
  find_package(Qt4 ${rviz_QT_VERSION} EXACT REQUIRED QtCore QtGui)
  include(${QT_USE_FILE})
  qt4_wrap_cpp(HEADER_FILES_MOCS ${HEADER_FILES})
  #qt4_wrap_ui(rqt_image_view_UIS_H ${rqt_image_view_UIS})
else()
  message(STATUS "Using Qt5 based on the rviz_QT_VERSION: ${rviz_QT_VERSION}")
  find_package(Qt5 ${rviz_QT_VERSION} EXACT REQUIRED Core Widgets)
  set(QT_LIBRARIES Qt5::Widgets)
  qt5_wrap_cpp(HEADER_FILES_MOCS ${HEADER_FILES})
  #qt5_wrap_ui(rqt_image_view_UIS_H ${rqt_image_view_UIS})
endif()

# Bundle source .cpp including the mocs
set(SOURCE_FILES
src/drive_widget.cpp
src/teleop_panel.cpp
${HEADER_FILES_MOCS}
)

# A rviz plugin is a shared library named ${PROJECT_NAME}.so
add_library(${PROJECT_NAME} ${SOURCE_FILES})

# Link executable with Qt libraries
target_link_libraries(${PROJECT_NAME}
  ${QT_LIBRARIES}
  ${catkin_LIBRARIES}
)

## Install rules...

I went on and generated the header from .ui via $ uic -o dotnect_window.h dotnect_window.ui. But uic deprecated the -i arg to generate the implementation file via uic -i PizzaEntry.h -o PizzaEntry.cpp pizza.ui. Argl.


Also the third step is nowhere to be found inside rqt_image_view.
I get confused with what is a rqt standalone and what I actually need to just get the rviz plugin asrviz::Panel building from .ui.


Originally posted by user23fj239 on ROS Answers with karma: 748 on 2016-08-16

Post score: 1


Original comments

Comment by ahendrix on 2016-08-16:
You definitely shouldn't be doing the conversion from .ui files to C++ code manually; the build system should do that for you. I don't do much work with QT, but the qt4/5_wrap_ui rules look like the right place to start.

$\endgroup$

1 Answer 1

0
$\begingroup$

Rosanswers logo

Here a sample CMakeLists.txt which allowed us to create rviz panels, I'm not quite sure what you need to adapt, however, we had no manual copying to do. Seems like you are missing the MOC_FILES and the UIC_FILES at the add_library() call...

Note that this is Qt4 only, but I guess the Qt5 way should be pretty similar...

find_package(Qt4 COMPONENTS QtCore QtGui REQUIRED)
include(${QT_USE_FILE})

add_definitions(-DQT_NO_KEYWORDS)

set(
  HEADER_FILES
  src/my_panel.h
)

# required if you want to add some images, etc. Could be made differently/nicer, probably.
file(GLOB QT_RESOURCES RELATIVE ${CMAKE_CURRENT_SOURCE_DIR} resource/*.resource)

qt4_add_resources(
  QT_RESOURCES_CPP
  ${QT_RESOURCES}
)

qt4_wrap_cpp(
  MOC_FILES
  ${HEADER_FILES}
)

qt4_wrap_ui(
  UIC_FILES
  resource/my_panel.ui
)

set(
  SOURCE_FILES
  src/my_panel.cpp
)

add_library(my_panel ${SOURCE_FILES} ${QT_RESOURCES_CPP} ${MOC_FILES} ${UIC_FILES})

target_link_libraries(my_panell ${QT_LIBRARIES} ${catkin_LIBRARIES})

# maybe you also need a add_dependencies() call, we did not...

EDIT

Note that this is implemented as a QWidget. Some more templates:

Our header my_panel.h:

#include <ros/ros.h>
#include <rviz/panel.h>

namespace Ui
{
class MyPanelUi;
}

namespace my_panel
{

class MyPanel: public rviz::Panel
{
Q_OBJECT
public:
  MyPanel( QWidget* parent = 0 );
  
  ~MyPanel();
  
protected:
  ros::NodeHandle nh_;

  Ui::MyPanelUi *ui_;
  
private Q_SLOTS:
  // Q_SLOTS for interaction with buttons, etc.
  void gui_button_stop();

  // your custom stuff
}; // MyPanel

}  // my_panel

The my_panel.cpp

#include "my_panel.h"

#include "ui_my_panel.h"

#include <QMessageBox>

namespace my_panel
{

MyPanel::MyPanel( QWidget* parent )
  : rviz::Panel( parent )
  , ui_(new Ui::MyPanelUi())
{
  // set up the GUI
  ui_->setupUi(this);

  // connecting the signals to the respectiv SLOTs
  /*
   * Main Control Buttons *
   */
  // the button is called pushButton_stop in the ui file
  connect( ui_->pushButton_stop, SIGNAL( clicked() ), this, SLOT( gui_button_stop() ));
}

Originally posted by mgruhler with karma: 12390 on 2016-08-18

This answer was ACCEPTED on the original site

Post score: 3


Original comments

Comment by user23fj239 on 2016-08-19:
Great, extensive answer. I will try to port the code and will post the updates once I got first results.

Comment by demorise on 2022-04-14:
Thanks! This really helped.

$\endgroup$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.