Beispiel #1
0
class CustomScrollableList(QWidget):
    def __init__(self, parent, item_type, floating_widget=None):
        super(CustomScrollableList, self).__init__()
        self.parent = parent
        self.item_type = item_type
        self.floating_widget = floating_widget

        self.layout = QVBoxLayout(self)
        self.layout.setContentsMargins(0, 0, 0, 0)

        self.list_widget = QWidget()
        self.list_layout = QVBoxLayout(self.list_widget)
        self.list_layout.setContentsMargins(0, 0, 0, 0)
        self.list_layout.setSpacing(10)
        self.list_layout.setAlignment(Qt.AlignmentFlag.AlignTop)

        self.scroll_area = QScrollArea()
        self.scroll_area.setWidgetResizable(True)
        self.scroll_area.setFrameStyle(0)
        self.scroll_area.setWidget(self.list_widget)
        self.layout.addWidget(self.scroll_area)

        if self.floating_widget is not None:
            self.list_layout.addWidget(self.floating_widget)

        self.item_widgets = []
        self.num_visible_item_widgets = 0

    def last_item_widget(self):
        return self.item_widgets[self.num_visible_item_widgets - 1]

    def update_item_list(self, item_list, params=None):

        if self.floating_widget is not None:
            self.list_layout.removeWidget(self.floating_widget)

        # make sure that there are enough item widgets
        while len(item_list) > len(self.item_widgets):
            self.item_widgets.append(self.item_type(self.parent))

        # make sure that the correct number of item widgets is shown
        while len(item_list) > self.num_visible_item_widgets:
            widget = self.item_widgets[self.num_visible_item_widgets]
            self.list_layout.addWidget(widget)
            widget.show()
            self.num_visible_item_widgets += 1

        while len(item_list) < self.num_visible_item_widgets:
            widget = self.item_widgets[self.num_visible_item_widgets - 1]
            widget.hide()
            self.list_layout.removeWidget(widget)
            self.num_visible_item_widgets -= 1

        if self.floating_widget is not None:
            self.list_layout.addWidget(self.floating_widget)

        # update item widgets
        for item, item_widget in zip(item_list,
                                     self.item_widgets[:len(item_list)]):
            item_widget.update_item(item, params)

    def enable_input(self):
        for item_widget in self.item_widgets:
            item_widget.enable_input()

    def disable_input(self):
        for item_widget in self.item_widgets:
            item_widget.disable_input()
class AgentVariablesGroupView(QWidget):
    onVariablesChange = pyqtSignal(dict)

    def __init__(
        self,
        variables: dict[str, tuple[type, Any]],
        parent: Optional[QWidget] = None,
        *args: Tuple[Any, Any],
        **kwargs: Tuple[Any, Any],
    ) -> None:
        """
        The two vertical box layouts of the variable names and their respective values.
        """
        super(AgentVariablesGroupView, self).__init__(parent=parent,
                                                      *args,
                                                      **kwargs)
        self.__variables = variables
        self.setContentsMargins(0, 0, 0, 0)
        # keep our name and value labels here so we can destroy them when we need to redraw with updated variables
        namesLabels = list[QLabel]()
        valuesLabels = list[QLabel]()

        self.__horizontalGroupBoxLayout = QHBoxLayout()
        self.__variableNamesBox = QVBoxLayout()
        self.__variableValuesBox = QVBoxLayout()

        # submethod to update the 'names' and 'values' vertical views properly
        def updateVariableViews(vars: dict[str, tuple[type, Any]]) -> None:
            # for each name label in the list of namelabel widgets,
            for nameLabel in namesLabels:
                # then clear the label so it doesn't redraw later…
                nameLabel.clear()
                # and remove it from the vertical box layout.
                self.__variableNamesBox.removeWidget(nameLabel)

            # for each value label in the list of valuelabel widgets,
            for valueLabel in valuesLabels:
                # then clear the label so it doesn't redraw later…
                valueLabel.clear()
                # and remove it from the vertical box layout.
                self.__variableValuesBox.removeWidget(valueLabel)

            self.__variables = vars

            # for each variable name, then…
            # make a copy of the KeysView (keys) so it won't unexpectedly change size during iteration
            currentKeys = list(self.__variables.keys())
            for variableName in currentKeys:
                # add it to the list of label widgets as a QLabel
                namesLabels.append(QLabel(variableName))
                # …also add it to the vertical labelNames labels box
                self.__variableNamesBox.addWidget(namesLabels[-1])

            # for each variable value, then…
            for variableValue in self.__variables.values():
                # add it to the list of label widgets as a QLabel
                valuesLabels.append(QLabel(str(variableValue)))
                # …also add it to the vertical labelValues labels box
                self.__variableValuesBox.addWidget(valuesLabels[-1])

            # add the layouts to our main window layout
            self.__horizontalGroupBoxLayout.addLayout(self.__variableNamesBox)
            self.__horizontalGroupBoxLayout.addLayout(self.__variableValuesBox)

            # aaand finally update the window to reflect our changes.
            self.update()

        self.onVariablesChange.connect(updateVariableViews)
        updateVariableViews(self.__variables)

        self.setLayout(self.__horizontalGroupBoxLayout)