def newButtonSetOrUpdateCurrent(self):
        '''
        Asks user whether saving of button set is to be 
        to a new file, or an update to the current file.
        Cancel is offered as well.
        @return: ButtonSaveResult.NEW_SET, ButtonSaveResult.UPDATE_CURRENT, or ButtonSaveResult.CANCEL
        @rtype: DialogService.ButtonSaveResult
        '''
        msgBox = QMessageBox()
        msgBox.setStyleSheet(SpeakEasyGUI.stylesheetAppBG);
        msgBox.setText('Create new button set, or update current set?')

        updateCurrButton   = QPushButton('Update current')
        msgBox.addButton(updateCurrButton, QMessageBox.NoRole)
        
        newSetButton   = QPushButton('Create new set')
        msgBox.addButton(newSetButton, QMessageBox.YesRole)
        
        cancelButton = QPushButton('Cancel');
        msgBox.addButton(cancelButton, QMessageBox.RejectRole)

        value = msgBox.exec_();
        return value;
示例#2
0
class Switcher(QObject):
    # PySide signals are always defined as class attributes (GPL Pyqt4 Signals use pyqtSignal)
    signal_master_changed_state = Signal(bool)

    def __init__(self, rqt_plugin_name):
        super(Switcher, self).__init__()
        self._rqt_plugin_name = rqt_plugin_name
        self._rqt_subprocess = None
        self._no_ros_master_dialog = QMessageBox(
            QMessageBox.Warning, self.tr(self._rqt_plugin_name),
            self.tr("Waiting for the ROS Master to become available."))
        self._no_ros_master_abort_button = self._no_ros_master_dialog.addButton(
            QMessageBox.Abort)
        self._no_ros_master_abort_button.clicked.connect(self.shutdown)
        self.signal_master_changed_state.connect(self.switch_state,
                                                 type=Qt.QueuedConnection)
        self._ros_master_monitor = RosMasterMonitor(
            period=1, callback_function=self._master_changed_state)
        self._rqt_subprocess_shutdown_by_us = False

    @Slot(bool)
    def switch_state(self, new_master_found):
        '''
        :param bool new_master_found: true when a new master is detected, false when a master has disappeared.
        '''
        if new_master_found:
            self._no_ros_master_dialog.hide()
            self._launch_rocon_remocon()
        else:
            self._no_ros_master_dialog.show()
            self._no_ros_master_dialog.raise_()
            if self._rqt_subprocess is not None:
                self._rqt_subprocess_shutdown_by_us = True
                self._rqt_subprocess.send_signal(signal.SIGINT)
                # self._rqt_subprocess.terminate() # this is SIGTERM
                self._rqt_subprocess = None

    def shutdown(self):
        '''
        Shutdowns from external signals or the abort button while waiting for a master.
        '''
        print("Shutting down the ros master monitor")
        self._ros_master_monitor.shutdown()
        if self._rqt_subprocess is not None:
            print("Terminating subprocess")
            self._rqt_subprocess.send_signal(signal.SIGINT)
            # self._rqt_subprocess.terminate() # this is SIGTERM
            self._rqt_subprocess = None
        QCoreApplication.instance().quit()

    def _rqt_shutdown(self):
        '''
        Shutdown handler coming from the rqt subprocess shutting down. This needs
        to be handled differently depending on whether it's us shutting it down
        because a ros master shut down (in which case we need to stay alive)
        or otherwise.
        '''
        if not self._rqt_subprocess_shutdown_by_us:
            self._ros_master_monitor.shutdown()
            QCoreApplication.instance().quit()
        else:
            self._rqt_subprocess_shutdown_by_us = False

    def _master_changed_state(self, available):
        '''
        :param bool available: whether the ros master is available or not.
        '''
        self.signal_master_changed_state.emit(available)

    def _launch_rocon_remocon(self):
        script = '''
#!/usr/bin/env python
import sys
from rqt_gui.main import Main
main = Main()
sys.exit(main.main(sys.argv, standalone='%s'))
        ''' % self._rqt_plugin_name
        executable_file = tempfile.NamedTemporaryFile(mode='w+t', delete=False)
        executable_file.write(script)
        executable_file.flush()
        self._rqt_subprocess = rocon_python_utils.system.Popen(
            ['python', executable_file.name], postexec_fn=self._rqt_shutdown)