Qt GUI + ROS: where to put the ros parameters?



  • Hi all!

    So, I created a Qt UI in a ROS node and after some fights with CMakeLists I managed to compile it with catkin.

    Now the problem that I have is that I don't know exactly where to put my ROS parameters in the mainwindow.cpp. I have it in a way where I can send messages when I click on the button "Send". However, it only works once because after that the app crashes (I assume the system gets trapped in the while(ros::ok())...)

    This is my mainwindow.cpp code (except some callbacks related to some buttons):

    #include "ros/ros.h"
    #include "mainwindow.h"
    #include "ui_mainwindow.h"
    #include <QtGui/QPushButton>
    #include "globals.h"
    #include <QString>
    #include <string>
    #include <sstream>
    #include "QMessageBox"
    #include "QTimer"
    #include "QTime"
    #include "qtgui/GUIDados.h"
    
    using namespace std;
    using namespace ros;
    
    MainWindow::MainWindow(QWidget *parent) :
        QMainWindow(parent),
        ui(new Ui::MainWindow)
    {
    
        ui->setupUi(this);
        ui->spinBox1->hide();
        ui->spinBox2->hide();
        ui->spinBox3->hide();
        ui->spinBox4->hide();
        ui->spinBox5->hide();
        ui->spinBox6->hide();
        ui->spinBox7->hide();
        ui->spinBox8->hide();
        ui->spinBox9->hide();
        ui->spinBox10->hide();
        ui->spinBox11->hide();
        ui->spinBox12->hide();
        ui->spinBox13->hide();
        ui->spinBox14->hide();
        ui->spinBox15->hide();
        ui->spinBox16->hide();
        ui->spinBoxall->hide();
        numberOfMotors =0;
    
        int argc = 0;
        char **argv;
        ros::init(argc, argv, "qtgui");
        cout << "init" << endl;
    
     /*   TIMER */
       QTimer *timer = new  QTimer(this);
        connect(timer, SIGNAL(timeout()), this, SLOT(showTime()));
        timer->start(1000);
        showTime();
    }
    
    void MainWindow::showTime()
    {
        QTime time = QTime::currentTime();
        QString text = time.toString("hh:mm");
        if ((time.second() % 2) == 0)
            text[2] = ' ';
        cout << "text" << endl;
    }
    
    MainWindow::~MainWindow()
    {
        delete ui;
    }
    
    void MainWindow::on_closeButton_clicked()
    {
        close();
    }
    
    void MainWindow::on_sendButton_clicked()
    {
        QMessageBox::information(this,tr("Titulo"),tr("escolheu: %1").arg( intensidade[0])); //dutycycle do motor1
          ros::NodeHandle n;
        cout << "nodehandle" << endl;
        ros::Publisher QtPublisher = n.advertise<qtgui::GUIDados>("guichattergui",1000);
        ros::Rate loop_rate(10); //10hz
        while(ros::ok())
       {
        qtgui::GUIDados msg;
    
        msg.numeroMotores = numberOfMotors;
        msg.intensidade.resize(16);
        msg.local.resize(16);
        for(int i=0;i<16;i++)
        {
            msg.intensidade[i] = intensidade[i];
            msg.local[i] = local[i];
        }
        QtPublisher.publish(msg);
        ros::spinOnce();
    
        loop_rate.sleep();
       }
    }
    

    What I have so far is that, when I click on send it sends a ros message. I tried to initialize ros in the *MainWindow::MainWindow(QWidget parent) however it didnt exactly work...

    As you probably can guess, I'm very new to this Qt interface thing (and also ROS to be fair), so any help would be useful.
    Where should I put my ros parameters so that this works fine?

    Here's my other parts of the code:
    main.cpp:

    #include "mainwindow.h"
    #include <QtGui/QApplication>
    #include "globals.h"
    #include "qtgui/GUIDados.h"
    
    using namespace std;
    
    int main(int argc, char *argv[])
    {
        std::cout<<"I am Alive!"<<std::endl;
    
        QApplication a(argc, argv); //creates a QApplication object
    
        MainWindow w; //creates the main window object
        w.show();
    
        return a.exec(); //enter its event loop
    }
    
    

    mainwindow.h:

    #ifndef MAINWINDOW_H
    #define MAINWINDOW_H
    #include <QMainWindow>
    
    namespace Ui {
    class MainWindow;
    }
    
    class MainWindow : public QMainWindow
    {
        Q_OBJECT //declares our class as a QObject
    
    public:
        explicit MainWindow(QWidget *parent = 0);
        ~MainWindow();
    
    private slots:
        void showTime();
    
        void on_closeButton_clicked();
    
    private:
        Ui::MainWindow *ui;
    };
    #endif // MAINWINDOW_H
    

    Thank you in advance!


  • Lifetime Qt Champion

    Hi and welcome to devnet,

    From the looks of it, shouldn't you rather have a dedicated object handling the ROS part and it's infinite loop running in a different thread and then have your GUI talk with it ?



  • @SGaist Hi and thank you!

    I have no idea.. As I said, I'm very new to this all ROS and Qt and even c++ thing (the only programming I ever had was matlab for 1 year and C for 1 semester..).

    I'm gonna try the way you said it, and I'll write here what I managed to do.

    Thanks!


  • Lifetime Qt Champion

    Before going further: did you saw the Qt ROS page ?



  • @SGaist Yes!



  • Done! I created a class with my QtPublisher where I initialize my publisher and where I created a function that sends the messages! Now it works perfectly!

    Thanks for the help! :)


  • Lifetime Qt Champion

    Great !

    Since you have it working now, please mark the thread as solved using the "Topic Tools" button so that other forum users may know a solution has been found :)


Log in to reply