Exemple #1
0
    def __init__(self, parent: QWidget, parent_layout: QVBoxLayout,
                 line_layout: QHBoxLayout, resource_database: ResourceDatabase,
                 requirement: RequirementArrayBase):
        self._editors = []
        self.resource_database = resource_database
        self._array_type = type(requirement)

        # the parent is added to a layout which is added to parent_layout, so we
        index = parent_layout.indexOf(line_layout) + 1

        self.group_box = QGroupBox(parent)
        self.group_box.setStyleSheet("QGroupBox { margin-top: 2px; }")
        parent_layout.insertWidget(index, self.group_box)
        self.item_layout = QVBoxLayout(self.group_box)
        self.item_layout.setContentsMargins(8, 2, 2, 6)
        self.item_layout.setAlignment(Qt.AlignTop)

        self.new_item_button = QPushButton(self.group_box)
        self.new_item_button.setMaximumWidth(75)
        self.new_item_button.setText("New Row")
        self.new_item_button.clicked.connect(self.new_item)

        self.comment_text_box = QLineEdit(parent)
        self.comment_text_box.setText(requirement.comment or "")
        self.comment_text_box.setPlaceholderText("Comment")
        line_layout.addWidget(self.comment_text_box)

        for item in requirement.items:
            self._create_item(item)

        self.item_layout.addWidget(self.new_item_button)
class OrderableListWidget(QScrollArea):
    """All available items in this list"""
    _item_list: list[OrderableListItem]
    """This lists actual widget"""
    _widget: QWidget
    """The widgets layout"""
    _layout: QLayout
    """Decides which way this list is ordered; 1 for ascending, -1 for descending"""
    _order_factor: int

    def __init__(self, order_asc=True, orientation_horizontal=False):
        """Init gui
        :type order_asc: bool
        :param order_asc: Whether to order the list ascending
        :type orientation_horizontal: bool
        :param orientation_horizontal: Should the list orientation be horizontal?
        """
        super().__init__()
        if order_asc:
            self._order_factor = 1
        else:
            self._order_factor = -1
        self._widget = QWidget()
        self.setWidget(self._widget)
        self.setWidgetResizable(True)
        # Set layout
        if orientation_horizontal:
            self._layout = QHBoxLayout()
        else:
            self._layout = QVBoxLayout()
        self._widget.setLayout(self._layout)
        self._layout.setAlignment(Qt.AlignTop)
        self._item_list = []

    def _get_order(self, list_item_a, list_item_b):
        """Defines this lists widget order
        :type list_item_a: OrderableListItem
        :param list_item_a: The first item to compare
        :type list_item_b: OrderableListItem
        :param list_item_b: The second item to compare
        :returns -1|0|1: list_item_a is: before, same, after list_item_b"""
        str_a: str = list_item_a.get_order_string()
        str_b: str = list_item_b.get_order_string()

        if str_a == str_b:
            return 0
        elif str_a < str_b:
            return -1 * self._order_factor
        else:
            return 1 * self._order_factor

    def add(self, list_item):
        """Add a new item to the list
        :type list_item: OrderableListItem
        :param list_item: The item to add
        """
        # Subscribe to changes
        list_item.subscribe(OrderableListItem.DELETED, self._item_deleted)
        list_item.subscribe(OrderableListItem.UPDATED, self._item_updated)
        # Make sure to add the item only once
        if list_item not in self._item_list:
            list_item_inserted = False
            self._item_list.append(list_item)

            # Walk all existing items
            for i in range(self._layout.count()):
                existing_item: OrderableListItem = self._layout.itemAt(i).widget()

                if 1 == self._get_order(existing_item, list_item):
                    self._layout.insertWidget(i, list_item)
                    list_item_inserted = True
                    break
            if not list_item_inserted:
                self._layout.addWidget(list_item)

    def _item_deleted(self, item):
        """Delete an item from the list
        :type item: OrderableListItem
        :param item: The item to delete
        """
        # See if the item exists in this list
        try:
            i: int = self._item_list.index(item)
        except ValueError:
            return
        # Delete the item
        self._item_list.pop(i)

    def _item_updated(self, item):
        """Update the list with the items new information
        :type item: OrderableListItem
        :param item: The item that was updated
        """
        pass
Exemple #3
0
class ParameterEditor(QWidget):
    onParametersChanged = Signal()

    def __init__(self, program: Program):
        super().__init__()
        self._program = program

        parametersLabel = QLabel("Parameters")
        newParameterButton = QPushButton("Add Parameter")
        newParameterButton.clicked.connect(self.AddParameter)

        layout = QVBoxLayout()
        titleLayout = QHBoxLayout()
        titleLayout.addWidget(parametersLabel)
        titleLayout.addWidget(newParameterButton)
        layout.addLayout(titleLayout)

        self._listArea = QScrollArea()
        self._listArea.setWidgetResizable(True)
        self._listArea.setHorizontalScrollBarPolicy(Qt.ScrollBarAlwaysOff)
        self._listArea.setVerticalScrollBarPolicy(Qt.ScrollBarAlwaysOn)
        layout.addWidget(self._listArea, stretch=1)
        listWidget = QWidget()
        self._itemLayout = QVBoxLayout()
        self._itemLayout.setAlignment(Qt.AlignTop)
        listWidget.setLayout(self._itemLayout)
        self.setLayout(layout)
        self._listArea.setWidget(listWidget)

        self.items: List[ParameterEditorItem] = []

        self._temporaryParameters = program.parameters.copy()

        self.Populate()

    def AddParameter(self):
        newParameter = Parameter()
        self._temporaryParameters.append(newParameter)
        self.onParametersChanged.emit()
        self.AddToList(newParameter)

    def Populate(self):
        for parameter in self._temporaryParameters:
            self.AddToList(parameter)
        self._listArea.updateGeometry()

    def AddToList(self, parameter: Parameter):
        newItem = ParameterEditorItem(parameter)
        newItem.onRemoveParameter.connect(self.RemoveParameter)
        newItem.onMoveParameterUp.connect(self.MoveParameterUp)
        newItem.onMoveParameterDown.connect(self.MoveParameterDown)
        newItem.onChanged.connect(self.onParametersChanged.emit)
        self._itemLayout.addWidget(newItem)
        self.items.append(newItem)

    def RemoveFromList(self, parameter: Parameter):
        item = [item for item in self.items if item.parameter is parameter]
        item[0].deleteLater()
        self.items.remove(item[0])

    def RemoveParameter(self, parameter: Parameter):
        self._temporaryParameters.remove(parameter)
        self.onParametersChanged.emit()
        self.RemoveFromList(parameter)

    def Reorder(self, parameter: Parameter, newPosition: int):
        item = [item for item in self.items if item.parameter is parameter][0]
        self._itemLayout.removeWidget(item)
        self._itemLayout.insertWidget(newPosition, item)
        self.items.remove(item)
        self.items.insert(newPosition, item)
        self._temporaryParameters.remove(parameter)
        self._temporaryParameters.insert(newPosition, parameter)
        self.onParametersChanged.emit()

    def MoveParameterUp(self, parameter: Parameter):
        index = self._temporaryParameters.index(parameter)
        self.Reorder(parameter, index - 1)

    def MoveParameterDown(self, parameter: Parameter):
        index = self._temporaryParameters.index(parameter)
        self.Reorder(parameter, index + 1)

    def Save(self):
        self._program.parameters = self._temporaryParameters
        self._temporaryParameters = self._program.parameters.copy()
        for item in self.items:
            item.UpdateParameter()