Exemple #1
0
    def __init__(self,
                 parent=None,
                 title="",
                 text="",
                 textFormat=Qt.AutoText,
                 icon=QIcon(),
                 wordWrap=True,
                 standardButtons=NoButton,
                 acceptLabel="Ok",
                 rejectLabel="No",
                 **kwargs):
        super().__init__(parent, **kwargs)
        self._margin = 10  # used in stylesheet and for dismiss button

        layout = QHBoxLayout()
        if sys.platform == "darwin":
            layout.setContentsMargins(6, 6, 6, 6)
        else:
            layout.setContentsMargins(9, 9, 9, 9)

        self.setStyleSheet("""
                            NotificationWidget {
                                margin: """ + str(self._margin) + """px;
                                background: #626262;
                                border: 1px solid #999999;
                                border-radius: 8px;
                            }
                            NotificationWidget QLabel#text-label {
                                color: white;
                            }
                            NotificationWidget QLabel#title-label {
                                color: white;
                                font-weight: bold;
                            }""")

        self._msgwidget = NotificationMessageWidget(
            parent=self,
            title=title,
            text=text,
            textFormat=textFormat,
            icon=icon,
            wordWrap=wordWrap,
            standardButtons=standardButtons,
            acceptLabel=acceptLabel,
            rejectLabel=rejectLabel)
        self._msgwidget.accepted.connect(self.accepted)
        self._msgwidget.rejected.connect(self.rejected)
        self._msgwidget.clicked.connect(self.clicked)

        self._dismiss_button = SimpleButton(
            parent=self,
            icon=QIcon(self.style().standardIcon(
                QStyle.SP_TitleBarCloseButton)))
        self._dismiss_button.setFixedSize(18, 18)
        self._dismiss_button.clicked.connect(self.dismissed)

        def dismiss_handler():
            self.clicked.emit(self._dismiss_button)

        self._dismiss_button.clicked.connect(dismiss_handler)

        layout.addWidget(self._msgwidget)
        self.setLayout(layout)

        self.setFixedWidth(400)
