Exemple #1
0
    def __init__(self,
                 parent=None,
                 icon=QIcon(),
                 title="",
                 text="",
                 wordWrap=False,
                 textFormat=Qt.PlainText,
                 standardButtons=NoButton,
                 acceptLabel="Ok",
                 rejectLabel="No",
                 **kwargs):
        super().__init__(parent, **kwargs)
        self._title = title
        self._text = text
        self._icon = QIcon()
        self._wordWrap = wordWrap
        self._standardButtons = NotificationMessageWidget.NoButton
        self._buttons = []
        self._acceptLabel = acceptLabel
        self._rejectLabel = rejectLabel

        self._iconlabel = QLabel(objectName="icon-label")
        self._titlelabel = QLabel(objectName="title-label",
                                  text=title,
                                  wordWrap=wordWrap,
                                  textFormat=textFormat)
        self._textlabel = QLabel(objectName="text-label",
                                 text=text,
                                 wordWrap=wordWrap,
                                 textFormat=textFormat)
        self._textlabel.setTextInteractionFlags(Qt.TextBrowserInteraction)
        self._textlabel.setOpenExternalLinks(True)

        if sys.platform == "darwin":
            self._titlelabel.setAttribute(Qt.WA_MacSmallSize)
            self._textlabel.setAttribute(Qt.WA_MacSmallSize)

        layout = QHBoxLayout()
        self._iconlabel.setSizePolicy(QSizePolicy.Fixed, QSizePolicy.Fixed)
        layout.addWidget(self._iconlabel)
        layout.setAlignment(self._iconlabel, Qt.AlignTop)

        message_layout = QVBoxLayout()
        self._titlelabel.setSizePolicy(QSizePolicy.Expanding,
                                       QSizePolicy.Fixed)
        if sys.platform == "darwin":
            self._titlelabel.setContentsMargins(0, 1, 0, 0)
        else:
            self._titlelabel.setContentsMargins(0, 0, 0, 0)
        message_layout.addWidget(self._titlelabel)
        self._textlabel.setSizePolicy(QSizePolicy.Expanding, QSizePolicy.Fixed)
        message_layout.addWidget(self._textlabel)

        self.button_layout = QHBoxLayout()
        self.button_layout.setAlignment(Qt.AlignLeft)
        message_layout.addLayout(self.button_layout)

        layout.addLayout(message_layout)
        layout.setSpacing(7)
        self.setLayout(layout)
        self.setIcon(icon)
        self.setStandardButtons(standardButtons)
