ROS Resources: Documentation | Support | Discussion Forum | Index | Service Status | ros @ Robotics Stack Exchange
Ask Your Question
0

How to Add Callbacks for a QTWidget in ROS?

asked 2014-10-16 10:51:01 -0500

ish45 gravatar image

updated 2014-10-16 11:18:48 -0500

gvdhoorn gravatar image

I am intending to develop a user interface using rqt in ros. I have developed a user interface containing a QTPushButton and QTLabel in QT Designer. I have imported this ui file into my Python Plugin. So, when I run the plugin, the user interface does pop up. But now I want to add a callback to the PushButton. So, that if I press the Button then the label should show the text "Button Clicked". I have tried many code snippets, but somehow nothing happens when I click the Button.

Can somebody please help. It is very urgent. Can somebody write the actual code for the callback.

My Plugin.py file is given below:

import os

import rospy

import rospkg

from qt_gui.plugin import Plugin

from python_qt_binding import loadUi

from python_qt_binding.QtGui import QWidget, QPushButton, QLabel

class MyPlugin(Plugin):

def __init__(self, context):

   super(MyPlugin, self).__init__(context)

   self.setObjectName('MyPlugin')  

    from argparse import ArgumentParser

    parser = ArgumentParser()

    parser.add_argument("-q", "--quiet", action="store_true", dest="quiet",
                         help="Put plugin in silent mode")

    args, unknowns = parser.parse_known_args(context.argv())

        if not args.quiet:
               print 'arguments: ', args
               print 'unknowns: ', unknowns

           # Create QWidget
        self._widget = QWidget()
           # Get path to UI file which should be in the "resource" folder of this package
        ui_file = os.path.join(rospkg.RosPack().get_path('rqt_mypkg'), 'resource', 'mainwindow.ui')
           # Extend the widget with all attributes and children from UI file
        loadUi(ui_file, self._widget)

        # Give QObjects reasonable names
        self._widget.setObjectName('MyPluginUi')
          # Show _widget.windowTitle on left-top of each plugin (when 
         # it's set in _widget). This is useful when you open multiple 
           # plugins at once. Also if you open multiple instances of your 
           # plugin at once, these lines add number to make it easy to 
           # tell from pane to pane.
        if context.serial_number() > 1:
               self._widget.setWindowTitle(self._widget.windowTitle() + (' (%d)' % context.serial_number()))
           # Add widget to the user interface
        context.add_widget(self._widget)

        self.text = QLabel("Data")
         pushButton = QPushButton("Click Here")
        pushButton.clicked.connect(self.buttonClicked)


    def buttonClicked(self):
        print("Button Clicked")
        self.text.setText("Button Has been Clicked")

Also, my ui file looks like this "mainwindow.ui":

<ui version="4.0">
  <class>Form</class>
  <widget class="QWidget" name="Form">
    <property name="geometry">
      <rect>
        <x>0</x>
        <y>0</y>
        <width>400</width>
        <height>300</height>
      </rect>
    </property>
    <property name="windowTitle">
      <string>Form</string>
    </property>
    <widget class="QPushButton" name="pushButton">
      <property name="geometry">
        <rect>
          <x>80</x>
          <y>180</y>
          <width>98</width>
          <height>27</height>
        </rect>
      </property>
      <property name="text">
        <string>PushButton</string>
      </property>
    </widget>
    <widget class="QLabel" name="label">
      <property name="geometry">
        <rect>
          <x>100</x>
          <y>80</y>
          <width>66</width>
          <height>17</height>
        </rect>
      </property>
      <property name="text">
        <string>TextLabel</string>
      </property>
    </widget>
  </widget>
  <resources/>
  <connections/>
</ui>
edit retag flag offensive close merge delete

Comments

It looks like you're creating a new button rather than retrieving the existing button that is created by the UI file.

ahendrix gravatar image ahendrix  ( 2014-10-16 11:52:20 -0500 )edit

Can you tell me how to reference the button from the UI File?

ish45 gravatar image ish45  ( 2014-10-16 11:53:37 -0500 )edit

Can somebody please help?

ish45 gravatar image ish45  ( 2014-10-16 12:50:59 -0500 )edit

I don't know how to retrieve a button that is created by the UI file offhand, but it shouldn't be hard to find a QT tutorial online.

ahendrix gravatar image ahendrix  ( 2014-10-16 13:18:56 -0500 )edit

I have searched the web for the last 2 days. But could not find a way of referencing the buttons from the ui file. I hope somebody else would be able to answer. It should be easy I suppose.

ish45 gravatar image ish45  ( 2014-10-16 13:23:04 -0500 )edit

I did this search: https://www.google.com/webhp?sourceid... and the first link (for me) looks like a fairly good reference: http://pyqt.sourceforge.net/Docs/PyQt... .

ahendrix gravatar image ahendrix  ( 2014-10-16 13:30:15 -0500 )edit

Thanks. I would have a look at these.

ish45 gravatar image ish45  ( 2014-10-16 14:16:48 -0500 )edit

There is a helper function in python_qt_binding called loadUi that will make things easier and more portable than those links. I have detailed its use below.

Aaron Blasdel gravatar image Aaron Blasdel  ( 2014-10-17 16:23:49 -0500 )edit

1 Answer

Sort by ยป oldest newest most voted
0

answered 2014-10-17 16:21:53 -0500

Aaron Blasdel gravatar image

updated 2014-10-17 16:26:57 -0500

The rqt system uses the "LoadUi" helper function to load ui files from python_qt_binding

It is imported like so:

from python_qt_binding import loadUi

And called like this:

ui_file = *PATH TO YOUR UI FILE*
my_widget = *WIDGET TO LOAD YOUR UI FILE INTO*
loadUi(ui_file, my_widget)

Each widget is loaded as a child widget to "my_widget" and it can be accessed using the name you gave it in the ui_file as so:

my_widget.load_button.hide()
my_widget.save_button.setText('')

Then simply connect the relevant callbacks as so:

my_widget.load_button.clicked.connect(self.load_callback_function)

If you want to see a working example please look at rqt_msg here:

https://github.com/ros-visualization/rqt_common_plugins/blob/groovy-devel/rqt_msg/src/rqt_msg/messages_widget.py
https://github.com/ros-visualization/rqt_common_plugins/blob/groovy-devel/rqt_msg/resource/messages.ui
edit flag offensive delete link more

Comments

Thanks. Yes, I have got this working now. I did not know that each widget would be a child widget of my_widget as in this case.

Thanks to you anyway. It was quite easy in the end.

ish45 gravatar image ish45  ( 2014-10-17 17:01:00 -0500 )edit

Question Tools

1 follower

Stats

Asked: 2014-10-16 10:51:01 -0500

Seen: 1,669 times

Last updated: Oct 17 '14