Exemple #2
0
    def set_basic_layout(self):
        """Provide the basic widget layout

        Which parts are created is regulated by class attributes
        `want_main_area`, `want_control_area`, `want_message_bar` and
        `buttons_area_orientation`, the presence of method `send_report`
        and attribute `graph_name`.
        """
        self.setLayout(QVBoxLayout())
        self.layout().setContentsMargins(2, 2, 2, 2)

        if not self.resizing_enabled:
            self.layout().setSizeConstraint(QVBoxLayout.SetFixedSize)

        self.want_main_area = self.want_main_area or self.graph_name
        self._create_default_buttons()

        self._insert_splitter()
        if self.want_control_area:
            self._insert_control_area()
        if self.want_main_area:
            self._insert_main_area()

        if self.want_message_bar:
            # Use a OverlayWidget for status bar positioning.
            c = OverlayWidget(self, alignment=Qt.AlignBottom)
            c.setSizePolicy(QSizePolicy.Expanding, QSizePolicy.Fixed)
            c.setWidget(self)
            c.setLayout(QVBoxLayout())
            c.layout().setContentsMargins(0, 0, 0, 0)
            sb = QStatusBar()
            sb.setSizePolicy(QSizePolicy.Ignored, QSizePolicy.Maximum)
            sb.setSizeGripEnabled(self.resizing_enabled)
            c.layout().addWidget(sb)

            help = self.__help_action
            icon = QIcon(gui.resource_filename("icons/help.svg"))
            icon.addFile(gui.resource_filename("icons/help-hover.svg"),
                         mode=QIcon.Active)
            help_button = SimpleButton(
                icon=icon,
                toolTip="Show widget help",
                visible=help.isVisible(),
            )

            @help.changed.connect
            def _():
                help_button.setVisible(help.isVisible())
                help_button.setEnabled(help.isEnabled())

            help_button.clicked.connect(help.trigger)
            sb.addWidget(help_button)

            if self.graph_name is not None:
                icon = QIcon(gui.resource_filename("icons/chart.svg"))
                icon.addFile(gui.resource_filename("icons/chart-hover.svg"),
                             mode=QIcon.Active)
                b = SimpleButton(
                    icon=icon,
                    toolTip="Save Image",
                )
                b.clicked.connect(self.save_graph)
                sb.addWidget(b)
            if hasattr(self, "send_report"):
                icon = QIcon(gui.resource_filename("icons/report.svg"))
                icon.addFile(gui.resource_filename("icons/report-hover.svg"),
                             mode=QIcon.Active)
                b = SimpleButton(icon=icon, toolTip="Report")
                b.clicked.connect(self.show_report)
                sb.addWidget(b)
            self.message_bar = MessagesWidget(self)
            self.message_bar.setSizePolicy(QSizePolicy.Preferred,
                                           QSizePolicy.Preferred)
            pb = QProgressBar(maximumWidth=120, minimum=0, maximum=100)
            pb.setSizePolicy(QSizePolicy.Maximum, QSizePolicy.Ignored)
            pb.setAttribute(Qt.WA_LayoutUsesWidgetRect)
            pb.setAttribute(Qt.WA_MacMiniSize)
            pb.hide()
            sb.addPermanentWidget(pb)
            sb.addPermanentWidget(self.message_bar)

            def statechanged():
                pb.setVisible(bool(self.processingState) or self.isBlocking())
                if self.isBlocking() and not self.processingState:
                    pb.setRange(0, 0)  # indeterminate pb
                elif self.processingState:
                    pb.setRange(0, 100)  # determinate pb

            self.processingStateChanged.connect(statechanged)
            self.blockingStateChanged.connect(statechanged)

            @self.progressBarValueChanged.connect
            def _(val):
                pb.setValue(int(val))

            # Reserve the bottom margins for the status bar
            margins = self.layout().contentsMargins()
            margins.setBottom(sb.sizeHint().height())
            self.setContentsMargins(margins)
