def _ui_setup(self): "Largely autogenerated layout code to setup interface" self.centralwidget = QtGui.QWidget(self) self.verticalLayout = QtGui.QVBoxLayout(self.centralwidget) self.vsplitter = QtGui.QSplitter(self.centralwidget) self.vsplitter.setOrientation(QtCore.Qt.Vertical) sizePolicy = QtGui.QSizePolicy(QtGui.QSizePolicy.Preferred, QtGui.QSizePolicy.Preferred) sizePolicy.setHorizontalStretch(1) sizePolicy.setVerticalStretch(1) sizePolicy.setHeightForWidth(self.vsplitter.sizePolicy().hasHeightForWidth()) self.vsplitter.setSizePolicy(sizePolicy) self.hsplitter = QtGui.QSplitter(self.vsplitter) self.hsplitter.setOrientation(QtCore.Qt.Horizontal) sizePolicy = QtGui.QSizePolicy(QtGui.QSizePolicy.Preferred, QtGui.QSizePolicy.Preferred) sizePolicy.setHorizontalStretch(1) sizePolicy.setVerticalStretch(1) sizePolicy.setHeightForWidth(self.hsplitter.sizePolicy().hasHeightForWidth()) self.hsplitter.setSizePolicy(sizePolicy) self.canTreeWidget = SignalTreeWidget(self.hsplitter) self.canTreeWidget.setMinimumSize(QtCore.QSize(300, 300)) self.canTreeWidget.setObjectName("canTreeWidget") self.tabWidget = TabViewContainer(self.hsplitter) sizePolicy = QtGui.QSizePolicy(QtGui.QSizePolicy.Expanding, QtGui.QSizePolicy.Expanding) sizePolicy.setHorizontalStretch(1) sizePolicy.setVerticalStretch(0) sizePolicy.setHeightForWidth(self.tabWidget.sizePolicy().hasHeightForWidth()) self.tabWidget.setSizePolicy(sizePolicy) self.tabWidget.setMinimumSize(QtCore.QSize(500, 300)) self.tabWidget.setObjectName("tabWidget") self.hsplitter.addWidget(self.canTreeWidget) self.hsplitter.addWidget(self.tabWidget) #Debugging Console self.console = QtGui.QTextEdit(self.vsplitter) self.console.setReadOnly(True) sizePolicy = QtGui.QSizePolicy(QtGui.QSizePolicy.Expanding, QtGui.QSizePolicy.Expanding) sizePolicy.setHorizontalStretch(0) sizePolicy.setVerticalStretch(0) sizePolicy.setHeightForWidth(self.console.sizePolicy().hasHeightForWidth()) self.console.setSizePolicy(sizePolicy) self.console.setMinimumSize(QtCore.QSize(0, 100)) self.console.setMaximumSize(QtCore.QSize(2000, 2000)) self.console.setObjectName("console") self.vsplitter.addWidget(self.hsplitter) self.vsplitter.addWidget(self.console) self.setCentralWidget(self.centralwidget) self.centralwidget.setLayout(self.verticalLayout) self.verticalLayout.addWidget(self.vsplitter) self.menubar = QtGui.QMenuBar(self) self.menubar.setGeometry(QtCore.QRect(0, 0, 878, 19)) self.menubar.setObjectName("menubar") self.menuFile = QtGui.QMenu(self.menubar) self.menuFile.setObjectName("menuFile") self.setMenuBar(self.menubar) self.toolBar = QtGui.QToolBar(self) self.toolBar.setObjectName("toolBar") self.toolBar.setToolButtonStyle(QtCore.Qt.ToolButtonIconOnly) self.makeTabIcon = find_icon("list-add.png") self.makeTabAction = QtGui.QAction(self.makeTabIcon, " ", self) link(self.makeTabAction.triggered, self.make_new_tab) self.makeTabButton = QtGui.QToolButton() self.makeTabButton.setDefaultAction(self.makeTabAction) self.toolBar.addWidget(self.makeTabButton) self.sendQueryIcon = find_icon("emblem-system.png") self.sendQueryAction = QtGui.QAction(self.sendQueryIcon, "", self) self.sendQueryButton = QtGui.QToolButton() self.sendQueryButton.setDefaultAction(self.sendQueryAction) self.toolBar.addWidget(self.sendQueryButton) def trigger_xombie_query(): if self.app.xombie_thread.isRunning(): app.xombie_thread.should_query = True link(self.sendQueryAction.triggered, trigger_xombie_query) self.sendTestIcon = find_icon("network-wireless.png") self.sendTestAction = QtGui.QAction(self.sendTestIcon, "", self) self.sendTestButton = QtGui.QToolButton() self.sendTestButton.setDefaultAction(self.sendTestAction) self.toolBar.addWidget(self.sendTestButton) def trigger_xombie_test(): if self.app.xombie_thread.isRunning(): app.xombie_thread.should_test = True link(self.sendTestAction.triggered, trigger_xombie_test) self.reassociateIcon = find_icon("go-jump.png") self.reassociateAction = QtGui.QAction(self.reassociateIcon, "", self) self.reassociateButton = QtGui.QToolButton() self.reassociateButton.setDefaultAction(self.reassociateAction) self.toolBar.addWidget(self.reassociateButton) def trigger_reassociate(): if self.app.xombie_thread.isRunning(): app.xombie_thread.should_reassociate = True link(self.reassociateAction.triggered, trigger_reassociate) self.nodeDiscoverIcon = find_icon("applications-internet.png") self.nodeDiscoverAction = QtGui.QAction(self.nodeDiscoverIcon, "", self) self.nodeDiscoverButton = QtGui.QToolButton() self.nodeDiscoverButton.setDefaultAction(self.nodeDiscoverAction) self.toolBar.addWidget(self.nodeDiscoverButton) def trigger_node_discover(): if self.app.xombie_thread.isRunning(): app.xombie_thread.should_discover = True link(self.nodeDiscoverAction.triggered, trigger_node_discover) self.addToolBar(QtCore.Qt.TopToolBarArea, self.toolBar) #self.insertToolBarBreak(self.toolBar) self.cornerMakeTabButton = QtGui.QToolButton() self.cornerMakeTabButton.setDefaultAction(self.makeTabAction) self.cornerMakeTabButton.setToolButtonStyle(QtCore.Qt.ToolButtonIconOnly) self.tabWidget.setCornerWidget(self.cornerMakeTabButton, QtCore.Qt.TopLeftCorner) self.statusBar = QtGui.QStatusBar(self) self.statusBar.setObjectName("statusBar") self.setStatusBar(self.statusBar)
class TelemetryViewerWindow(QtGui.QMainWindow): def __init__(self, application, title, desc_sets): QtGui.QMainWindow.__init__(self) self.title = title self.app = application self.setWindowTitle(title) self.icon_cache = {} self.tab_types = [] for view in [LiveGraphTabView, HistoricalGraphTabView, BatteryScatterPlotTabView]: self.tab_types.append((view.view_name, find_icon(view.view_icon), view.view_desc, view.view_id)) self._ui_setup() self.tabWidget.setMovable(True) self.tabs = [] #Take the CAN descriptions from the *.can.json files #and place them in the TreeWidget so that we can drag'n'drop them #to the main graph view self.canTreeWidget.add_descriptors(desc_sets) self.message_queue = Queue() self.logger = ConsoleLogger(self.message_queue) self.console_timer = QtCore.QTimer(self) self.redraw_timer = QtCore.QTimer(self) self.color_timer = QtCore.QTimer(self) link(self.console_timer.timeout, self.update_console) link(self.redraw_timer.timeout, self.redraw) self.console_timer.start(50) self.redraw_timer.start(100) def json_friendly(self): return [(self.tabWidget.tabText(i), self.tabWidget.widget(i).json_friendly()) for i in xrange(self.tabWidget.count())] def redraw(self): "Updates and redraws the active plot" now = datetime.datetime.utcnow() plot = self.tabWidget.currentWidget() if plot is not None: plot.update_view(now) plot.redraw() def _ui_setup(self): "Largely autogenerated layout code to setup interface" self.centralwidget = QtGui.QWidget(self) self.verticalLayout = QtGui.QVBoxLayout(self.centralwidget) self.vsplitter = QtGui.QSplitter(self.centralwidget) self.vsplitter.setOrientation(QtCore.Qt.Vertical) sizePolicy = QtGui.QSizePolicy(QtGui.QSizePolicy.Preferred, QtGui.QSizePolicy.Preferred) sizePolicy.setHorizontalStretch(1) sizePolicy.setVerticalStretch(1) sizePolicy.setHeightForWidth(self.vsplitter.sizePolicy().hasHeightForWidth()) self.vsplitter.setSizePolicy(sizePolicy) self.hsplitter = QtGui.QSplitter(self.vsplitter) self.hsplitter.setOrientation(QtCore.Qt.Horizontal) sizePolicy = QtGui.QSizePolicy(QtGui.QSizePolicy.Preferred, QtGui.QSizePolicy.Preferred) sizePolicy.setHorizontalStretch(1) sizePolicy.setVerticalStretch(1) sizePolicy.setHeightForWidth(self.hsplitter.sizePolicy().hasHeightForWidth()) self.hsplitter.setSizePolicy(sizePolicy) self.canTreeWidget = SignalTreeWidget(self.hsplitter) self.canTreeWidget.setMinimumSize(QtCore.QSize(300, 300)) self.canTreeWidget.setObjectName("canTreeWidget") self.tabWidget = TabViewContainer(self.hsplitter) sizePolicy = QtGui.QSizePolicy(QtGui.QSizePolicy.Expanding, QtGui.QSizePolicy.Expanding) sizePolicy.setHorizontalStretch(1) sizePolicy.setVerticalStretch(0) sizePolicy.setHeightForWidth(self.tabWidget.sizePolicy().hasHeightForWidth()) self.tabWidget.setSizePolicy(sizePolicy) self.tabWidget.setMinimumSize(QtCore.QSize(500, 300)) self.tabWidget.setObjectName("tabWidget") self.hsplitter.addWidget(self.canTreeWidget) self.hsplitter.addWidget(self.tabWidget) #Debugging Console self.console = QtGui.QTextEdit(self.vsplitter) self.console.setReadOnly(True) sizePolicy = QtGui.QSizePolicy(QtGui.QSizePolicy.Expanding, QtGui.QSizePolicy.Expanding) sizePolicy.setHorizontalStretch(0) sizePolicy.setVerticalStretch(0) sizePolicy.setHeightForWidth(self.console.sizePolicy().hasHeightForWidth()) self.console.setSizePolicy(sizePolicy) self.console.setMinimumSize(QtCore.QSize(0, 100)) self.console.setMaximumSize(QtCore.QSize(2000, 2000)) self.console.setObjectName("console") self.vsplitter.addWidget(self.hsplitter) self.vsplitter.addWidget(self.console) self.setCentralWidget(self.centralwidget) self.centralwidget.setLayout(self.verticalLayout) self.verticalLayout.addWidget(self.vsplitter) self.menubar = QtGui.QMenuBar(self) self.menubar.setGeometry(QtCore.QRect(0, 0, 878, 19)) self.menubar.setObjectName("menubar") self.menuFile = QtGui.QMenu(self.menubar) self.menuFile.setObjectName("menuFile") self.setMenuBar(self.menubar) self.toolBar = QtGui.QToolBar(self) self.toolBar.setObjectName("toolBar") self.toolBar.setToolButtonStyle(QtCore.Qt.ToolButtonIconOnly) self.makeTabIcon = find_icon("list-add.png") self.makeTabAction = QtGui.QAction(self.makeTabIcon, " ", self) link(self.makeTabAction.triggered, self.make_new_tab) self.makeTabButton = QtGui.QToolButton() self.makeTabButton.setDefaultAction(self.makeTabAction) self.toolBar.addWidget(self.makeTabButton) self.sendQueryIcon = find_icon("emblem-system.png") self.sendQueryAction = QtGui.QAction(self.sendQueryIcon, "", self) self.sendQueryButton = QtGui.QToolButton() self.sendQueryButton.setDefaultAction(self.sendQueryAction) self.toolBar.addWidget(self.sendQueryButton) def trigger_xombie_query(): if self.app.xombie_thread.isRunning(): app.xombie_thread.should_query = True link(self.sendQueryAction.triggered, trigger_xombie_query) self.sendTestIcon = find_icon("network-wireless.png") self.sendTestAction = QtGui.QAction(self.sendTestIcon, "", self) self.sendTestButton = QtGui.QToolButton() self.sendTestButton.setDefaultAction(self.sendTestAction) self.toolBar.addWidget(self.sendTestButton) def trigger_xombie_test(): if self.app.xombie_thread.isRunning(): app.xombie_thread.should_test = True link(self.sendTestAction.triggered, trigger_xombie_test) self.reassociateIcon = find_icon("go-jump.png") self.reassociateAction = QtGui.QAction(self.reassociateIcon, "", self) self.reassociateButton = QtGui.QToolButton() self.reassociateButton.setDefaultAction(self.reassociateAction) self.toolBar.addWidget(self.reassociateButton) def trigger_reassociate(): if self.app.xombie_thread.isRunning(): app.xombie_thread.should_reassociate = True link(self.reassociateAction.triggered, trigger_reassociate) self.nodeDiscoverIcon = find_icon("applications-internet.png") self.nodeDiscoverAction = QtGui.QAction(self.nodeDiscoverIcon, "", self) self.nodeDiscoverButton = QtGui.QToolButton() self.nodeDiscoverButton.setDefaultAction(self.nodeDiscoverAction) self.toolBar.addWidget(self.nodeDiscoverButton) def trigger_node_discover(): if self.app.xombie_thread.isRunning(): app.xombie_thread.should_discover = True link(self.nodeDiscoverAction.triggered, trigger_node_discover) self.addToolBar(QtCore.Qt.TopToolBarArea, self.toolBar) #self.insertToolBarBreak(self.toolBar) self.cornerMakeTabButton = QtGui.QToolButton() self.cornerMakeTabButton.setDefaultAction(self.makeTabAction) self.cornerMakeTabButton.setToolButtonStyle(QtCore.Qt.ToolButtonIconOnly) self.tabWidget.setCornerWidget(self.cornerMakeTabButton, QtCore.Qt.TopLeftCorner) self.statusBar = QtGui.QStatusBar(self) self.statusBar.setObjectName("statusBar") self.setStatusBar(self.statusBar) def setup_tabs(self, descs): if not descs: return for i, [tab_name, desc] in enumerate(descs): try: if desc["type"] == LiveGraphTabView.view_id: new_tab = LiveGraphTabView.from_json(desc, self.tabWidget, find_source) elif desc["type"] == NewTabViewSelector.view_id: new_tab = NewTabViewSelector.from_json(desc, self.tabWidget, self.tab_types, self.transform_tab) elif desc["type"] == HistoricalGraphTabView.view_id: new_tab = HistoricalGraphTabView.from_json(desc, self.tabWidget, self.app.can_descriptors, self.app.connection) else: continue except BaseException as e: print ("Error occurred while setting up tab #%d \"%s\": %s" % (i + 1, tab_name, e)) continue icon = None if desc.get("icon") is not None: icon = find_icon(desc.get("icon")) if icon is None: print "Warning: couldn't load icon '%s'" % icon if icon is not None: self.tabWidget.addTab(new_tab, icon, tab_name) new_tab.icon = desc.get("icon") else: self.tabWidget.addTab(new_tab, tab_name) self.tabs.append(new_tab) def update_console(self): "Pull any messages from the message queue and display them on the console" while not self.message_queue.empty(): self.console.append(self.message_queue.get_nowait()) self.update_colors() def make_new_tab(self): new_tab = NewTabViewSelector(self.tabWidget, self.tab_types, self.tabWidget) if new_tab.view_icon: self.tabWidget.addTab(new_tab, find_icon(new_tab.view_icon), "A New Tab") else: self.tabWidget.addTab(new_tab, "A New Tab") self.tabWidget.setCurrentWidget(new_tab) self.tabs.append(new_tab) link(new_tab.choice_selected, self.transform_tab) def transform_tab(self, choice): if choice == LiveGraphTabView.view_id: new_tab = LiveGraphTabView(self.tabWidget, find_source) elif choice == BatteryScatterPlotTabView.view_id: return elif choice == HistoricalGraphTabView.view_id: new_tab = HistoricalGraphTabView(self.tabWidget, self.app.can_descriptors, self.app.connection) if hasattr(new_tab, "icon"): icon = find_icon(new_tab.icon) else: icon = find_icon(new_tab.view_icon) self.tabWidget.replace_tab(new_tab, icon) def update_colors(self): if not app.xombie_thread.isRunning(): return received_times = [] for name, source in app.xombie_thread.stream.data_table.items(): received_times.append((name, source.last_received)) self.canTreeWidget.update_colors(received_times)