Robotics StackExchange | Archived questions

add rqt plugin to QMainWindow as QDockWidget (C++)

I have several rqt plugins all written in C++ and want to write my own simple "plugin manager" instead of using the ROS rqt manager. For that I wrote a main.cpp that creates a QMainWindow, than I created a new object of my rqt plugin class.

1. attempt casting MyPlugin to QDockWidget

I tried to cast this object to a QDockWidget. However that doesn't work. What I get is the following error without a window:

[FATAL] [1444370401.501434073]: You must call ros::init() before creating the first NodeHandle
Couldn't find an AF_INET address for []
Couldn't find an AF_INET address for []
[ERROR] [1444370401.502916301]: [registerPublisher] Failed to contact master at [:0].  Retrying...
Couldn't find an AF_INET address for []

Then I added the line ros::init(argc, argv, "rqt_mypkg");, however that crashes the program and I get a Segmentation fault (core dumped)

2. attempt casting MyPlugin to QWidget and add it to a QDockWidget

This results in the same error as above, however if I add the line ros::init(argc, argv, "rqt_mypkg"); I get a window with the QDockWidget but without the rqt plugin itself.

My main.cpp I used:

#include "rqt_mypkg/my_plugin.h"

#include <QMainWindow>
#include <QApplication>
#include <QDockWidget>
#include <QWidget>

#include <ros/ros.h>

using namespace rqt_mypkg;

int main( int argc, char **argv ) {

    // create an application
    QApplication a( argc, argv );

    // tried with and without this line
//    ros::init(argc, argv, "rqt_mypkg");

    // create main window
    QMainWindow w;

    // new rqt plugin
    MyPlugin* myPlugin;
    myPlugin = new MyPlugin();

    // 1. attempt by casting myPlugin to a QDockWidget
    QDockWidget *dockWidget = qobject_cast<QDockWidget*>(myPlugin);
    dockWidget->setAllowedAreas(Qt::LeftDockWidgetArea | Qt::RightDockWidgetArea);
    w.addDockWidget(Qt::RightDockWidgetArea, dockWidget);

    // 2. attempt by casting myPlugin to a QWidget and add it to a QDockWidget
//    QWidget *widget = qobject_cast<QWidget*>(myPlugin);
//    QDockWidget *dock = new QDockWidget();
//    dock->setAllowedAreas(Qt::LeftDockWidgetArea | Qt::RightDockWidgetArea);
//    dock->setWidget(widget);
//    w.addDockWidget(Qt::RightDockWidgetArea, dock);    

    // show main window
    w.show();
    return a.exec();
}

The whole package including the rqt plugin is on GitHub

https://github.com/samuelba/rqt_mypkg

Asked by sam_123 on 2015-10-09 01:34:19 UTC

Comments

Answers

Writing your own main and then trying to use a C++ rqt plugin won't be an easy task. rqt is a framework which does a lot of complex things behind the scene.

If you look into the code you will find that your C++ rqt plugin subclasses from rqt_gui_cpp::Plugin (https://github.com/ros-visualization/rqt/blob/groovy-devel/rqt_gui_cpp/include/rqt_gui_cpp/plugin.h). This class is a Nodelet as well as a qt_gui_cpp::Plugin (https://github.com/ros-visualization/qt_gui_core/blob/groovy-devel/qt_gui_cpp/include/qt_gui_cpp/plugin.h). This class is a QObject and not a widget. Therefore you can't simply cast it to QDockWidget.

A rqt plugin can provide more than one widget throught the PluginContext (https://github.com/ros-visualization/qt_gui_core/blob/1eaff5a7586e78ec4f5bf501d9a3172a5da07b06/qt_gui_cpp/include/qt_gui_cpp/plugin_context.h#L82). If you want to implement your own main you need to use the same API and mimic the behavior in order to leverage existing plugins.

Asked by Dirk Thomas on 2015-10-09 11:21:56 UTC

Comments