master_chooser.py
Go to the documentation of this file.
00001 #!/usr/bin/env python
00002 #
00003 # License: BSD
00004 #   https://raw.github.com/robotics-in-concert/rocon_qt_gui/license/LICENSE
00005 #
00006 ##############################################################################
00007 # Imports
00008 ##############################################################################
00009 
00010 import os
00011 import sys
00012 
00013 from python_qt_binding import loadUi
00014 from python_qt_binding.QtCore import Qt, QSize  # QFile, QIODevice, QAbstractListModel, pyqtSignal, QStringList
00015 from python_qt_binding.QtGui import QIcon, QWidget, QLabel  # QFileDialog, QGraphicsScene, QImage, QPainter, QComboBox
00016 from python_qt_binding.QtGui import QSizePolicy, QTextEdit, QPushButton, QDialog  # QCompleter, QBrush, QPen, QColor
00017 from python_qt_binding.QtGui import QMainWindow, QCheckBox
00018 
00019 from python_qt_binding.QtGui import QGridLayout, QVBoxLayout, QHBoxLayout, QMessageBox  # QTabWidget, QPlainTextEdit
00020 #from PyQt4.QtSvg import QSvgGenerator
00021 
00022 import rospkg
00023 from rocon_console import console
00024 import rocon_python_utils
00025 
00026 from .rocon_masters import RoconMasters
00027 from . import utils
00028 
00029 ##############################################################################
00030 # Main Window
00031 ##############################################################################
00032 
00033 
00034 class QMasterChooser(QMainWindow):
00035 
00036     rocon_remocon_script = utils.find_rocon_remocon_script('rocon_remocon')
00037     rocon_remocon_sub_script = utils.find_rocon_remocon_script('rocon_remocon_sub')
00038 
00039     def __init__(self, parent, title, application):
00040         self._context = parent
00041         self.application = application
00042         super(QMasterChooser, self).__init__()
00043         utils.setup_home_dirs()
00044 
00045         self._init_widget()
00046         self._init_interface()
00047 
00048         # start application
00049         self._widget_main.show()
00050         self._widget_main.activateWindow()  # give it the focus
00051         self._widget_main.raise_()          # make sure it is on top
00052         self._update_rocon_master_list()
00053 
00054     def __del__(self):
00055         console.loginfo("RemoconMain: Destroy")
00056 
00057     def _init_host_configuration(self):
00058         self.host_name = "localhost"
00059         self.master_uri = "http://%s:11311" % (self.host_name)
00060 
00061         self.env_host_name = os.getenv("ROS_HOSTNAME")
00062         self.env_master_uri = os.getenv("ROS_MASTER_URI")
00063         if self.env_host_name:
00064             self.host_name = self.env_host_name
00065         if self.env_master_uri == None:
00066             self.env_master_uri = "http://%s:11311" % (self.host_name)
00067         elif self.env_master_uri:
00068             self.master_uri = self.env_master_uri
00069 
00070     def _init_icon_paths(self):
00071         self.icon_paths = {}
00072         try:
00073             self.icon_paths['unknown'] = rocon_python_utils.ros.find_resource_from_string('rocon_icons/unknown', extension='png')
00074         except (rospkg.ResourceNotFound, ValueError):
00075             console.logerror("Remocon : couldn't find icons on the ros package path (install rocon_icons and rocon_bubble_icons")
00076             sys.exit(1)
00077 
00078     def _init_widget(self):
00079         self._init_icon_paths()
00080 
00081         self.setObjectName('Remocon')
00082         self._widget_main = QWidget()
00083 
00084         rospack = rospkg.RosPack()
00085         path = os.path.join(rospack.get_path('rocon_remocon'), 'ui', 'remocon.ui')
00086         loadUi(path, self._widget_main)
00087 
00088         # main widget
00089         self._widget_main.list_widget.setIconSize(QSize(50, 50))
00090         self._widget_main.list_widget.itemDoubleClicked.connect(self._connect_rocon_master)  # list item double click event
00091         self._widget_main.list_widget.itemClicked.connect(self._select_rocon_master)  # list item double click event
00092 
00093         self._widget_main.add_concert_btn.pressed.connect(self._set_add_rocon_master)  # add button event
00094         self._widget_main.delete_btn.pressed.connect(self._delete_rocon_master)  # delete button event
00095         self._widget_main.delete_all_btn.pressed.connect(self._delete_all_rocon_masters)  # delete all button event
00096         self._widget_main.refresh_btn.pressed.connect(self._refresh_all_rocon_master_list)  # refresh all button event
00097 
00098         self._widget_main.list_info_widget.clear()
00099 
00100     def _init_interface(self):
00101         self._init_host_configuration()
00102 
00103         self.rocon_masters = RoconMasters()
00104         self._connect_dlg = None
00105         self.cur_selected_rocon_master = None
00106         self._is_init = True
00107 
00108     def _delete_all_rocon_masters(self):
00109         self.rocon_masters.clear()
00110         self._update_rocon_master_list()
00111         self._widget_main.list_info_widget.clear()
00112 
00113     def _delete_rocon_master(self):
00114         if self.cur_selected_rocon_master in self.rocon_masters.keys():
00115             self.rocon_masters.delete(self.cur_selected_rocon_master)
00116         self._update_rocon_master_list()
00117         self._widget_main.list_info_widget.clear()
00118 
00119     def _add_rocon_master(self, uri_text_widget, host_name_text_widget):
00120         rocon_master = self.rocon_masters.add(uri_text_widget.toPlainText(), host_name_text_widget.toPlainText())
00121         self._refresh_rocon_master(rocon_master)
00122 
00123     def _set_add_rocon_master(self):
00124         if self._connect_dlg:
00125             console.logdebug("Dialog is live!!")
00126             self._connect_dlg.done(0)
00127 
00128         self._connect_dlg = self._create_add_rocon_master_dialog()
00129         self._connect_dlg.setVisible(True)
00130         self._connect_dlg.finished.connect(self._destroy_connect_dlg)
00131 
00132     def _refresh_rocon_master(self, rocon_master):
00133         rocon_master.check()
00134         self._widget_main.list_info_widget.clear()
00135         self._update_rocon_master_list()
00136 
00137     def _refresh_all_rocon_master_list(self):
00138         self.rocon_masters.check()
00139         self._widget_main.list_info_widget.clear()
00140         self._update_rocon_master_list()
00141 
00142     def _update_rocon_master_list(self):
00143         self._widget_main.list_widget.clear()
00144         for rocon_master in self.rocon_masters.values():
00145             self._add_rocon_master_list_item(rocon_master)
00146         self.rocon_masters.dump()
00147 
00148     def _add_rocon_master_list_item(self, rocon_master):
00149 
00150         rocon_master.current_row = str(self._widget_main.list_widget.count())
00151 
00152         display_name = str(rocon_master.name) + "\n" + "[" + str(rocon_master.uri) + "]"
00153         self._widget_main.list_widget.insertItem(self._widget_main.list_widget.count(), display_name)
00154 
00155         # setting the list font
00156         font = self._widget_main.list_widget.item(self._widget_main.list_widget.count() - 1).font()
00157         font.setPointSize(13)
00158         self._widget_main.list_widget.item(self._widget_main.list_widget.count() - 1).setFont(font)
00159 
00160         # setToolTip
00161         rocon_master_info = ""
00162         rocon_master_info += "rocon_master_index: " + str(rocon_master.index) + "\n"
00163         rocon_master_info += "rocon_master_name: " + str(rocon_master.name) + "\n"
00164         rocon_master_info += "master_uri:  " + str(rocon_master.uri) + "\n"
00165         rocon_master_info += "host_name:  " + str(rocon_master.host_name) + "\n"
00166         rocon_master_info += "description:  " + str(rocon_master.description)
00167         self._widget_main.list_widget.item(self._widget_main.list_widget.count() - 1).setToolTip(rocon_master_info)
00168 
00169         # set icon
00170         if rocon_master.icon == "unknown.png":
00171             icon = QIcon(self.icon_paths['unknown'])
00172             self._widget_main.list_widget.item(self._widget_main.list_widget.count() - 1).setIcon(icon)
00173         elif len(rocon_master.icon):
00174             icon = QIcon(os.path.join(utils.get_icon_cache_home(), rocon_master.icon))
00175             self._widget_main.list_widget.item(self._widget_main.list_widget.count() - 1).setIcon(icon)
00176         else:
00177             console.logdebug("%s : No icon" % rocon_master.name)
00178 
00179     def _select_rocon_master(self, Item):
00180         list_widget = Item.listWidget()
00181         for k in self.rocon_masters.values():
00182             if k.current_row == str(list_widget.currentRow()):
00183                 self.cur_selected_rocon_master = k.index
00184                 break
00185         self._widget_main.list_info_widget.clear()
00186         info_text = "<html>"
00187         info_text += "<p>-------------------------------------------</p>"
00188         info_text += "<p><b>name: </b>" + str(self.rocon_masters[self.cur_selected_rocon_master].name) + "</p>"
00189         info_text += "<p><b>master_uri: </b>" + str(self.rocon_masters[self.cur_selected_rocon_master].uri) + "</p>"
00190         info_text += "<p><b>host_name: </b>" + str(self.rocon_masters[self.cur_selected_rocon_master].host_name) + "</p>"
00191         info_text += "<p><b>description: </b>" + str(self.rocon_masters[self.cur_selected_rocon_master].description) + "</p>"
00192         info_text += "<p>-------------------------------------------</p>"
00193         info_text += "</html>"
00194         self._widget_main.list_info_widget.appendHtml(info_text)
00195 
00196     def _destroy_connect_dlg(self):
00197         self._connect_dlg = None
00198 
00199     def _connect_rocon_master(self):
00200         rocon_master_name = str(self.rocon_masters[self.cur_selected_rocon_master].name)
00201         rocon_master_uri = str(self.rocon_masters[self.cur_selected_rocon_master].uri)
00202         rocon_master_host_name = str(self.rocon_masters[self.cur_selected_rocon_master].host_name)
00203 
00204         rocon_master_index = str(self.cur_selected_rocon_master)
00205         self.rocon_masters[rocon_master_index].check()
00206         # Todo this use of flags is spanky
00207         if self.rocon_masters[rocon_master_index].flag == '0':
00208             QMessageBox.warning(self, 'Rocon Master Connection Error', "Could not find a rocon master at %s" % self.rocon_masters[rocon_master_index].uri, QMessageBox.Ok)
00209             return
00210         if self.rocon_masters[rocon_master_index].flag == '1':
00211             QMessageBox.warning(self, 'Rocon Master Communication Error', "Found a rocon master at %s but cannot communicate with it (are ROS_IP/ROS_MASTER_URI correctly configured locally and remotely?)" % self.rocon_masters[rocon_master_index].uri, QMessageBox.Ok)
00212             return
00213 
00214         self._widget_main.hide()
00215         arguments = ["", rocon_master_uri, rocon_master_host_name]
00216         os.execv(QMasterChooser.rocon_remocon_sub_script, arguments)
00217         console.logdebug("Spawning: %s with args %s" % (QMasterChooser.rocon_remocon_sub_script, arguments))
00218 
00219     def _create_add_rocon_master_dialog(self):
00220         # dialog
00221         connect_dlg = QDialog(self._widget_main)
00222         connect_dlg.setWindowTitle("Add Ros Master")
00223         connect_dlg.setSizePolicy(QSizePolicy.MinimumExpanding, QSizePolicy.Ignored)
00224         connect_dlg.setMinimumSize(350, 0)
00225         # dlg_rect = self._connect_dlg.geometry()
00226 
00227         # dialog layout
00228         ver_layout = QVBoxLayout(connect_dlg)
00229         ver_layout.setContentsMargins(9, 9, 9, 9)
00230 
00231         # param layout
00232         text_grid_sub_widget = QWidget()
00233         text_grid_layout = QGridLayout(text_grid_sub_widget)
00234         text_grid_layout.setColumnStretch(1, 0)
00235         text_grid_layout.setRowStretch(2, 0)
00236 
00237         # param 1
00238         title_widget1 = QLabel("MASTER_URI: ")
00239         context_widget1 = QTextEdit()
00240         context_widget1.setSizePolicy(QSizePolicy.MinimumExpanding, QSizePolicy.Ignored)
00241         context_widget1.setMinimumSize(0, 30)
00242         context_widget1.append(self.master_uri)
00243 
00244         # param 2
00245         title_widget2 = QLabel("HOST_NAME: ")
00246         context_widget2 = QTextEdit()
00247         context_widget2.setSizePolicy(QSizePolicy.MinimumExpanding, QSizePolicy.Ignored)
00248         context_widget2.setMinimumSize(0, 30)
00249         context_widget2.append(self.host_name)
00250 
00251         # add param
00252         text_grid_layout.addWidget(title_widget1)
00253         text_grid_layout.addWidget(context_widget1)
00254         text_grid_layout.addWidget(title_widget2)
00255         text_grid_layout.addWidget(context_widget2)
00256 
00257         # add param layout
00258         ver_layout.addWidget(text_grid_sub_widget)
00259 
00260         # button layout
00261         button_hor_sub_widget = QWidget()
00262         button_hor_layout = QHBoxLayout(button_hor_sub_widget)
00263 
00264         uri_text_widget = context_widget1
00265         host_name_text_widget = context_widget2
00266 
00267         # button
00268         btn_call = QPushButton("Add")
00269         btn_cancel = QPushButton("Cancel")
00270 
00271         btn_call.clicked.connect(lambda: connect_dlg.done(0))
00272         btn_call.clicked.connect(lambda: self._add_rocon_master(uri_text_widget, host_name_text_widget))
00273 
00274         btn_cancel.clicked.connect(lambda: connect_dlg.done(0))
00275 
00276         # add button
00277         button_hor_layout.addWidget(btn_call)
00278         button_hor_layout.addWidget(btn_cancel)
00279 
00280         # add button layout
00281         ver_layout.addWidget(button_hor_sub_widget)
00282 
00283         return connect_dlg


rocon_remocon
Author(s): Daniel Stonier, Donguk Lee
autogenerated on Fri Feb 12 2016 02:50:18