def __init__(self, *args): super(MainUI, self).__init__(*args) self.setupUi(self) # Restore window size if present in the config file try: size = Config().get("window_size") self.resize(size[0], size[1]) except KeyError: pass ###################################################### # By lxrocks # 'Skinny Progress Bar' tweak for Yosemite # Tweak progress bar - artistic I am not - so pick your own colors !!! # Only apply to Yosemite ###################################################### import platform if platform.system() == 'Darwin': (Version, junk, machine) = platform.mac_ver() logger.info("This is a MAC - checking if we can apply Progress " "Bar Stylesheet for Yosemite Skinny Bars ") yosemite = (10, 10, 0) tVersion = tuple(map(int, (Version.split(".")))) if tVersion >= yosemite: logger.info("Found Yosemite - applying stylesheet") tcss = """ QProgressBar { border: 1px solid grey; border-radius: 5px; text-align: center; } QProgressBar::chunk { background-color: """ + COLOR_BLUE + """; } """ self.setStyleSheet(tcss) else: logger.info("Pre-Yosemite - skinny bar stylesheet not applied") ###################################################### self.cf = Crazyflie(ro_cache=None, rw_cache=cfclient.config_path + "/cache") cflib.crtp.init_drivers(enable_debug_driver=Config() .get("enable_debug_driver")) zmq_params = ZMQParamAccess(self.cf) zmq_params.start() zmq_leds = ZMQLEDDriver(self.cf) zmq_leds.start() self.scanner = ScannerThread() self.scanner.interfaceFoundSignal.connect(self.foundInterfaces) self.scanner.start() # Create and start the Input Reader self._statusbar_label = QLabel("No input-device found, insert one to" " fly.") self.statusBar().addWidget(self._statusbar_label) self.joystickReader = JoystickReader() self._active_device = "" # self.configGroup = QActionGroup(self._menu_mappings, exclusive=True) self._mux_group = QActionGroup(self._menu_inputdevice, exclusive=True) # TODO: Need to reload configs # ConfigManager().conf_needs_reload.add_callback(self._reload_configs) self.cf.connection_failed.add_callback( self.connectionFailedSignal.emit) self.connectionFailedSignal.connect(self._connection_failed) self._input_device_error_signal.connect( self._display_input_device_error) self.joystickReader.device_error.add_callback( self._input_device_error_signal.emit) self._input_discovery_signal.connect(self.device_discovery) self.joystickReader.device_discovery.add_callback( self._input_discovery_signal.emit) # Hide the 'File' menu on OS X, since its only item, 'Exit', gets # merged into the application menu. if sys.platform == 'darwin': self.menuFile.menuAction().setVisible(False) # Connect UI signals self.logConfigAction.triggered.connect(self._show_connect_dialog) self.interfaceCombo.currentIndexChanged['QString'].connect( self.interfaceChanged) self.connectButton.clicked.connect(self._connect) self.scanButton.clicked.connect(self._scan) self.menuItemConnect.triggered.connect(self._connect) self.menuItemConfInputDevice.triggered.connect( self._show_input_device_config_dialog) self.menuItemExit.triggered.connect(self.closeAppRequest) self.batteryUpdatedSignal.connect(self._update_battery) self._menuitem_rescandevices.triggered.connect(self._rescan_devices) self._menuItem_openconfigfolder.triggered.connect( self._open_config_folder) self.address.setValue(0xE7E7E7E7E7) self._auto_reconnect_enabled = Config().get("auto_reconnect") self.autoReconnectCheckBox.toggled.connect( self._auto_reconnect_changed) self.autoReconnectCheckBox.setChecked(Config().get("auto_reconnect")) self._disable_input = False self.joystickReader.input_updated.add_callback( lambda *args: self._disable_input or self.cf.commander.send_setpoint(*args)) self.joystickReader.assisted_input_updated.add_callback( lambda *args: self._disable_input or self.cf.commander.send_velocity_world_setpoint(*args)) self.joystickReader.heighthold_input_updated.add_callback( lambda *args: self._disable_input or self.cf.commander.send_zdistance_setpoint(*args)) self.joystickReader.hover_input_updated.add_callback( self.cf.commander.send_hover_setpoint) # Connection callbacks and signal wrappers for UI protection self.cf.connected.add_callback(self.connectionDoneSignal.emit) self.connectionDoneSignal.connect(self._connected) self.cf.disconnected.add_callback(self.disconnectedSignal.emit) self.disconnectedSignal.connect(self._disconnected) self.cf.connection_lost.add_callback(self.connectionLostSignal.emit) self.connectionLostSignal.connect(self._connection_lost) self.cf.connection_requested.add_callback( self.connectionInitiatedSignal.emit) self.connectionInitiatedSignal.connect(self._connection_initiated) self._log_error_signal.connect(self._logging_error) self.batteryBar.setTextVisible(False) self.batteryBar.setStyleSheet(progressbar_stylesheet(COLOR_BLUE)) self.linkQualityBar.setTextVisible(False) self.linkQualityBar.setStyleSheet(progressbar_stylesheet(COLOR_BLUE)) # Connect link quality feedback self.cf.link_quality_updated.add_callback(self.linkQualitySignal.emit) self.linkQualitySignal.connect( lambda percentage: self.linkQualityBar.setValue(percentage)) self._selected_interface = None self._initial_scan = True self._scan() # Parse the log configuration files self.logConfigReader = LogConfigReader(self.cf) self._current_input_config = None self._active_config = None self._active_config = None self.inputConfig = None # Add things to helper so tabs can access it cfclient.ui.pluginhelper.cf = self.cf cfclient.ui.pluginhelper.inputDeviceReader = self.joystickReader cfclient.ui.pluginhelper.logConfigReader = self.logConfigReader cfclient.ui.pluginhelper.mainUI = self self.logConfigDialogue = LogConfigDialogue(cfclient.ui.pluginhelper) self._bootloader_dialog = BootloaderDialog(cfclient.ui.pluginhelper) self._cf2config_dialog = Cf2ConfigDialog(cfclient.ui.pluginhelper) self._cf1config_dialog = Cf1ConfigDialog(cfclient.ui.pluginhelper) self.menuItemBootloader.triggered.connect(self._bootloader_dialog.show) self._about_dialog = AboutDialog(cfclient.ui.pluginhelper) self.menuItemAbout.triggered.connect(self._about_dialog.show) self._menu_cf2_config.triggered.connect(self._cf2config_dialog.show) self._menu_cf1_config.triggered.connect(self._cf1config_dialog.show) # Load and connect tabs self.tabsMenuItem = QMenu("Tabs", self.menuView, enabled=True) self.menuView.addMenu(self.tabsMenuItem) # self.tabsMenuItem.setMenu(QtWidgets.QMenu()) tabItems = {} self.loadedTabs = [] for tabClass in cfclient.ui.tabs.available: tab = tabClass(self.tabs, cfclient.ui.pluginhelper) item = QtWidgets.QAction(tab.getMenuName(), self, checkable=True) item.toggled.connect(tab.toggleVisibility) self.tabsMenuItem.addAction(item) tabItems[tab.getTabName()] = item self.loadedTabs.append(tab) if not tab.enabled: item.setEnabled(False) # First instantiate all tabs and then open them in the correct order try: for tName in Config().get("open_tabs").split(","): t = tabItems[tName] if (t is not None and t.isEnabled()): # Toggle though menu so it's also marked as open there t.toggle() except Exception as e: logger.warning("Exception while opening tabs [{}]".format(e)) # Loading toolboxes (A bit of magic for a lot of automatic) self.toolboxesMenuItem = QMenu("Toolboxes", self.menuView, enabled=True) self.menuView.addMenu(self.toolboxesMenuItem) self.toolboxes = [] for t_class in cfclient.ui.toolboxes.toolboxes: toolbox = t_class(cfclient.ui.pluginhelper) dockToolbox = MyDockWidget(toolbox.getName()) dockToolbox.setWidget(toolbox) self.toolboxes += [dockToolbox, ] # Add menu item for the toolbox item = QtWidgets.QAction(toolbox.getName(), self) item.setCheckable(True) item.triggered.connect(self.toggleToolbox) self.toolboxesMenuItem.addAction(item) dockToolbox.closed.connect(lambda: self.toggleToolbox(False)) # Setup some introspection item.dockToolbox = dockToolbox item.menuItem = item dockToolbox.dockToolbox = dockToolbox dockToolbox.menuItem = item # References to all the device sub-menus in the "Input device" menu self._all_role_menus = () # Used to filter what new devices to add default mapping to self._available_devices = () # Keep track of mux nodes so we can enable according to how many # devices we have self._all_mux_nodes = () # Check which Input muxes are available self._mux_group = QActionGroup(self._menu_inputdevice, exclusive=True) for m in self.joystickReader.available_mux(): node = QAction(m.name, self._menu_inputdevice, checkable=True, enabled=False) node.toggled.connect(self._mux_selected) self._mux_group.addAction(node) self._menu_inputdevice.addAction(node) self._all_mux_nodes += (node,) mux_subnodes = () for name in m.supported_roles(): sub_node = QMenu(" {}".format(name), self._menu_inputdevice, enabled=False) self._menu_inputdevice.addMenu(sub_node) mux_subnodes += (sub_node,) self._all_role_menus += ({"muxmenu": node, "rolemenu": sub_node},) node.setData((m, mux_subnodes)) self._mapping_support = True
def __init__(self, *args): super(MainUI, self).__init__(*args) self.setupUi(self) ###################################################### # By lxrocks # 'Skinny Progress Bar' tweak for Yosemite # Tweak progress bar - artistic I am not - so pick your own colors !!! # Only apply to Yosemite ###################################################### import platform if platform.system() == 'Darwin': (Version, junk, machine) = platform.mac_ver() logger.info("This is a MAC - checking if we can apply Progress " "Bar Stylesheet for Yosemite Skinny Bars ") yosemite = (10, 10, 0) tVersion = tuple(map(int, (Version.split(".")))) if tVersion >= yosemite: logger.info("Found Yosemite - applying stylesheet") tcss = """ QProgressBar { border: 1px solid grey; border-radius: 5px; text-align: center; } QProgressBar::chunk { background-color: """ + COLOR_BLUE + """; } """ self.setStyleSheet(tcss) else: logger.info("Pre-Yosemite - skinny bar stylesheet not applied") ###################################################### self.cf = Crazyflie(ro_cache=None, rw_cache=cfclient.config_path + "/cache") cflib.crtp.init_drivers(enable_debug_driver=Config() .get("enable_debug_driver")) zmq_params = ZMQParamAccess(self.cf) zmq_params.start() zmq_leds = ZMQLEDDriver(self.cf) zmq_leds.start() self.scanner = ScannerThread() self.scanner.interfaceFoundSignal.connect(self.foundInterfaces) self.scanner.start() # Create and start the Input Reader self._statusbar_label = QLabel("No input-device found, insert one to" " fly.") self.statusBar().addWidget(self._statusbar_label) self.joystickReader = JoystickReader() self._active_device = "" # self.configGroup = QActionGroup(self._menu_mappings, exclusive=True) self._mux_group = QActionGroup(self._menu_inputdevice, exclusive=True) # TODO: Need to reload configs # ConfigManager().conf_needs_reload.add_callback(self._reload_configs) self.cf.connection_failed.add_callback( self.connectionFailedSignal.emit) self.connectionFailedSignal.connect(self._connection_failed) self._input_device_error_signal.connect( self._display_input_device_error) self.joystickReader.device_error.add_callback( self._input_device_error_signal.emit) self._input_discovery_signal.connect(self.device_discovery) self.joystickReader.device_discovery.add_callback( self._input_discovery_signal.emit) # Hide the 'File' menu on OS X, since its only item, 'Exit', gets # merged into the application menu. if sys.platform == 'darwin': self.menuFile.menuAction().setVisible(False) # Connect UI signals self.logConfigAction.triggered.connect(self._show_connect_dialog) self.interfaceCombo.currentIndexChanged['QString'].connect( self.interfaceChanged) self.connectButton.clicked.connect(self._connect) self.scanButton.clicked.connect(self._scan) self.menuItemConnect.triggered.connect(self._connect) self.menuItemConfInputDevice.triggered.connect( self._show_input_device_config_dialog) self.menuItemExit.triggered.connect(self.closeAppRequest) self.batteryUpdatedSignal.connect(self._update_battery) self._menuitem_rescandevices.triggered.connect(self._rescan_devices) self._menuItem_openconfigfolder.triggered.connect( self._open_config_folder) self.address.setValue(0xE7E7E7E7E7) self._auto_reconnect_enabled = Config().get("auto_reconnect") self.autoReconnectCheckBox.toggled.connect( self._auto_reconnect_changed) self.autoReconnectCheckBox.setChecked(Config().get("auto_reconnect")) self.joystickReader.input_updated.add_callback( self.cf.commander.send_setpoint) # Connection callbacks and signal wrappers for UI protection self.cf.connected.add_callback(self.connectionDoneSignal.emit) self.connectionDoneSignal.connect(self._connected) self.cf.disconnected.add_callback(self.disconnectedSignal.emit) self.disconnectedSignal.connect(self._disconnected) self.cf.connection_lost.add_callback(self.connectionLostSignal.emit) self.connectionLostSignal.connect(self._connection_lost) self.cf.connection_requested.add_callback( self.connectionInitiatedSignal.emit) self.connectionInitiatedSignal.connect(self._connection_initiated) self._log_error_signal.connect(self._logging_error) self.batteryBar.setTextVisible(False) self.batteryBar.setStyleSheet(progressbar_stylesheet(COLOR_BLUE)) self.linkQualityBar.setTextVisible(False) self.linkQualityBar.setStyleSheet(progressbar_stylesheet(COLOR_BLUE)) # Connect link quality feedback self.cf.link_quality_updated.add_callback(self.linkQualitySignal.emit) self.linkQualitySignal.connect( lambda percentage: self.linkQualityBar.setValue(percentage)) self._selected_interface = None self._initial_scan = True self._scan() # Parse the log configuration files self.logConfigReader = LogConfigReader(self.cf) self._current_input_config = None self._active_config = None self._active_config = None self.inputConfig = None # Add things to helper so tabs can access it cfclient.ui.pluginhelper.cf = self.cf cfclient.ui.pluginhelper.inputDeviceReader = self.joystickReader cfclient.ui.pluginhelper.logConfigReader = self.logConfigReader self.logConfigDialogue = LogConfigDialogue(cfclient.ui.pluginhelper) self._bootloader_dialog = BootloaderDialog(cfclient.ui.pluginhelper) self._cf2config_dialog = Cf2ConfigDialog(cfclient.ui.pluginhelper) self._cf1config_dialog = Cf1ConfigDialog(cfclient.ui.pluginhelper) self.menuItemBootloader.triggered.connect(self._bootloader_dialog.show) self._about_dialog = AboutDialog(cfclient.ui.pluginhelper) self.menuItemAbout.triggered.connect(self._about_dialog.show) self._menu_cf2_config.triggered.connect(self._cf2config_dialog.show) self._menu_cf1_config.triggered.connect(self._cf1config_dialog.show) # Loading toolboxes (A bit of magic for a lot of automatic) self.toolboxes = [] self.toolboxesMenuItem.setMenu(QtGui.QMenu()) for t_class in cfclient.ui.toolboxes.toolboxes: toolbox = t_class(cfclient.ui.pluginhelper) dockToolbox = MyDockWidget(toolbox.getName()) dockToolbox.setWidget(toolbox) self.toolboxes += [dockToolbox, ] # Add menu item for the toolbox item = QtGui.QAction(toolbox.getName(), self) item.setCheckable(True) item.triggered.connect(self.toggleToolbox) self.toolboxesMenuItem.menu().addAction(item) dockToolbox.closed.connect(lambda: self.toggleToolbox(False)) # Setup some introspection item.dockToolbox = dockToolbox item.menuItem = item dockToolbox.dockToolbox = dockToolbox dockToolbox.menuItem = item # Load and connect tabs self.tabsMenuItem.setMenu(QtGui.QMenu()) tabItems = {} self.loadedTabs = [] for tabClass in cfclient.ui.tabs.available: tab = tabClass(self.tabs, cfclient.ui.pluginhelper) item = QtGui.QAction(tab.getMenuName(), self) item.setCheckable(True) item.toggled.connect(tab.toggleVisibility) self.tabsMenuItem.menu().addAction(item) tabItems[tab.getTabName()] = item self.loadedTabs.append(tab) if not tab.enabled: item.setEnabled(False) # First instantiate all tabs and then open them in the correct order try: for tName in Config().get("open_tabs").split(","): t = tabItems[tName] if (t is not None and t.isEnabled()): # Toggle though menu so it's also marked as open there t.toggle() except Exception as e: logger.warning("Exception while opening tabs [{}]".format(e)) # References to all the device sub-menus in the "Input device" menu self._all_role_menus = () # Used to filter what new devices to add default mapping to self._available_devices = () # Keep track of mux nodes so we can enable according to how many # devices we have self._all_mux_nodes = () # Check which Input muxes are available self._mux_group = QActionGroup(self._menu_inputdevice, exclusive=True) for m in self.joystickReader.available_mux(): node = QAction(m.name, self._menu_inputdevice, checkable=True, enabled=False) node.toggled.connect(self._mux_selected) self._mux_group.addAction(node) self._menu_inputdevice.addAction(node) self._all_mux_nodes += (node,) mux_subnodes = () for name in m.supported_roles(): sub_node = QMenu(" {}".format(name), self._menu_inputdevice, enabled=False) self._menu_inputdevice.addMenu(sub_node) mux_subnodes += (sub_node,) self._all_role_menus += ({"muxmenu": node, "rolemenu": sub_node},) node.setData((m, mux_subnodes)) self._mapping_support = True
def __init__(self, *args): super(MainUI, self).__init__(*args) self.setupUi(self) # Restore window size if present in the config file try: size = Config().get("window_size") self.resize(size[0], size[1]) except KeyError: pass self.cf = Crazyflie(ro_cache=None, rw_cache=cfclient.config_path + "/cache") cflib.crtp.init_drivers( enable_debug_driver=Config().get("enable_debug_driver")) zmq_params = ZMQParamAccess(self.cf) zmq_params.start() zmq_leds = ZMQLEDDriver(self.cf) zmq_leds.start() self.scanner = ScannerThread() self.scanner.interfaceFoundSignal.connect(self.foundInterfaces) self.scanner.start() # Create and start the Input Reader self._statusbar_label = QLabel("No input-device found, insert one to" " fly.") self.statusBar().addWidget(self._statusbar_label) self.joystickReader = JoystickReader() self._active_device = "" # self.configGroup = QActionGroup(self._menu_mappings, exclusive=True) self._mux_group = QActionGroup(self._menu_inputdevice) self._mux_group.setExclusive(True) # TODO: Need to reload configs # ConfigManager().conf_needs_reload.add_callback(self._reload_configs) self.connect_input = QShortcut("Ctrl+I", self.connectButton, self._connect) self.cf.connection_failed.add_callback( self.connectionFailedSignal.emit) self.connectionFailedSignal.connect(self._connection_failed) self._input_device_error_signal.connect( self._display_input_device_error) self.joystickReader.device_error.add_callback( self._input_device_error_signal.emit) self._input_discovery_signal.connect(self.device_discovery) self.joystickReader.device_discovery.add_callback( self._input_discovery_signal.emit) # Connect UI signals self.logConfigAction.triggered.connect(self._show_connect_dialog) self.interfaceCombo.currentIndexChanged['QString'].connect( self.interfaceChanged) self.connectButton.clicked.connect(self._connect) self.scanButton.clicked.connect(self._scan) self.menuItemConnect.triggered.connect(self._connect) self.menuItemConfInputDevice.triggered.connect( self._show_input_device_config_dialog) self.menuItemExit.triggered.connect(self.closeAppRequest) self.batteryUpdatedSignal.connect(self._update_battery) self._menuitem_rescandevices.triggered.connect(self._rescan_devices) self._menuItem_openconfigfolder.triggered.connect( self._open_config_folder) self.address.setValue(0xE7E7E7E7E7) self._auto_reconnect_enabled = Config().get("auto_reconnect") self.autoReconnectCheckBox.toggled.connect( self._auto_reconnect_changed) self.autoReconnectCheckBox.setChecked(Config().get("auto_reconnect")) self._disable_input = False self.joystickReader.input_updated.add_callback( lambda *args: self._disable_input or self.cf.commander. send_setpoint(*args)) self.joystickReader.assisted_input_updated.add_callback( lambda *args: self._disable_input or self.cf.commander. send_velocity_world_setpoint(*args)) self.joystickReader.heighthold_input_updated.add_callback( lambda *args: self._disable_input or self.cf.commander. send_zdistance_setpoint(*args)) self.joystickReader.hover_input_updated.add_callback( self.cf.commander.send_hover_setpoint) # Connection callbacks and signal wrappers for UI protection self.cf.connected.add_callback(self.connectionDoneSignal.emit) self.connectionDoneSignal.connect(self._connected) self.cf.disconnected.add_callback(self.disconnectedSignal.emit) self.disconnectedSignal.connect(self._disconnected) self.cf.connection_lost.add_callback(self.connectionLostSignal.emit) self.connectionLostSignal.connect(self._connection_lost) self.cf.connection_requested.add_callback( self.connectionInitiatedSignal.emit) self.connectionInitiatedSignal.connect(self._connection_initiated) self._log_error_signal.connect(self._logging_error) self.batteryBar.setTextVisible(False) self.linkQualityBar.setTextVisible(False) # Connect link quality feedback self.cf.link_quality_updated.add_callback(self.linkQualitySignal.emit) self.linkQualitySignal.connect( lambda percentage: self.linkQualityBar.setValue(percentage)) self._selected_interface = None self._initial_scan = True self._scan() # Parse the log configuration files self.logConfigReader = LogConfigReader(self.cf) self._current_input_config = None self._active_config = None self._active_config = None self.inputConfig = None # Add things to helper so tabs can access it cfclient.ui.pluginhelper.cf = self.cf cfclient.ui.pluginhelper.inputDeviceReader = self.joystickReader cfclient.ui.pluginhelper.logConfigReader = self.logConfigReader cfclient.ui.pluginhelper.pose_logger = PoseLogger(self.cf) cfclient.ui.pluginhelper.mainUI = self self.logConfigDialogue = LogConfigDialogue(cfclient.ui.pluginhelper) self._bootloader_dialog = BootloaderDialog(cfclient.ui.pluginhelper) self._cf2config_dialog = Cf2ConfigDialog(cfclient.ui.pluginhelper) self.menuItemBootloader.triggered.connect(self._bootloader_dialog.show) self._about_dialog = AboutDialog(cfclient.ui.pluginhelper) self.menuItemAbout.triggered.connect(self._about_dialog.show) self._menu_cf2_config.triggered.connect(self._cf2config_dialog.show) # Load and connect tabs self.tabsMenuItem = QMenu("Tabs", self.menuView, enabled=True) self.menuView.addMenu(self.tabsMenuItem) tabItems = {} self.loadedTabs = [] for tabClass in cfclient.ui.tabs.available: tab = tabClass(self.tabs, cfclient.ui.pluginhelper) # Set reference for plot-tab. if isinstance(tab, cfclient.ui.tabs.PlotTab): cfclient.ui.pluginhelper.plotTab = tab item = QtWidgets.QAction(tab.getMenuName(), self, checkable=True) item.toggled.connect(tab.toggleVisibility) self.tabsMenuItem.addAction(item) tabItems[tab.getTabName()] = item self.loadedTabs.append(tab) if not tab.enabled: item.setEnabled(False) # First instantiate all tabs and then open them in the correct order try: for tName in Config().get("open_tabs").split(","): t = tabItems[tName] if (t is not None and t.isEnabled()): # Toggle though menu so it's also marked as open there t.toggle() except Exception as e: logger.warning("Exception while opening tabs [{}]".format(e)) # Loading toolboxes (A bit of magic for a lot of automatic) self.toolboxesMenuItem = QMenu("Toolboxes", self.menuView, enabled=True) self.menuView.addMenu(self.toolboxesMenuItem) self.toolboxes = [] for t_class in cfclient.ui.toolboxes.toolboxes: toolbox = t_class(cfclient.ui.pluginhelper) dockToolbox = MyDockWidget(toolbox.getName()) dockToolbox.setWidget(toolbox) self.toolboxes += [ dockToolbox, ] # Add menu item for the toolbox item = QtWidgets.QAction(toolbox.getName(), self) item.setCheckable(True) item.triggered.connect(self.toggleToolbox) self.toolboxesMenuItem.addAction(item) dockToolbox.closed.connect(lambda: self.toggleToolbox(False)) # Setup some introspection item.dockToolbox = dockToolbox item.menuItem = item dockToolbox.dockToolbox = dockToolbox dockToolbox.menuItem = item # References to all the device sub-menus in the "Input device" menu self._all_role_menus = () # Used to filter what new devices to add default mapping to self._available_devices = () # Keep track of mux nodes so we can enable according to how many # devices we have self._all_mux_nodes = () # Check which Input muxes are available self._mux_group = QActionGroup(self._menu_inputdevice) self._mux_group.setExclusive(True) for m in self.joystickReader.available_mux(): node = QAction(m.name, self._menu_inputdevice, checkable=True, enabled=False) node.toggled.connect(self._mux_selected) self._mux_group.addAction(node) self._menu_inputdevice.addAction(node) self._all_mux_nodes += (node, ) mux_subnodes = () for name in m.supported_roles(): sub_node = QMenu(" {}".format(name), self._menu_inputdevice, enabled=False) self._menu_inputdevice.addMenu(sub_node) mux_subnodes += (sub_node, ) self._all_role_menus += ({ "muxmenu": node, "rolemenu": sub_node }, ) node.setData((m, mux_subnodes)) self._mapping_support = True # Add checkbuttons for theme-selection. self._theme_group = QActionGroup(self.menuThemes) self._theme_group.setExclusive(True) self._theme_checkboxes = [] for theme in UiUtils.THEMES: node = QAction(theme, self.menuThemes, checkable=True) node.setObjectName(theme) node.toggled.connect(self._theme_selected) self._theme_checkboxes.append(node) self._theme_group.addAction(node) self.menuThemes.addAction(node)