コード例 #1
0
class PlotWindow(QWidget):
    def __init__(self, tab):
        super(PlotWindow, self).__init__()
        self.tab = tab
        self.allAxes = {}
        self.curveList = []
        self.extraLines = []
        self.layout = QHBoxLayout()
        self.graph_layout = QVBoxLayout()
        self.gbox_layout = QVBoxLayout()

        self.tabGBActor = QTabWidget()

        self.dateplot = DatePlot(self)
        self.customize = Customize(self)
        self.button_arrow = self.ButtonArrow()
        self.button_del_graph = self.ButtonDelete()

        self.gbox_layout.addWidget(self.dateplot)
        self.gbox_layout.addWidget(self.customize)
        self.gbox_layout.addWidget(self.tabGBActor)
        self.gbox_layout.addWidget(self.button_del_graph)

        self.layout.addLayout(self.graph_layout)
        self.layout.addWidget(self.button_arrow)
        self.layout.addLayout(self.gbox_layout)

        for widget in [self.dateplot, self.customize, self.tabGBActor]:
            widget.setMaximumWidth(400)

        self.setLayout(self.layout)

    @property
    def mainwindow(self):
        return self.tab.mainwindow

    @property
    def config(self):
        return self.dateplot.config

    @property
    def axes2curves(self):
        d = {ax: [] for ax in [None] + list(self.allAxes.values())}

        for curve in self.curveList:
            d[curve.getAxes()].append(curve)

        return d

    @property
    def line2Curve(self):
        return {curve.line: curve for curve in self.curveList}

    @property
    def axes2id(self):
        d = {ax: id for id, ax in self.allAxes.items()}
        d[None] = None
        return d

    def createGraph(self, custom):
        try:
            self.graph.close()
            self.graph_layout.removeWidget(self.graph)
            self.graph.deleteLater()
        except AttributeError:
            pass

        self.graph = Graph(self, custom)
        self.graph_layout.insertWidget(0, self.graph)

    def getAxes(self, newType, i=-1):

        for i, ax in self.allAxes.items():
            try:
                curve = self.axes2curves[ax][0]
                if curve.type == newType:
                    return ax
            except IndexError:
                return ax

            if i == 3:
                raise ValueError('No Axe available')
        return i + 1

    def setAxes(self, allAxes):
        for idAxes, oldAxes in list(self.allAxes.items()):
            self.unsetLines(oldAxes, allAxes)
            self.allAxes.pop(idAxes, None)

        self.allAxes = allAxes

    def unsetLines(self, axes, newAxes):
        while axes.lines:
            line = axes.lines[0]
            axes.lines.remove(line)
            try:
                curve = self.line2Curve[line]
                curve.line = False
                if curve.getAxes() not in newAxes.values():
                    curve.setAxes(None)
            except KeyError:
                pass
            del line

    def addCurve(self, curveConf):

        new_curve = Curve(self, curveConf)
        axes = self.getAxes(new_curve.type)

        if isinstance(axes, int):
            idAxes = axes
            self.customize.allAxes[idAxes].checkbox.setChecked(2)
            axes = self.allAxes[idAxes]

        new_curve.setAxes(axes)
        self.appendCurve(new_curve)
        self.graph.plotCurves(new_curve)

        return new_curve

    def appendCurve(self, new_curve):

        self.curveList.append(new_curve)
        self.customize.appendRow(new_curve)

    def switchCurve(self, axeId, curve):
        ax = self.allAxes[axeId] if axeId is not None else None
        self.graph.switchCurve(ax, curve)

    def removeCurve(self, curve):
        self.curveList.remove(curve)
        self.graph.removeCurve(curve)

        try:
            checkbox = curve.checkbox
            checkbox.setCheckable(True)
            checkbox.setChecked(0)
        except RuntimeError:
            pass  # Checkbox could have been already deleted

    def constructGroupbox(self, config):

        while self.tabGBActor.count():
            widget = self.tabGBActor.widget(0)
            self.clearLayout(widget.layout())
            self.tabGBActor.removeTab(0)
            widget.close()
            widget.deleteLater()

        sortedModule = self.sortCfg(config)

        for actorname in sorted(sortedModule):
            config = sortedModule[actorname]
            if config:
                t = TabActor(self, config)
                self.tabGBActor.addTab(t, actorname)

    def showhideConfig(self, button_arrow):

        if not self.tabGBActor.isHidden():
            self.tabGBActor.hide()
            self.dateplot.hide()
            self.customize.hide()
            self.button_del_graph.hide()
            button_arrow.setIcon(self.mainwindow.icon_arrow_left)
        else:
            self.tabGBActor.show()
            self.button_del_graph.show()
            self.dateplot.show()
            self.customize.show()
            button_arrow.setIcon(self.mainwindow.icon_arrow_right)

    def ButtonDelete(self):
        button = QPushButton('Remove Graph')
        button.clicked.connect(partial(self.removeGraph, self.layout))
        return button

    def ButtonArrow(self):

        button_arrow = QPushButton()
        button_arrow.setIcon(self.mainwindow.icon_arrow_right)
        button_arrow.clicked.connect(partial(self.showhideConfig, button_arrow))
        button_arrow.setStyleSheet('border: 0px')

        return button_arrow

    def removeGraph(self, layout):
        self.clearLayout(layout)
        self.tab.removeGraph(self)

    def clearLayout(self, layout):

        if layout is not None:
            while layout.count():
                item = layout.takeAt(0)
                widget = item.widget()
                if widget is not None:
                    widget.deleteLater()
                else:
                    self.clearLayout(item.layout())

    def table2label(self, tablename, mergeAIT=False):
        for key, label in self.mainwindow.cuArms.items():
            if key in tablename:
                return label
        if mergeAIT:
            return 'AIT'
        else:
            return tablename.split('__')[0].upper()

    def sortCfg(self, config):
        sortedDict = {}
        for dev in config:
            label = self.table2label(tablename=dev.tablename, mergeAIT=False)
            try:
                sortedDict[label].append(dev)
            except KeyError:
                sortedDict[label] = [dev]
        return sortedDict