Exemple #2
0
class NotificationMessageWidget(QWidget):
    #: Emitted when a button with the AcceptRole is clicked
    accepted = Signal()
    #: Emitted when a button with the RejectRole is clicked
    rejected = Signal()
    #: Emitted when a button is clicked
    clicked = Signal(QAbstractButton)

    class StandardButton(enum.IntEnum):
        NoButton, Ok, Close = 0x0, 0x1, 0x2

    NoButton, Ok, Close = list(StandardButton)

    class ButtonRole(enum.IntEnum):
        InvalidRole, AcceptRole, RejectRole, DismissRole = 0, 1, 2, 3

    InvalidRole, AcceptRole, RejectRole, DismissRole = list(ButtonRole)

    _Button = namedtuple("_Button", ["button", "role", "stdbutton"])

    def __init__(self,
                 parent=None,
                 icon=QIcon(),
                 title="",
                 text="",
                 wordWrap=False,
                 textFormat=Qt.PlainText,
                 standardButtons=NoButton,
                 acceptLabel="Ok",
                 rejectLabel="No",
                 **kwargs):
        super().__init__(parent, **kwargs)
        self._title = title
        self._text = text
        self._icon = QIcon()
        self._wordWrap = wordWrap
        self._standardButtons = NotificationMessageWidget.NoButton
        self._buttons = []
        self._acceptLabel = acceptLabel
        self._rejectLabel = rejectLabel

        self._iconlabel = QLabel(objectName="icon-label")
        self._titlelabel = QLabel(objectName="title-label",
                                  text=title,
                                  wordWrap=wordWrap,
                                  textFormat=textFormat)
        self._textlabel = QLabel(objectName="text-label",
                                 text=text,
                                 wordWrap=wordWrap,
                                 textFormat=textFormat)
        self._textlabel.setTextInteractionFlags(Qt.TextBrowserInteraction)
        self._textlabel.setOpenExternalLinks(True)

        if sys.platform == "darwin":
            self._titlelabel.setAttribute(Qt.WA_MacSmallSize)
            self._textlabel.setAttribute(Qt.WA_MacSmallSize)

        layout = QHBoxLayout()
        self._iconlabel.setSizePolicy(QSizePolicy.Fixed, QSizePolicy.Fixed)
        layout.addWidget(self._iconlabel)
        layout.setAlignment(self._iconlabel, Qt.AlignTop)

        message_layout = QVBoxLayout()
        self._titlelabel.setSizePolicy(QSizePolicy.Expanding,
                                       QSizePolicy.Fixed)
        if sys.platform == "darwin":
            self._titlelabel.setContentsMargins(0, 1, 0, 0)
        else:
            self._titlelabel.setContentsMargins(0, 0, 0, 0)
        message_layout.addWidget(self._titlelabel)
        self._textlabel.setSizePolicy(QSizePolicy.Expanding, QSizePolicy.Fixed)
        message_layout.addWidget(self._textlabel)

        self.button_layout = QHBoxLayout()
        self.button_layout.setAlignment(Qt.AlignLeft)
        message_layout.addLayout(self.button_layout)

        layout.addLayout(message_layout)
        layout.setSpacing(7)
        self.setLayout(layout)
        self.setIcon(icon)
        self.setStandardButtons(standardButtons)

    def setText(self, text):
        """
        Set the current message text.

        :type message: str
        """
        if self._text != text:
            self._text = text
            self._textlabel.setText(text)

    def text(self):
        """
        Return the current message text.

        :rtype: str
        """
        return self._text

    def setTitle(self, title):
        """
        Set the current title text.

        :type title: str
        """
        if self._title != title:
            self._title = title
            self._titleLabel.setText(title)

    def title(self):
        """
        Return the current title text.

        :rtype: str
        """
        return self._title

    def setIcon(self, icon):
        """
        Set the message icon.

        :type icon: QIcon | QPixmap | QString | QStyle.StandardPixmap
        """
        if isinstance(icon, QStyle.StandardPixmap):
            icon = self.style().standardIcon(icon)
        else:
            icon = QIcon(icon)

        if self._icon != icon:
            self._icon = QIcon(icon)
            if not self._icon.isNull():
                size = self.style().pixelMetric(QStyle.PM_SmallIconSize, None,
                                                self)
                pm = self._icon.pixmap(QSize(size, size))
            else:
                pm = QPixmap()

            self._iconlabel.setPixmap(pm)
            self._iconlabel.setVisible(not pm.isNull())

    def icon(self):
        """
        Return the current icon.

        :rtype: QIcon
        """
        return QIcon(self._icon)

    def setWordWrap(self, wordWrap):
        """
        Set the message text wrap property

        :type wordWrap: bool
        """
        if self._wordWrap != wordWrap:
            self._wordWrap = wordWrap
            self._textlabel.setWordWrap(wordWrap)

    def wordWrap(self):
        """
        Return the message text wrap property.

        :rtype: bool
        """
        return self._wordWrap

    def setTextFormat(self, textFormat):
        """
        Set message text format

        :type textFormat: Qt.TextFormat
        """
        self._textlabel.setTextFormat(textFormat)

    def textFormat(self):
        """
        Return the message text format.

        :rtype: Qt.TextFormat
        """
        return self._textlabel.textFormat()

    def setAcceptLabel(self, label):
        """
        Set the accept button label.
        :type label: str
        """
        self._acceptLabel = label

    def acceptLabel(self):
        """
        Return the accept button label.
        :rtype str
        """
        return self._acceptLabel

    def setRejectLabel(self, label):
        """
        Set the reject button label.
        :type label: str
        """
        self._rejectLabel = label

    def rejectLabel(self):
        """
        Return the reject button label.
        :rtype str
        """
        return self._rejectLabel

    def setStandardButtons(self, buttons):
        for button in NotificationMessageWidget.StandardButton:
            existing = self.button(button)
            if button & buttons and existing is None:
                self.addButton(button)
            elif existing is not None:
                self.removeButton(existing)

    def standardButtons(self):
        return functools.reduce(
            operator.ior,
            (slot.stdbutton
             for slot in self._buttons if slot.stdbutton is not None),
            NotificationMessageWidget.NoButton)

    def addButton(self, button, *rolearg):
        """
        addButton(QAbstractButton, ButtonRole)
        addButton(str, ButtonRole)
        addButton(StandardButton)

        Add and return a button
        """
        stdbutton = None
        if isinstance(button, QAbstractButton):
            if len(rolearg) != 1:
                raise TypeError("Wrong number of arguments for "
                                "addButton(QAbstractButton, role)")
            role = rolearg[0]
        elif isinstance(button, NotificationMessageWidget.StandardButton):
            if rolearg:
                raise TypeError("Wrong number of arguments for "
                                "addButton(StandardButton)")
            stdbutton = button
            if button == NotificationMessageWidget.Ok:
                role = NotificationMessageWidget.AcceptRole
                button = QPushButton(self._acceptLabel,
                                     default=False,
                                     autoDefault=False)
            elif button == NotificationMessageWidget.Close:
                role = NotificationMessageWidget.RejectRole
                button = QPushButton(self._rejectLabel,
                                     default=False,
                                     autoDefault=False)
        elif isinstance(button, str):
            if len(rolearg) != 1:
                raise TypeError("Wrong number of arguments for "
                                "addButton(str, ButtonRole)")
            role = rolearg[0]
            button = QPushButton(button, default=False, autoDefault=False)

        if sys.platform == "darwin":
            button.setAttribute(Qt.WA_MacSmallSize)

        self._buttons.append(
            NotificationMessageWidget._Button(button, role, stdbutton))
        button.clicked.connect(self._button_clicked)
        self._relayout()

        return button

    def _relayout(self):
        for slot in self._buttons:
            self.button_layout.removeWidget(slot.button)
        order = {
            NotificationWidget.AcceptRole: 0,
            NotificationWidget.RejectRole: 1,
        }
        ordered = sorted([
            b for b in self._buttons if
            self.buttonRole(b.button) != NotificationMessageWidget.DismissRole
        ],
                         key=lambda slot: order.get(slot.role, -1))

        prev = self._textlabel
        for slot in ordered:
            self.button_layout.addWidget(slot.button)
            QWidget.setTabOrder(prev, slot.button)

    def removeButton(self, button):
        """
        Remove a `button`.

        :type button: QAbstractButton
        """
        slot = [s for s in self._buttons if s.button is button]
        if slot:
            slot = slot[0]
            self._buttons.remove(slot)
            self.layout().removeWidget(slot.button)
            slot.button.setParent(None)

    def buttonRole(self, button):
        """
        Return the ButtonRole for button

        :type button: QAbstractButton
        """
        for slot in self._buttons:
            if slot.button is button:
                return slot.role
        return NotificationMessageWidget.InvalidRole

    def button(self, standardButton):
        """
        Return the button for the StandardButton.

        :type standardButton: StandardButton
        """
        for slot in self._buttons:
            if slot.stdbutton == standardButton:
                return slot.button
        return None

    def _button_clicked(self):
        button = self.sender()
        role = self.buttonRole(button)
        self.clicked.emit(button)

        if role == NotificationMessageWidget.AcceptRole:
            self.accepted.emit()
            self.close()
        elif role == NotificationMessageWidget.RejectRole:
            self.rejected.emit()
            self.close()
    def __init__(self, iterateSettings):
        nRows = len(iterateSettings["iterableAttrs"])
        if not nRows:
            return
        nCols = 5
        super().__init__()
        self.css = """
        QPushButton {background-color: #1588c5; color: white; height: 20px; border: 1px solid black; border-radius: 2px;}
        QPushButton:hover {background-color: #1555f5; }
        QPushButton:hover:pressed { background-color: #1588c5; color: black; border-style: inset; border: 1px solid white} 
        QPushButton:disabled { background-color: lightGray; border: 1px solid gray; } 
        """
        self.setMinimumSize(520, 240)
        self.iterateSettings = iterateSettings
        self.setWindowTitle("Edit iterate settings")
        self.table = QTableWidget()
        self.table.setColumnCount(nCols)
        for col in range(nCols - 1):
            self.table.horizontalHeader().setResizeMode(
                col, QtGui.QHeaderView.ResizeToContents)
        self.table.horizontalHeader().setResizeMode(nCols - 1,
                                                    QtGui.QHeaderView.Stretch)
        self.table.horizontalHeader().setStretchLastSection(True)
        self.table.setHorizontalHeaderLabels([
            "", "Parameter", "Group size", "Threads needed",
            "Required RAM (MB)"
        ])
        self.settingsCopy = copy.deepcopy(self.iterateSettings)
        self.table.setRowCount(nRows)
        rowNum = 0

        for parm in self.settingsCopy["iterableAttrs"]:
            # init values if they are not there
            if "data" not in self.settingsCopy:
                self.settingsCopy["data"] = {}
            if parm not in self.settingsCopy["data"]:
                self.settingsCopy["data"][parm] = {
                    "groupSize": "1",
                    "threads": "1",
                    "ram": "0",
                }

            if ("groupSize" not in self.settingsCopy["data"][parm].keys()
                    or not self.settingsCopy["data"][parm]["groupSize"]):
                self.settingsCopy["data"][parm]["groupSize"] = "1"
            if ("threads" not in self.settingsCopy["data"][parm].keys()
                    or not self.settingsCopy["data"][parm]["threads"]):
                self.settingsCopy["data"][parm]["threads"] = "1"
            if ("ram" not in self.settingsCopy["data"][parm].keys()
                    or not self.settingsCopy["data"][parm]["ram"]):
                self.settingsCopy["data"][parm]["ram"] = "0"
            # make column items
            cb = QTableWidgetItem()
            parmItem = QTableWidgetItem(parm)
            groupSizeItem = QTableWidgetItem(
                self.settingsCopy["data"][parm]["groupSize"])
            threadItem = QTableWidgetItem(
                self.settingsCopy["data"][parm]["threads"])
            ramItem = QTableWidgetItem(self.settingsCopy["data"][parm]["ram"])

            self.setSelect(parmItem, False)
            parmItem.setFlags(parmItem.flags() ^ Qt.ItemIsEditable)
            parmItem.setFlags(parmItem.flags() ^ Qt.ItemIsSelectable)
            cb.setFlags(cb.flags() ^ Qt.ItemIsSelectable)
            if ("iteratedAttrs" in self.settingsCopy
                    and parm in self.settingsCopy["iteratedAttrs"]):
                cb.setCheckState(QtCore.Qt.Checked)
            else:
                cb.setCheckState(QtCore.Qt.Unchecked)
                self.setEnable(parmItem, False)
                self.setEnableSelect(groupSizeItem, False)
                self.setEnableSelect(threadItem, False)
                self.setEnableSelect(ramItem, False)

            self.table.setItem(rowNum, 0, cb)
            self.table.setItem(rowNum, 1, parmItem)
            self.table.setItem(rowNum, 2, groupSizeItem)
            self.table.setItem(rowNum, 3, threadItem)
            self.table.setItem(rowNum, 4, ramItem)
            rowNum = rowNum + 1
        self.table.cellChanged.connect(self.onCheckBoxChanged)

        # buttons for save and load

        saveBtn = gui.button(None, self, "Save", callback=self.save)
        saveBtn.setStyleSheet(self.css)
        saveBtn.setFixedSize(70, 20)

        # table
        tableBox = QGroupBox()
        scroll_area = QScrollArea(verticalScrollBarPolicy=Qt.ScrollBarAlwaysOn)
        scroll_area.setWidget(tableBox)
        scroll_area.setWidgetResizable(True)
        tableLayout = QHBoxLayout()
        tableLayout.addWidget(self.table)
        tableBox.setLayout(tableLayout)

        # buttons
        buttonLayout = QHBoxLayout()
        buttonLayout.setAlignment(Qt.AlignTop)
        buttonLayout.addWidget(saveBtn)

        iterateLayout = QVBoxLayout()
        iterateLayout.addWidget(tableBox)
        iterateLayout.addLayout(buttonLayout)
        self.setLayout(iterateLayout)