Exemple #3
0
class NotificationWidget(QWidget):
    #: Emitted when a button with an Accept role is clicked
    accepted = Signal()
    #: Emitted when a button with a Reject role is clicked
    rejected = Signal()
    #: Emitted when a button with a Dismiss role is clicked
    dismissed = Signal()
    #: Emitted when a button is clicked
    clicked = Signal(QAbstractButton)

    NoButton, Ok, Close = list(NotificationMessageWidget.StandardButton)
    InvalidRole, AcceptRole, RejectRole, DismissRole = \
        list(NotificationMessageWidget.ButtonRole)

    def __init__(self,
                 parent=None,
                 title="",
                 text="",
                 textFormat=Qt.AutoText,
                 icon=QIcon(),
                 wordWrap=True,
                 standardButtons=NoButton,
                 acceptLabel="Ok",
                 rejectLabel="No",
                 **kwargs):
        super().__init__(parent, **kwargs)
        self._margin = 10  # used in stylesheet and for dismiss button

        layout = QHBoxLayout()
        if sys.platform == "darwin":
            layout.setContentsMargins(6, 6, 6, 6)
        else:
            layout.setContentsMargins(9, 9, 9, 9)

        self.setStyleSheet("""
                            NotificationWidget {
                                margin: """ + str(self._margin) + """px;
                                background: #626262;
                                border: 1px solid #999999;
                                border-radius: 8px;
                            }
                            NotificationWidget QLabel#text-label {
                                color: white;
                            }
                            NotificationWidget QLabel#title-label {
                                color: white;
                                font-weight: bold;
                            }""")

        self._msgwidget = NotificationMessageWidget(
            parent=self,
            title=title,
            text=text,
            textFormat=textFormat,
            icon=icon,
            wordWrap=wordWrap,
            standardButtons=standardButtons,
            acceptLabel=acceptLabel,
            rejectLabel=rejectLabel)
        self._msgwidget.accepted.connect(self.accepted)
        self._msgwidget.rejected.connect(self.rejected)
        self._msgwidget.clicked.connect(self.clicked)

        self._dismiss_button = SimpleButton(
            parent=self,
            icon=QIcon(self.style().standardIcon(
                QStyle.SP_TitleBarCloseButton)))
        self._dismiss_button.setFixedSize(18, 18)
        self._dismiss_button.clicked.connect(self.dismissed)

        def dismiss_handler():
            self.clicked.emit(self._dismiss_button)

        self._dismiss_button.clicked.connect(dismiss_handler)

        layout.addWidget(self._msgwidget)
        self.setLayout(layout)

        self.setFixedWidth(400)

    def resizeEvent(self, event):
        super().resizeEvent(event)
        if sys.platform == "darwin":
            corner_margin = 6
        else:
            corner_margin = 7
        x = self.width() - self._dismiss_button.width(
        ) - self._margin - corner_margin
        y = self._margin + corner_margin
        self._dismiss_button.move(x, y)

    def clone(self):
        cloned = NotificationWidget(
            parent=self.parent(),
            title=self.title(),
            text=self.text(),
            textFormat=self._msgwidget.textFormat(),
            icon=self.icon(),
            standardButtons=self._msgwidget.standardButtons(),
            acceptLabel=self._msgwidget.acceptLabel(),
            rejectLabel=self._msgwidget.rejectLabel())
        cloned.accepted.connect(self.accepted)
        cloned.rejected.connect(self.rejected)
        cloned.dismissed.connect(self.dismissed)

        # each canvas displays a clone of the original notification,
        # therefore the cloned buttons' events are connected to the original's
        # pylint: disable=protected-access
        button_map = dict(
            zip([b.button for b in cloned._msgwidget._buttons] +
                [cloned._dismiss_button],
                [b.button
                 for b in self._msgwidget._buttons] + [self._dismiss_button]))
        cloned.clicked.connect(lambda b: self.clicked.emit(button_map[b]))

        return cloned

    def paintEvent(self, event):
        opt = QStyleOption()
        opt.initFrom(self)
        painter = QPainter(self)
        self.style().drawPrimitive(QStyle.PE_Widget, opt, painter, self)

    @proxydoc(NotificationMessageWidget.setText)
    def setText(self, text):
        self._msgwidget.setText(text)

    @proxydoc(NotificationMessageWidget.text)
    def text(self):
        return self._msgwidget.text()

    @proxydoc(NotificationMessageWidget.setTitle)
    def setTitle(self, title):
        self._msgwidget.setTitle(title)

    @proxydoc(NotificationMessageWidget.title)
    def title(self):
        return self._msgwidget.title()

    @proxydoc(NotificationMessageWidget.setIcon)
    def setIcon(self, icon):
        self._msgwidget.setIcon(icon)

    @proxydoc(NotificationMessageWidget.icon)
    def icon(self):
        return self._msgwidget.icon()

    @proxydoc(NotificationMessageWidget.textFormat)
    def textFormat(self):
        return self._msgwidget.textFormat()

    @proxydoc(NotificationMessageWidget.setTextFormat)
    def setTextFormat(self, textFormat):
        self._msgwidget.setTextFormat(textFormat)

    @proxydoc(NotificationMessageWidget.setStandardButtons)
    def setStandardButtons(self, buttons):
        self._msgwidget.setStandardButtons(buttons)

    @proxydoc(NotificationMessageWidget.addButton)
    def addButton(self, *args):
        return self._msgwidget.addButton(*args)

    @proxydoc(NotificationMessageWidget.removeButton)
    def removeButton(self, button):
        self._msgwidget.removeButton(button)

    @proxydoc(NotificationMessageWidget.buttonRole)
    def buttonRole(self, button):
        if button is self._dismiss_button:
            return NotificationWidget.DismissRole
        return self._msgwidget.buttonRole(button)

    @proxydoc(NotificationMessageWidget.button)
    def button(self, standardButton):
        return self._msgwidget.button(standardButton)