コード例 #2
0
class MainWindow(QMainWindow):
    def __init__(self, appctx, *args, **kwargs):
        super(MainWindow, self).__init__(*args, **kwargs)
        self.appctx = appctx
        self.setup_center_ui()
        self.setup_log_ui()
        self.setup_command_dock_ui()
        self.setup_menu()

    def setup_center_ui(self):
        """
        Set up the central widget area, which includes:
            DatasetWidget
            LogWidget
        """
        self.setWindowTitle(f"CLARITE v{self.appctx.VERSION}")
        self.setWindowIcon(QIcon(":/images/clarite_logo.png"))

        self.setContentsMargins(10, 10, 10, 10)

        # Set up the central widget
        splitter = QSplitter(self)
        splitter.setOrientation(Qt.Vertical)
        splitter.setMinimumSize(800, 600)
        self.setCentralWidget(splitter)

        # Add the main sections
        dataset_widget = DatasetWidget(parent=self)
        splitter.addWidget(dataset_widget)

        self.log_tabs = QTabWidget(parent=self)
        self.log_tabs.setTabPosition(QTabWidget.North)
        splitter.addWidget(self.log_tabs)

        # Set the initial sizes (and relative ratio) of the two groups
        splitter.setSizes([500, 100])

    def setup_log_ui(self):
        """Add log tabs each with individual widgets"""
        # Normal Log
        info_log_widget = LogWidget(parent=self)
        self.appctx.signals.log_info.connect(info_log_widget.append)
        self.log_tabs.addTab(info_log_widget, "Info Log")
        # Python Log
        python_log_widget = LogWidget(
            parent=self,
            filetype="Python Files (*.py)",
            initial_log=["import clarite\n\n"],
        )
        python_log_widget.btn_clear.setHidden(
            True
        )  # Don't allow the python log to be cleared- too tricky
        self.appctx.signals.log_python.connect(python_log_widget.append)
        self.log_tabs.addTab(python_log_widget, "Python Log")

    def setup_command_dock_ui(self):
        """
        Set up the dock widgets, which includes:
            CommandDockWidget
        """
        # Initialize command dock and place on the left
        self.command_dock_widget = CommandDockWidget(parent=self)
        self.addDockWidget(Qt.LeftDockWidgetArea, self.command_dock_widget)

    def setup_menu(self):
        """Set up the file menu"""
        # Add menubar and get a reference to it
        menubar = self.menuBar()
        # Add menus
        file_menu = menubar.addMenu("File")
        edit_menu = menubar.addMenu("Edit")
        view_menu = menubar.addMenu("View")
        help_menu = menubar.addMenu("Help")

        # Add to File menu
        exit_action = QAction("Exit", parent=self)
        exit_action.setShortcut("Ctrl+Q")
        exit_action.setStatusTip("Exit application")
        exit_action.triggered.connect(self.close)
        file_menu.addAction(exit_action)

        # Add to Edit menu
        preferences_action = QAction("Preferences", parent=self)
        preferences_action.setStatusTip("Edit preferences")
        preferences_action.triggered.connect(
            lambda: PreferencesDialog(parent=self.appctx.main_window).show()
        )
        edit_menu.addAction(preferences_action)

        # Add to View menu
        view_commands_menu = view_menu.addMenu("Commands")
        # Show/Hide
        show_commands_action = self.command_dock_widget.toggleViewAction()
        show_commands_action.setStatusTip("Show/Hide the command dock")
        show_commands_action.setText("Show")
        view_commands_menu.addAction(show_commands_action)
        # Dock/Undock (These are reversed booleans since True = floating and it is displaying docked status instead)
        dock_commands_action = QAction("Dock", parent=self)
        dock_commands_action.setStatusTip("Dock/Undock the command dock")
        dock_commands_action.setCheckable(True)
        dock_commands_action.setChecked(not self.command_dock_widget.isFloating())
        dock_commands_action.triggered.connect(
            lambda make_floating: self.command_dock_widget.setFloating(
                not make_floating
            )
        )
        self.command_dock_widget.topLevelChanged.connect(
            lambda is_floating: dock_commands_action.setChecked(not is_floating)
        )
        view_commands_menu.addAction(dock_commands_action)

        showLogsButton = QAction("Logs", parent=self)
        showLogsButton.setStatusTip("Show the logs")
        showLogsButton.setCheckable(True)
        showLogsButton.setChecked(not self.log_tabs.isHidden())
        showLogsButton.triggered.connect(self.log_tabs.setVisible)
        view_menu.addAction(showLogsButton)

        # Add to Help menu
        showAboutButton = QAction("About", parent=self)
        showAboutButton.setStatusTip("Show information about CLARITE")
        showAboutButton.triggered.connect(
            lambda: AboutDialog(parent=self.appctx.main_window).show()
        )
        help_menu.addAction(showAboutButton)
        showLicenseButton = QAction("License Info", parent=self)
        showLicenseButton.setStatusTip("Show the license (GPLv3) for the CLARITE GUI")
        showLicenseButton.triggered.connect(
            lambda: LicenseDialog(parent=self.appctx.main_window).show()
        )
        help_menu.addAction(showLicenseButton)