Exemplo n.º 1
0
class TimerWidget(QLabel):
    def __init__(self,ressource_directory, dim: QSize, clock_dim_ratio: tuple=(0.9, 0.35), clock_color="#FFFFFF", dev_mode=False):
        super().__init__()
        self.setMaximumSize(dim)
        self.setMinimumSize(dim)
        self.font_color = clock_color
        # Setup clock background
        self._load_timer_picture(ressource_directory)
        #self.setPixmap(self.fond_pixmap.scaled(dim, Qt.KeepAspectRatio))
        self.setPixmap(self.fond_pixmap.scaled(QSize(dim.width()-5,dim.height()-5), Qt.KeepAspectRatio))
        self.setContentsMargins((dim.width() - self.pixmap().width()) * 0.5,
                                (dim.height() - self.pixmap().height()) * 0.5,
                                (dim.width() - self.pixmap().width()) * 0.5,
                                (dim.height() - self.pixmap().height()) * 0.5)
        if dev_mode:
            self.setStyleSheet("background-color:yellow")
        else:
            self.setAttribute(Qt.WA_TranslucentBackground, True)
        # Setup clock foreground
        self.clock_layout = QtGui.QGridLayout()
        self.setLayout(self.clock_layout)
        self.clock_layout.setContentsMargins(0,0,0,0)
        self.clock_label = QLabel()
        self.clock_layout.addWidget(self.clock_label)
        self.clock_label.setAlignment(Qt.AlignCenter)
        #self.default_font = self.font() #TODO set custom font
        font = self.clock_label.font()
        font.setBold(True)
        self.clock_label.setFont(font)
        bound = self.clock_label.fontMetrics().boundingRect("00")
        font_size_ratio = min(dim.width() * clock_dim_ratio[0] / bound.width() * 0.5,
                              dim.height() * clock_dim_ratio[1] / bound.height())
        font.setPointSizeF(font_size_ratio * self.clock_label.font().pointSize()+10)
        self.clock_label.setFont(font)
        self.clock_label.setAttribute(Qt.WA_TranslucentBackground, True)
        self.set_timer_value(0)

    # TODO def adjustSize , to resize the widget

    def set_timer_value(self, new_val):
        self.clock_label.setText("<font color=" + self.font_color + ">" + str(new_val) + "</font>")

    def _load_timer_picture(self, ressource_directory):
        """Load les Pixelmap des images du timer
        Utile a l'initialisation """
        # Image de fond
        self.fond_pixmap = QtGui.QPixmap(ressource_directory + "fond_timer.png")
Exemplo n.º 2
0
def _get_pos_widget(name, backgroundColor, foregroundColor):
    label = QLabel()
    label.setAttribute(Qt.WA_TransparentForMouseEvents, True)

    pixmap = QPixmap(25*10, 25*10)
    pixmap.fill(backgroundColor)
    painter = QPainter()
    painter.begin(pixmap)
    pen = QPen(foregroundColor)
    painter.setPen(pen)
    painter.setRenderHint(QPainter.Antialiasing)
    font = QFont()
    font.setBold(True)
    font.setPixelSize(25*10-30)
    path = QPainterPath()
    path.addText(QPointF(50, 25*10-50), font, name)
    brush = QBrush(foregroundColor)
    painter.setBrush(brush)
    painter.drawPath(path)
    painter.setFont(font)
    painter.end()
    pixmap = pixmap.scaled(QSize(20,20),
                           Qt.KeepAspectRatio,
                           Qt.SmoothTransformation)
    label.setPixmap(pixmap)

    spinbox = QSpinBox()
    spinbox.setAttribute(Qt.WA_TransparentForMouseEvents, True)
    spinbox.setEnabled(False)
    spinbox.setAlignment(Qt.AlignCenter)
    spinbox.setToolTip("{0} Spin Box".format(name))
    spinbox.setButtonSymbols(QAbstractSpinBox.NoButtons)
    spinbox.setMaximumHeight(20)
    spinbox.setMaximum(9999)
    font = spinbox.font()
    font.setPixelSize(14)
    spinbox.setFont(font)
    sheet = TEMPLATE.format(foregroundColor.name(),
                            backgroundColor.name())
    spinbox.setStyleSheet(sheet)
    return label, spinbox
Exemplo n.º 3
0
def _get_pos_widget(name, backgroundColor, foregroundColor):
    label = QLabel()
    label.setAttribute(Qt.WA_TransparentForMouseEvents, True)

    pixmap = QPixmap(25*10, 25*10)
    pixmap.fill(backgroundColor)
    painter = QPainter()
    painter.begin(pixmap)
    pen = QPen(foregroundColor)
    painter.setPen(pen)
    painter.setRenderHint(QPainter.Antialiasing)
    font = QFont()
    font.setBold(True)
    font.setPixelSize(25*10-30)
    path = QPainterPath()
    path.addText(QPointF(50, 25*10-50), font, name)
    brush = QBrush(foregroundColor)
    painter.setBrush(brush)
    painter.drawPath(path)
    painter.setFont(font)
    painter.end()
    pixmap = pixmap.scaled(QSize(20,20),
                           Qt.KeepAspectRatio,
                           Qt.SmoothTransformation)
    label.setPixmap(pixmap)

    spinbox = QSpinBox()
    spinbox.setAttribute(Qt.WA_TransparentForMouseEvents, True)
    spinbox.setEnabled(False)
    spinbox.setAlignment(Qt.AlignCenter)
    spinbox.setToolTip("{0} Spin Box".format(name))
    spinbox.setButtonSymbols(QAbstractSpinBox.NoButtons)
    spinbox.setMaximumHeight(20)
    spinbox.setMaximum(9999)
    font = spinbox.font()
    font.setPixelSize(14)
    spinbox.setFont(font)
    sheet = TEMPLATE.format(foregroundColor.name(),
                            backgroundColor.name())
    spinbox.setStyleSheet(sheet)
    return label, spinbox
Exemplo n.º 4
0
 def createAxisLabel(self):
     axisLabel = QLabel()
     axisLabel.setAttribute(Qt.WA_TransparentForMouseEvents, True)
     pixmap = self.createAxisLabelPixmap()
     axisLabel.setPixmap(pixmap)
     return axisLabel
Exemplo n.º 5
0
class ThumbnailWidget(QFrame):
    def __init__(self, parent, svg_data="", text=""):
        QFrame.__init__(self, parent)

        self.setFrameStyle(QFrame.StyledPanel)

        self.label = QLabel(text, self)
        self.label.setWordWrap(True)

        self.label.setSizePolicy(QSizePolicy.Ignored, QSizePolicy.Expanding)
        self.label.setAlignment(Qt.AlignCenter)
        self.label.setAttribute(Qt.WA_TransparentForMouseEvents)

        self.svg = SVGThumbnailWidget(svg_data, parent=self)
        self.svg.setAttribute(Qt.WA_TransparentForMouseEvents)

        layout = QVBoxLayout()
        layout.addWidget(self.label, stretch=1, alignment=Qt.AlignCenter)
        layout.addWidget(self.svg, stretch=4, alignment=Qt.AlignCenter)

        self.setLayout(layout)
        self.setSizePolicy(QSizePolicy.Fixed, QSizePolicy.Fixed)

        self._selected = False

    def setSelected(self, val):
        if self._selected != val:
            self._selected = val
            self.svg.setSelected(val)

    def getSelected(self):
        return self._selected

    selected = property(getSelected, setSelected)

    def setData(self, data):
        self.svg.setData(data)

    def setImageSize(self, width, height):
        self.svg.setFixedSize(width, height)

    def paintEvent(self, event):
        QFrame.paintEvent(self, event)

    def mousePressEvent(self, event):
        if event.button() & Qt.LeftButton:
            parent = self.parent()
            if event.modifiers() & Qt.ControlModifier:
                self.setSelected(not self._selected)
            else:
                for child in parent.findChildren(ThumbnailWidget):
                    child.setSelected(False)

                self.setSelected(True)

            parent.selectionChanged.emit()

        super(ThumbnailWidget, self).mousePressEvent(event)

    def mouseDoubleClickEvent(self, event):
        self._bigimage = BigSvgWidget()
        self._bigimage.load(QByteArray(self.svg._data))
        self._bigimage.show()

    def customEvent(self, event):
        self.layout().invalidate()
        self.update()
Exemplo n.º 6
0
 def createAxisLabel(self):
     axisLabel = QLabel()
     axisLabel.setAttribute(Qt.WA_TransparentForMouseEvents, True)
     pixmap = self.createAxisLabelPixmap()
     axisLabel.setPixmap(pixmap)
     return axisLabel
Exemplo n.º 7
0
class MessageWidget(QWidget):
    """
    A widget displaying a simple message to the user.

    This is an alternative to a full QMessageBox intended for inline
    modeless messages.

    [[icon] {Message text} (Ok) (Cancel)]
    """
    #: 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 with the HelpRole is clicked
    helpRequested = Signal()
    #: Emitted when a button is clicked
    clicked = Signal(QAbstractButton)

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

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

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

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

    def __init__(self, parent=None, icon=QIcon(), text="", wordWrap=False,
                 textFormat=Qt.AutoText, standardButtons=NoButton, **kwargs):
        super().__init__(parent, **kwargs)
        self.__text = text
        self.__icon = QIcon()
        self.__wordWrap = wordWrap
        self.__standardButtons = MessageWidget.NoButton
        self.__buttons = []

        layout = QHBoxLayout()
        layout.setContentsMargins(8, 0, 8, 0)

        self.__iconlabel = QLabel(objectName="icon-label")
        self.__iconlabel.setSizePolicy(QSizePolicy.Fixed, QSizePolicy.Fixed)
        self.__textlabel = QLabel(objectName="text-label", text=text,
                                  wordWrap=wordWrap, textFormat=textFormat)

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

        layout.addWidget(self.__iconlabel)
        layout.addWidget(self.__textlabel)

        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 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 changeEvent(self, event):
        # reimplemented
        if event.type() == 177:  # QEvent.MacSizeChange:
            ...
        super().changeEvent(event)

    def setStandardButtons(self, buttons):
        for button in MessageWidget.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),
            MessageWidget.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, MessageWidget.StandardButton):
            if len(rolearg) != 0:
                raise TypeError("Wrong number of arguments for "
                                "addButton(StandardButton)")
            stdbutton = button
            if button == MessageWidget.Ok:
                role = MessageWidget.AcceptRole
                button = QPushButton("Ok", default=False, autoDefault=False)
            elif button == MessageWidget.Close:
                role = MessageWidget.RejectRole
#                 button = QPushButton(
#                     default=False, autoDefault=False, flat=True,
#                     icon=QIcon(self.style().standardIcon(
#                                QStyle.SP_TitleBarCloseButton)))
                button = SimpleButton(
                    icon=QIcon(self.style().standardIcon(
                               QStyle.SP_TitleBarCloseButton)))
            elif button == MessageWidget.Help:
                role = MessageWidget.HelpRole
                button = QPushButton("Help", 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(MessageWidget._Button(button, role, stdbutton))
        button.clicked.connect(self.__button_clicked)
        self.__relayout()

        return 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: QAbsstractButton
        """
        for slot in self.__buttons:
            if slot.button is button:
                return slot.role
        else:
            return MessageWidget.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
        else:
            return None

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

        if role == MessageWidget.AcceptRole:
            self.accepted.emit()
            self.close()
        elif role == MessageWidget.RejectRole:
            self.rejected.emit()
            self.close()
        elif role == MessageWidget.HelpRole:
            self.helpRequested.emit()

    def __relayout(self):
        for slot in self.__buttons:
            self.layout().removeWidget(slot.button)
        order = {
            MessageOverlayWidget.HelpRole: 0,
            MessageOverlayWidget.AcceptRole: 2,
            MessageOverlayWidget.RejectRole: 3,
        }
        orderd = sorted(self.__buttons,
                        key=lambda slot: order.get(slot.role, -1))

        prev = self.__textlabel
        for slot in orderd:
            self.layout().addWidget(slot.button)
            QWidget.setTabOrder(prev, slot.button)
Exemplo n.º 8
0
class PreView(QGraphicsView):
    def __init__(self):
        QGraphicsView.__init__(self)

        self.zoom = 2
        self.scale(self.zoom, self.zoom)
        self.lastSize = 0

        self.setDragMode(QGraphicsView.ScrollHandDrag)
        #        self.setHorizontalScrollBarPolicy(Qt.ScrollBarAlwaysOff)
        #        self.setVerticalScrollBarPolicy(Qt.ScrollBarAlwaysOff)
        self.installEventFilter(self)

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

        self.ellipseLabel = QLabel()
        self.ellipseLabel.setMinimumWidth(self.width())
        self.hudLayout.addWidget(self.ellipseLabel)
        self.ellipseLabel.setAttribute(Qt.WA_TransparentForMouseEvents, True)

    def setPreviewImage(self, previewImage):
        self.grscene = QGraphicsScene()
        pixmapImage = QPixmap(previewImage)
        self.grscene.addPixmap(pixmapImage)
        self.setScene(self.grscene)

    def eventFilter(self, obj, event):
        if (event.type() == QEvent.Resize):
            self.ellipseLabel.setMinimumWidth(self.width())
            self.updateFilledCircle(self.lastSize)
        return False

    def sizeHint(self):
        return QSize(200, 200)

    def setFilledBrsuh(self, size):
        self.updateFilledCircle(size)

    def updateCircle(self, s):
        size = s * self.zoom
        pixmap = QPixmap(self.width(), self.height())
        pixmap.fill(Qt.transparent)
        #painter ellipse 1
        painter = QPainter()
        painter.begin(pixmap)
        painter.setRenderHint(QPainter.Antialiasing)
        pen = QPen(Qt.red)
        pen.setWidth(3)
        painter.setPen(pen)
        brush = QBrush(Qt.green)
        painter.setBrush(brush)
        painter.drawEllipse(
            QRect(self.width() / 2 - size / 2,
                  self.height() / 2 - size / 2, size, size))
        painter.end()
        #painter ellipse 2
        painter2 = QPainter()
        painter2.begin(pixmap)
        painter2.setRenderHint(QPainter.Antialiasing)
        pen2 = QPen(Qt.green)
        pen2.setStyle(Qt.DotLine)
        pen2.setWidth(3)
        painter2.setPen(pen2)
        painter2.drawEllipse(
            QRect(self.width() / 2 - size / 2,
                  self.height() / 2 - size / 2, size, size))
        painter2.end()

        self.ellipseLabel.setPixmap(QPixmap(pixmap))
        self.lastSize = s

    def updateFilledCircle(self, s):
        size = s * self.zoom
        pixmap = QPixmap(self.width(), self.height())
        pixmap.fill(Qt.transparent)
        #painter filled ellipse
        p = QPalette()
        painter = QPainter()
        painter.begin(pixmap)
        painter.setRenderHint(QPainter.Antialiasing)
        brush = QBrush(p.link().color())
        painter.setBrush(brush)
        painter.setOpacity(0.4)
        painter.drawEllipse(
            QRect(self.width() / 2 - size / 2,
                  self.height() / 2 - size / 2, size, size))
        painter.end()
        #painter ellipse 2
        painter2 = QPainter()
        painter2.begin(pixmap)
        painter2.setRenderHint(QPainter.Antialiasing)
        pen2 = QPen(Qt.green)
        pen2.setWidth(1)
        painter2.setPen(pen2)
        painter2.drawEllipse(
            QRect(self.width() / 2 - size / 2,
                  self.height() / 2 - size / 2, size, size))
        painter2.end()

        self.ellipseLabel.setPixmap(QPixmap(pixmap))
        self.lastSize = s
Exemplo n.º 9
0
Arquivo: ui.py Projeto: Xifax/ransukan
class GUI(QWidget):

    def __init__(self, parent=None):
        super(GUI, self).__init__(parent)

        self.create_ui_components()
        self.compose_ui()

        # Initializing: window composition, it's contents and event handlers
        self.init_composition()
        self.init_contents()
        self.init_actions()

        self.on_start()

    def create_ui_components(self):
        """
        Create layouts and qt controls.
        """
        self.layout = QGridLayout()

        self.kanjiGroup = QGroupBox()
        self.kanjiLayout = QGridLayout()

        # Kanji ui group
        self.day, self.week, self.month, self.year = \
        QLabel(KANJI), QLabel(KANJI), QLabel(KANJI), QLabel(KANJI)

        self.dayLabel, self.weekLabel, self.monthLabel, self.yearLabel = \
        QLabel('<b>Day</b>'), QLabel('<b>Week</b>'), \
        QLabel('<b>Month</b>'), QLabel('<b>Year</b>')

        # Main layout
        self.showAbout = QPushButton('A&bout')
        # DB controls (top)
        self.showDB, self.availableDB, self.changeDB = \
        QPushButton('&Change DB (active:)'), QComboBox(), QPushButton('&Remap')
        # General controls (bottom)
        self.getAll, self.showStats, self.quitApp, self.authGen, self.methodCombo = \
        QPushButton('&Get all'), QPushButton('&Stats'), QPushButton('&Quit'), \
        QPushButton('&Auth'), QComboBox()
        # Notifications
        self.progressBar = QProgressBar()
        self.statusMessage = QLabel()
        # About
        self.aboutBox = QMessageBox()

    def compose_ui(self):
        """
        Fill layouts and groups, initialize filters.
        """
        self.kanjiLayout.addWidget(self.day, 0, 0)
        self.kanjiLayout.addWidget(self.week, 0, 1)
        self.kanjiLayout.addWidget(self.dayLabel, 1, 0)
        self.kanjiLayout.addWidget(self.weekLabel, 1, 1)

        self.kanjiLayout.addWidget(self.month, 2, 0)
        self.kanjiLayout.addWidget(self.year, 2, 1)
        self.kanjiLayout.addWidget(self.monthLabel, 3, 0)
        self.kanjiLayout.addWidget(self.yearLabel, 3, 1)

        self.kanjiGroup.setLayout(self.kanjiLayout)

        self.layout.addWidget(self.showDB, 0, 0, 1, 2)
        self.layout.addWidget(self.availableDB, 1, 0)
        self.layout.addWidget(self.changeDB, 1, 1)
        self.layout.addWidget(self.kanjiGroup, 2, 0, 1, 2)
        self.layout.addWidget(self.getAll, 3, 0)
        self.layout.addWidget(self.showStats, 3, 1)
        self.layout.addWidget(self.methodCombo, 4, 0)
        self.layout.addWidget(self.authGen, 4, 1)
        #self.layout.addWidget(self.quitApp, 5, 0, 1, 2)
        self.layout.addWidget(self.quitApp, 5, 0)
        self.layout.addWidget(self.showAbout, 5, 1)
        self.layout.addWidget(self.progressBar, 6, 0, 1, 2)
        self.layout.addWidget(self.statusMessage, 7, 0, 1, 2)

        self.setLayout(self.layout)

        self.eFilter = LabelEventFilter()

    def on_start(self):
        """
        Additional procedures run on application start.
        """
        # Let's initialize even some stuff!
        self.al = None
        self.auth_thread = None
        self.init_backend()

        choose_db(str(self.availableDB.currentText()))
        self.showDB.setText("&Change DB (active: %s)" % self.availableDB.currentText())

        self.stats = StatsUI(self.al, self)

    def init_composition(self):
        """
        Window composition and general params.
        """
        self.setWindowTitle(NAME + ' ' + __version__)
        desktop = QApplication.desktop()
        self.setGeometry((desktop.width() - WIDTH)/2,
                        (desktop.height() - HEIGHT)/2, WIDTH, HEIGHT)

    def init_contents(self):
        """
        Setting up qt controls.
        """
        self.changeDB.hide()
        self.availableDB.hide()
        self.availableDB.addItems(dbs.keys())

        self.kanjiGroup.setAlignment(Qt.AlignCenter)
        self.kanjiGroup.setStyleSheet("QGroupBox { border: 1px solid gray; border-radius: 3px; }")

        self.day.setAlignment(Qt.AlignCenter)
        self.week.setAlignment(Qt.AlignCenter)
        self.month.setAlignment(Qt.AlignCenter)
        self.year.setAlignment(Qt.AlignCenter)
        self.dayLabel.setAlignment(Qt.AlignCenter)
        self.weekLabel.setAlignment(Qt.AlignCenter)
        self.monthLabel.setAlignment(Qt.AlignCenter)
        self.yearLabel.setAlignment(Qt.AlignCenter)

        self.day.setFont(QFont(PRETTY_FONT, KANJI_SIZE))
        self.week.setFont(QFont(PRETTY_FONT, KANJI_SIZE))
        self.month.setFont(QFont(PRETTY_FONT, KANJI_SIZE))
        self.year.setFont(QFont(PRETTY_FONT, KANJI_SIZE))

        self.methodCombo.addItems(RandomMess.algs.keys())
        self.methodCombo.setCurrentIndex(1)

        self.statusMessage.setAlignment(Qt.AlignCenter)
        self.statusMessage.hide()
        self.statusMessage.setMaximumHeight(MESSAGE_HEIGHT)
        self.statusMessage.setStyleSheet(WARNING_STYLE)

        self.progressBar.setMaximum(0)
        self.progressBar.setMaximumHeight(PROGRESS_HEIGHT)
        self.progressBar.hide()

        QToolTip.setFont(QFont(PRETTY_FONT, TOOLTIP_FONT_SIZE))

        self.getAll.setToolTip('Randomly select all 4 kanji')
        self.methodCombo.setToolTip('Choose algorithm for randomness')
        self.authGen.setToolTip('Authorize on remote RNG services')
        self.showStats.setToolTip('Show/hide dialog with comprehensive statistics')
        self.quitApp.setToolTip('Close application')
        self.showDB.setToolTip('Show/hide available databases')
        self.availableDB.setToolTip('Available kanji frequency charts db')
        self.changeDB.setToolTip('Pick new kanji from currently selected db')

        # About dialog
        self.aboutBox.layout().itemAt(1).widget().setAlignment(Qt.AlignLeft)

        self.aboutBox.setTextFormat(Qt.RichText)
        self.aboutBox.setText('Version:\t<b>' + __version__ + '</b><br/>Python:\t<b>' + platform.python_version() + '</b>' +
                                '<br/>Platform:\t<b>' + platform.system() + ' ' + platform.release() + '</b>' +
                                '<br/>Author:\t<b>' + __author__ + '</b>' + app_about)
        self.aboutBox.setWindowTitle('About ' + app_name)
        self.aboutBox.setIconPixmap(QPixmap(paths['icon']))

    def init_actions(self):
        """
        Binding events/handlers.
        """
        self.showDB.clicked.connect(self.show_available_db)
        self.changeDB.clicked.connect(self.change_db)

        self.quitApp.clicked.connect(self.close)
        self.getAll.clicked.connect(self.get_all)
        self.authGen.clicked.connect(self.auth_task)
        self.showStats.clicked.connect(self.show_stats)
        self.methodCombo.currentIndexChanged.connect(self.update_alg)

        self.showAbout.clicked.connect(self.app_help)

        # Mouse events for labels
        self.day.setAttribute(Qt.WA_Hover, True)
        self.week.setAttribute(Qt.WA_Hover, True)
        self.month.setAttribute(Qt.WA_Hover, True)
        self.year.setAttribute(Qt.WA_Hover, True)
        self.day.installEventFilter(self.eFilter)
        self.week.installEventFilter(self.eFilter)
        self.month.installEventFilter(self.eFilter)
        self.year.installEventFilter(self.eFilter)

    ##### actions #####

    def show_stats(self):
        if self.stats.isVisible():
            self.stats.hide()
        else:
            self.stats.show()

    def show_available_db(self):
        if self.availableDB.isVisible():
            self.availableDB.hide()
            self.changeDB.hide()
        else:
            self.availableDB.show()
            self.changeDB.show()

    def change_db(self):
        try:
            choose_db(str(self.availableDB.currentText()))
            self.availableDB.hide()
            self.changeDB.hide()
            self.show_message_then_hide("DB successfully remaped!", False)
            self.showDB.setText("&Change DB (active: %s)" % self.availableDB.currentText())

            self.stats.update_stat_info()
            self.stats.refresh_plot()
        except NoDbException as e:
            self.show_message_then_hide(e.message)

    def get_all(self):
        self.random_kanji_task = RandomKanjiTask(self.al)
        self.random_kanji_task.done.connect(self.update_kanji)
        self.show_progress('Selecting kanji...')
        self.random_kanji_task.start()

    def update_kanji(self, results):
        if results['success']:
            kanji_set = results['kanji_set']
            for_a_day = kanji_set.pop()
            for_a_week = kanji_set.pop()
            for_a_month = kanji_set.pop()
            for_a_year = kanji_set.pop()

            self.day.setText(for_a_day.character)
            self.dayLabel.setText('<b>Day:</b> ' + str(for_a_day.frequency) + ' | '
                                        + str(for_a_day.dominance) + '%')
            self.week.setText(for_a_week.character)
            self.weekLabel.setText('<b>Week:</b> ' + str(for_a_week.frequency) + ' | '
                                        + str(for_a_week.dominance) + '%')
            self.month.setText(for_a_month.character)
            self.monthLabel.setText('<b>Month:</b> ' + str(for_a_month.frequency) + ' | '
                                        + str(for_a_month.dominance) + '%')
            self.year.setText(for_a_year.character)
            self.yearLabel.setText('<b>Year:</b> ' + str(for_a_year.frequency) + ' | '
                                        + str(for_a_year.dominance) + '%')

            self.kanji_tooltip(self.day)
            self.kanji_tooltip(self.week)
            self.kanji_tooltip(self.month)
            self.kanji_tooltip(self.year)

            if self.stats.isVisible():
                self.stats.update_stat_info()
                self.stats.refresh_plot()

            self.hide_message()
        else:
            self.show_message_then_hide(results['message'])

        self.hide_progress()

    def pretty_font(self):
        pass

    def update_alg(self):
        self.al.set_active(str(self.methodCombo.currentText()))

    def init_backend(self):
        self.al = RandomMess()
        self.update_alg()

    def auth_task(self):
        self.auth_thread = AuthorizationTask(self.al)
        self.auth_thread.done.connect(self.auth_complete)
        #self.auth_thread.run()
        # IT DOESN't work on windows as it should!
        self.auth_thread.start()
        self.show_progress('Authorizing on RNG services...')

    def auth_complete(self, success):
        self.hide_message()
        self.hide_progress()
        if success:
            self.show_message_then_hide("Successfully authenticated!", False)
        else:
            self.show_message_then_hide("Sorry, could not authenticate.")

    def show_message_then_hide(self, message, error=True):
        if error:
            self.statusMessage.setStyleSheet(WARNING_STYLE)
        else:
            self.statusMessage.setStyleSheet(NOTE_STYLE)

        self.statusMessage.setText(message)
        self.statusMessage.show()
        QTimer.singleShot(MESSAGE_TIMEOUT, self.hide_message)

    def show_progress(self, message):
        self.statusMessage.setStyleSheet(NOTE_STYLE)
        self.statusMessage.setText(message)
        self.statusMessage.show()
        self.progressBar.show()

    def hide_message(self):
        self.statusMessage.setText('')
        self.statusMessage.hide()

    def hide_progress(self):
        self.progressBar.hide()

    def toggle_kanji_info(self, label, info):
        label.setToolTip(info.info())

    def kanji_tooltip(self, label):
        found = JDIC.search(label.text())
        if found:
            label.setToolTip(found.info())
        else:
            label.setToolTip('No such kanji in kanjidic2!')

    def kanji_info(self, kanji):
        pass

    def app_help(self):
        self.aboutBox.show()

        #### Utility events ####

    def resizeEvent(self, QResizeEvent):
        self.updateStatsPosition()
        self.updateStatsSize()

    def moveEvent(self, QMoveEvent):
        self.updateStatsPosition()
        self.updateStatsSize()

    def updateStatsPosition(self):
        self.stats.move(self.x() + self.width() + 20, self.y())

    def updateStatsSize(self):
        self.stats.resize(QSize(self.stats.width(), self.height()))
Exemplo n.º 10
0
class MuWizard(QWizard):

    def __init__(self, R=None, parent=None):
        QWizard.__init__(self, parent)

        self.R = R
        self.data = None

        self.addPage(self.introPage())
        self.addPage(self.loadPage())
        self.addPage(self.modelsPage())
        self.addPage(self.resultsPage())
        self.setWindowTitle('Wizard of muScale')
        self.setPixmap(QWizard.LogoPixmap, QPixmap(RES + ICONS + LOGO))

        self.setStyleSheet('QWizard {' + GRADIENT +'}\
                        QPushButton {\
                            color: #333;\
                            border: 1px solid #555;\
                            border-radius: 11px;\
                            padding: 2px;\
                            background: qradialgradient(cx: 0.3, cy: -0.4,\
                            fx: 0.3, fy: -0.4,\
                            radius: 1.35, stop: 0 #fff, stop: 1 #888);\
                            min-width: 80px;}\
                        QPushButton:hover {\
                            color: #fff;\
                            background: qradialgradient(cx: 0.3, cy: -0.4,\
                            fx: 0.3, fy: -0.4,\
                            radius: 1.35, stop: 0 #fff, stop: 1 #bbb);}\
                        QPushButton:pressed {\
                            color: #800;\
                            background: qradialgradient(cx: 0.4, cy: -0.1,\
                            fx: 0.4, fy: -0.1,\
                            radius: 1.35, stop: 0 #fff, stop: 1 #ddd);}\
                        QPushButton:checked {\
                            background: qradialgradient(cx: 0.4, cy: -0.1,\
                            fx: 0.4, fy: -0.1,\
                            radius: 1.35, stop: 0 #fff, stop: 1 #ddd);}\
                        QComboBox {\
                            color: #333;\
                            border: 1px solid #555;\
                            border-radius: 11px;\
                            padding: 1px 18px 1px 3px;\
                            background: qradialgradient(cx: 0.3, cy: -0.4,\
                            fx: 0.3, fy: -0.4,\
                            radius: 1.35, stop: 0 #fff, stop: 1 #888);\
                            min-width: 20px;}\
                        QComboBox:hover {\
                            color: #fff;\
                            background: qradialgradient(cx: 0.3, cy: -0.4,\
                            fx: 0.3, fy: -0.4,\
                            radius: 1.35, stop: 0 #fff, stop: 1 #bbb);}\
                        QComboBox::down-arrow {\
                             image: url(' + RES + ICONS + ARROW_DOWN + ');}\
                        QComboBox::down-arrow:on {\
                             top: 1px;\
                             left: 1px;}\
                        QComboBox::drop-down {\
                             subcontrol-origin: padding;\
                             subcontrol-position: top right;\
                             width: 15px;\
                             border-left-width: 1px;\
                             border-left-color: darkgray;\
                             border-left-style: solid;\
                             border-top-right-radius: 3px;\
                             border-bottom-right-radius: 3px;}\
                         QToolButton {\
                            color: #333;\
                            border: 1px solid #555;\
                            border-radius: 11px;\
                            padding: 2px;\
                            background: qradialgradient(cx: 0.3, cy: -0.4,\
                            fx: 0.3, fy: -0.4,\
                            radius: 1.35, stop: 0 #fff, stop: 1 #888);\
                            min-width: 20px;}\
                        QToolButton:hover {\
                            color: #fff;\
                            background: qradialgradient(cx: 0.3, cy: -0.4,\
                            fx: 0.3, fy: -0.4,\
                            radius: 1.35, stop: 0 #fff, stop: 1 #bbb);}\
                        QToolButton:pressed {\
                            background: qradialgradient(cx: 0.4, cy: -0.1,\
                            fx: 0.4, fy: -0.1,\
                            radius: 1.35, stop: 0 #fff, stop: 1 #ddd);}\
                        QToolButton:checked {\
                            background: qradialgradient(cx: 0.4, cy: -0.1,\
                            fx: 0.4, fy: -0.1,\
                            radius: 1.35, stop: 0 #fff, stop: 1 #ddd);}')

    def introPage(self):
        intro = QWizardPage()

        intro.setTitle('Hello and welcome')
        label = QLabel('''This is a wizard.
Now you're ready to forecast some time series!
        ''')

        label.setWordWrap(True)
        layout = QVBoxLayout()
        layout.addWidget(label)
        intro.setLayout(layout)

        return intro

    def loadPage(self):
        load = WizardPageEx('loadCheck')

        load.setTitle('Initial data')
        pathLbl = QLabel("<font style='color: gray'>Specify the file with time series to forecast:</font>")
        loadLbl = QLabel("<font style='color: gray'>Click</font>")
        loadLbl.setAlignment(Qt.AlignCenter)

        self.path = QLineEdit()
        self.path.setPlaceholderText('path to file')
        getPath = QToolButton()
        getPath.setText('...')

        self.resultLbl = QLabel()
        self.resultLbl.setAlignment(Qt.AlignCenter)
        self.resultLbl.hide()

        self.preview = QLabel()
        self.preview.setAlignment(Qt.AlignCenter)
        self.preview.setWordWrap(True)
        self.preview.hide()

        self.preview.setAttribute(Qt.WA_Hover)
        self.filter = Filter()
        self.preview.installEventFilter(self.filter)

        getPath.clicked.connect(self.loadData)

        layout = QGridLayout()
        layout.addWidget(pathLbl, 0, 0)
        layout.addWidget(loadLbl, 0, 1)
        layout.addWidget(self.path, 1, 0)
        layout.addWidget(getPath, 1, 1)
        layout.addWidget(self.resultLbl, 2, 0, 1, 2)
        layout.addWidget(self.preview, 3, 0, 1, 2)
        load.setLayout(layout)

        load.previewSeries = SeriesPreview()
        self.previewSeries = load.previewSeries

        # to be able to reference from class namespace
        self.loadCheck = load.check

        return load

    def modelsPage(self):
        models = WizardPageEx('modelCheck')
        models.setTitle('Forecast')

        lbl = QLabel("<font style='color: gray'>Forecast horizon:</font>")
        self.steps = QSpinBox()
        self.steps.setRange(MIN_FORECAST, MAX_FORECAST)
        self.steps.setValue(10)
        self.start = QPushButton('Forecast')
        self.start.clicked.connect(self.modelling)
        self.custom = QPushButton('Advanced')
        self.processing = QLabel()

        self.gifLoading = QMovie(RES + ICONS + PROGRESS, QByteArray(), self)
        self.gifLoading.setCacheMode(QMovie.CacheAll)
        self.gifLoading.setSpeed(100)
        self.processing.setMovie(self.gifLoading)
        self.processing.setAlignment(Qt.AlignCenter)
        self.processing.hide()

        self.status = QLabel()
        self.status.setAlignment(Qt.AlignCenter)
        self.status.hide()

        layout = QGridLayout()
        layout.addWidget(lbl, 0, 0)
        layout.addWidget(self.steps, 0, 1)
        layout.addWidget(self.start, 0, 2)
        layout.addWidget(self.custom, 0, 3)
        layout.addWidget(self.status, 1, 0, 1, 4)
        layout.addWidget(self.processing, 2, 0, 1, 4)
        models.setLayout(layout)

        self.customOpt = CustomOption()
        self.custom.clicked.connect(self.customOpt.show)
        self.modelCheck = models.check

        return models

    def resultsPage(self):
        results = QWizardPage()
        results.setFinalPage(True)
        results.setTitle('Results')

        self.graph = QLabel("<font style='font-size: 16px;'>Plot</font>")
        self.export = QLabel("<font style='font-size: 16px;'>Export</font>")
        self.showData = QLabel("<font style='font-size: 16px;'>Data</font>")
        
        self.plotResult = MplWidget(None)
        self.plotResult.canvas.fig.set_facecolor('white')
        self.resData = QLabel('')
        self.resData.setAlignment(Qt.AlignCenter)
        self.resData.setWordWrap(True)
        self.resData.hide()

        self.resFilter = ResFilter()

        self.resLayout = QVBoxLayout()
        self.resLayout.addWidget(self.export)
        self.resLayout.addWidget(self.graph)
        self.resLayout.addWidget(self.showData)
        self.resLayout.addWidget(self.plotResult)
        self.resLayout.addWidget(self.resData)

        self.plotResult.hide()

        for index in range(0, self.resLayout.count()):
            try:
                self.resLayout.itemAt(index).widget().setAlignment(Qt.AlignCenter)
                self.resLayout.itemAt(index).widget().setStyleSheet('QLabel { color: gray; }')
                self.resLayout.itemAt(index).widget().setAttribute(Qt.WA_Hover)
                self.resLayout.itemAt(index).widget().installEventFilter(self.resFilter)
            except Exception:
                pass

        self.resLayout.setAlignment(Qt.AlignCenter)
        self.resLayout.setSpacing(60)

        results.setLayout(self.resLayout)

        return results

    #---- actions ----#
    def loadData(self):
        fileName = unicode(QFileDialog.getOpenFileName(self, 'Open text file', RES))
        if fileName:
            self.resultLbl.hide()
            self.preview.hide()
            if DataParser.istextfile(fileName):
                self.data = DataParser.getTimeSeriesFromTextData(data=open(fileName, 'r').read())
                if len(self.data[0]) > DATA_LOW_LIMIT:
                    self.resultLbl.setText("<font style='color: gray'>Success! Loaded<b> " + str(len(self.data[0])) +
                                           '</b> values, errors: <b>' + str(
                                            self.data[1]) + '</b></font>')
                    self.resultLbl.show()
                    self.path.setText(fileName)

                    previewLength = 40
                    self.preview.setText("<font style='color: gray'><b>Preview:</b> "+ ' '.join(
                                        [str(e) for e in self.data[0][:previewLength]]) +
                                        "...</font>")
                    self.previewSeries.updateData(self.data)
                    self.preview.show()
                    self.loadCheck.setChecked(True)
                else:
                    self.resultLbl.setText("<font style='color: gray'>Not enough values to form data series.</font>")
                    self.resultLbl.show()
            else:
                self.resultLbl.setText("<font style='color: gray'>Specified file is binary file!</font>")
                self.resultLbl.show()

    def modelling(self):
        self.processing.show()
        self.gifLoading.start()
        self.status.setText('')

        statusText = u"<font style='color: gray'>"

        # decomposition #
        if self.customOpt.options['enable']:
            self.signalEx = self.customOpt.options['signal']
            self.wavelet = pywt.Wavelet(self.customOpt.options['wavelet'])
            wLevel = self.customOpt.options['lvls'] - 1
            maxLevel = pywt.dwt_max_level(len(self.data[0]), self.wavelet)

            if wLevel > maxLevel:
                wLevel = maxLevel

            self.wInitialCoefficients = pywt.wavedec(self.data[0], self.wavelet,
                                                       level=wLevel, mode=self.signalEx)
            self.wCoefficients = self.wInitialCoefficients
        else:
            self.signalEx = pywt.MODES.sp1
            selected = select_wavelet(self.data[0], self.R)
            index = max(selected)
            self.wavelet = pywt.Wavelet(selected[index][1])

            wLevel = calculate_suitable_lvl(self.data[0],
                                         self.wavelet, self.R, swt=False)
            self.wInitialCoefficients = pywt.wavedec(self.data[0], self.wavelet,
                                                     level=wLevel, mode=self.signalEx)
            self.wCoefficients = self.wInitialCoefficients

        statusText += 'Wavelet: <b>' + self.wavelet.family_name + \
                      '</b> (' + self.wavelet.name + ', ' + self.wavelet.symmetry + ', orthogonal: ' + \
                      str(self.wavelet.orthogonal) + ')<br/>'

        statusText += 'Discrete Wavelet Transfom: <b>' + str(wLevel + 1) + ' levels</b><br/>'

        # models #
        options = {}
        options['multi'] = True
        options['fractal'] = False
        options['ljung'] = False
        self.models = auto_model(self.wCoefficients, self.R, options, self.data[0])

        statusText += '<br/>Selected models:<br/>'
        for lvl, model in self.models.iteritems():
            statusText += str(lvl) + '. <b>' + model.enumname.replace('_', ' ') + '</b><br/>'

        # forecasting #
        try:
            frequency = self.customOpt.options['frequency']
        except Exception:
            frequency = 8
        aic = False
        options['hw_gamma'] = True
        options['hw_model'] = 'additive'
        options['hw_period'] = frequency
        options['ar_aic'] = aic
        options['ar_method'] = 'burg'
        options['ar_order'] = 50
        options['arima_auto'] = False
        options['arima_nons'] = True
        options['arima_nons_order'] = [6, 0, 9]
        options['arima_seas'] = True
        options['arima_seas_order'] = [9, 0, 1]
        options['lsf_aic'] = aic
        options['lsf_order'] = 30
        options['ets_auto'] = aic
        options['ets_period'] = frequency
        options['sts_type'] = 'trend'
        options['append_fit'] = True

        self.multi_model_thread = MultiModelThread(self.models,
                                           self.wCoefficients,
                                           self.R,
                                           self.steps.value(),
                                           options,)
        self.multi_model_thread.done.connect(self.multiForecastFinished)
        self.multi_model_thread.start()

        statusText += '<br/>Forecasting...'

        self.status.setText(statusText)
        self.status.show()

    def multiForecastFinished(self, results):
        self.forecast = results
        self.gifLoading.stop()
        self.processing.hide()

        self.status.setText('<br/>'.join(str(self.status.text()).split('<br/>')[:-1]) +
                            '<br/>Forecast complete.')
        self.modelCheck.setChecked(True)

    #---- results -----#
    def togglePlot(self):
        if self.plotResult.isVisible():
            self.plotResult.hide()
            self.export.show()
            self.showData.show()
            self.resLayout.setSpacing(60)
        else:
            self.updateGraph()
            self.plotResult.show()
            self.export.hide()
            self.showData.hide()
            self.resLayout.setSpacing(5)

    def toggleData(self):
        if self.resData.isVisible():
            self.export.show()
            self.graph.show()
            self.showData.show()
            self.resData.hide()
            self.resLayout.setSpacing(60)
            self.adjustSize()
        else:
            self.plotResult.hide()
            self.graph.hide()
            self.export.hide()
            self.showData.show()
            self.resData.show()
            self.resLayout.setSpacing(5)

            res = self.inverseWT()
            max = len(self.data[0]) - 1
            resText = '<table border="0" align="center" style="border-style: groove;">'
            resText += '<tr><td align="center"><i>Initial</i></td><td align="center"><i>Forecast</i></td></tr>'
            resText += '<tr><td align="center">...</td><td></td></tr>'
            table = zip(self.data[0][max-10:max], res[max-10:max])
            for i, j in table:
                resText += '<tr>'
                resText += '<td align="center">' + str(i) + '</td>'
                resText += '<td align="center">' + str(j) + '</td>'
                resText += '</tr>'

            for e in res[max+1:max+10]:
                resText += '<tr>'
                resText += '<td align="center"></td>'
                resText += '<td align="center">' + str(e) + '</td>'
                resText += '</tr>'

            resText += '<tr><td align="center"></td><td align="center">...</td></tr>'
            resText += '</table>'

            self.resData.setText(resText)
            self.adjustSize()

    def inverseWT(self):
        return pywt.waverec(update_dwt([e [1] for e in self.forecast], self.wavelet, self.signalEx),
                                            self.wavelet, mode=self.signalEx)

    def updateGraph(self):
        self.plotResult.updatePlot(self.inverseWT(), label='Simulation', color='r')
        self.plotResult.updatePlot(self.data[0], label='Time series', color='b')

    def exportToXls(self):
        # opening file dialog
        fileName = QFileDialog.getSaveFileName(self,
            'Save as', RES, 'Microsoft Excel Spreadsheet (*.xls)')

        if fileName.count() > 0:
            try:
                COLUMN_WIDTH = 3000

                alignment = Alignment()
                alignment.horizontal = Alignment.HORZ_CENTER
                alignment.vertical = Alignment.VERT_CENTER

                borders = Borders()
                borders.left = Borders.THIN
                borders.right = Borders.THIN
                borders.top = Borders.THIN
                borders.bottom = Borders.THIN

                style = XFStyle()
                style.alignment = alignment
                style.borders = borders

                font = Font()
                font.bold = True
                headerStyle = XFStyle()
                headerStyle.font = font

                separate = Borders()
                separate.left = Borders.THIN
                separate.right = Borders.DOUBLE
                separate.top = Borders.THIN
                separate.bottom = Borders.THIN
                separateStyle = XFStyle()
                separateStyle.borders = separate

                book = Workbook(encoding='utf-8')

                # modelling data
                dec_sheet = book.add_sheet('Data decomposition')

                # decomposition data
                # initial data
                column = 0
                row = 0
                dec_sheet.write(row, column, 'Time series', headerStyle)
                dec_sheet.col(column).width = COLUMN_WIDTH
                row += 1
                for item in self.data[0]:
                    dec_sheet.write(row, column, item, separateStyle)
                    row += 1

                # decomposition
                for lvl in self.wCoefficients:
                    row = 0
                    column += 1
                    dec_sheet.write(row, column, 'Level' + str(column - 1), headerStyle)
                    dec_sheet.col(column).width = COLUMN_WIDTH
                    row += 1
                    for item in lvl:
                        dec_sheet.write(row, column, item, style)
                        row += 1

                # decomposition graphs
                pass

                levels_sheet = book.add_sheet('Multiscale forecast')

                # levels data
                column = 0
                for lvl in self.forecast:
                    row = 0
                    levels_sheet.write(row, column, 'Level' + str(column), headerStyle)
                    levels_sheet.col(column).width = COLUMN_WIDTH
                    row += 1
                    for item in lvl[1]:
                        levels_sheet.write(row, column, float(item), style)
                        row += 1
                    column += 1

                result_sheet = book.add_sheet('Results')

                # initial
                column = 0
                row = 0
                result_sheet.write(row, column, 'Initial data', headerStyle)
                result_sheet.col(column).width = COLUMN_WIDTH
                row += 1
                for item in self.data[0]:
                    result_sheet.write(row, column, item, separateStyle)
                    row += 1

                # forecast
                row = 0
                column += 1
                result_sheet.write(row, column, 'Forecast', headerStyle)
                result_sheet.col(column).width = COLUMN_WIDTH
                row += 1
                for item in self.inverseWT():
                    result_sheet.write(row, column, item, style)
                    row += 1

                row = 0
                column = 2
                self.updateGraph()
                self.plotResult.saveFigure('forecast', format='bmp')

                result_sheet.insert_bitmap(RES + TEMP + 'forecast.bmp', row, column)

                # saving xls
                try:
                    book.save(unicode(fileName))
                except Exception:
                    pass

            except Exception, e:
                pass
Exemplo n.º 11
0
class PreView(QGraphicsView):
    def __init__(self):
        QGraphicsView.__init__(self)    
        
        self.zoom = 2
        self.scale(self.zoom, self.zoom) 
        self.lastSize = 0
        
        self.setDragMode(QGraphicsView.ScrollHandDrag)
#        self.setHorizontalScrollBarPolicy(Qt.ScrollBarAlwaysOff)
#        self.setVerticalScrollBarPolicy(Qt.ScrollBarAlwaysOff)
        self.installEventFilter(self)
                
        self.hudLayout = QVBoxLayout(self)
        self.hudLayout.setContentsMargins(0,0,0,0)
        
        self.ellipseLabel =  QLabel()
        self.ellipseLabel.setMinimumWidth(self.width())
        self.hudLayout.addWidget(self.ellipseLabel)
        self.ellipseLabel.setAttribute(Qt.WA_TransparentForMouseEvents, True)  

        
    def setPreviewImage(self, previewImage):
        self.grscene = QGraphicsScene()
        pixmapImage = QPixmap(previewImage)
        self.grscene.addPixmap(pixmapImage)
        self.setScene(self.grscene)
        

    def eventFilter(self, obj, event):
        if(event.type()==QEvent.Resize):
            self.ellipseLabel.setMinimumWidth(self.width())
            self.updateFilledCircle(self.lastSize)
        return False
    
    def sizeHint(self):
        return QSize(200, 200)


    def setFilledBrsuh(self, size):
        self.updateFilledCircle(size)
        
    def updateCircle(self, s):
        size = s * self.zoom
        pixmap = QPixmap(self.width(), self.height())
        pixmap.fill(Qt.transparent)
        #painter ellipse 1
        painter = QPainter()
        painter.begin(pixmap)
        painter.setRenderHint(QPainter.Antialiasing)
        pen = QPen(Qt.red)
        pen.setWidth(3)
        painter.setPen(pen)
        brush = QBrush(Qt.green)
        painter.setBrush(brush)
        painter.drawEllipse(QRect(self.width()/2 - size/2, self.height()/2 - size/2, size, size))
        painter.end()
        #painter ellipse 2
        painter2 = QPainter()
        painter2.begin(pixmap)
        painter2.setRenderHint(QPainter.Antialiasing)
        pen2 = QPen(Qt.green)
        pen2.setStyle(Qt.DotLine)
        pen2.setWidth(3)
        painter2.setPen(pen2)
        painter2.drawEllipse(QRect(self.width()/2 - size/2, self.height()/2 - size/2, size, size))
        painter2.end()
        
        self.ellipseLabel.setPixmap(QPixmap(pixmap))
        self.lastSize = s
        
    def updateFilledCircle(self, s):
        size = s * self.zoom
        pixmap = QPixmap(self.width(), self.height())
        pixmap.fill(Qt.transparent)
        #painter filled ellipse
        p = QPalette()
        painter = QPainter()
        painter.begin(pixmap)
        painter.setRenderHint(QPainter.Antialiasing)
        brush = QBrush(p.link().color())
        painter.setBrush(brush)
        painter.setOpacity(0.4)
        painter.drawEllipse(QRect(self.width()/2 - size/2, self.height()/2 - size/2, size, size))
        painter.end()
        #painter ellipse 2
        painter2 = QPainter()
        painter2.begin(pixmap)
        painter2.setRenderHint(QPainter.Antialiasing)
        pen2 = QPen(Qt.green)
        pen2.setWidth(1)
        painter2.setPen(pen2)
        painter2.drawEllipse(QRect(self.width()/2 - size/2, self.height()/2 - size/2, size, size))
        painter2.end()
        
        self.ellipseLabel.setPixmap(QPixmap(pixmap))
        self.lastSize = s
Exemplo n.º 12
0
class GUI(QWidget):
    def __init__(self, parent=None):
        super(GUI, self).__init__(parent)

        self.create_ui_components()
        self.compose_ui()

        # Initializing: window composition, it's contents and event handlers
        self.init_composition()
        self.init_contents()
        self.init_actions()

        self.on_start()

    def create_ui_components(self):
        """
        Create layouts and qt controls.
        """
        self.layout = QGridLayout()

        self.kanjiGroup = QGroupBox()
        self.kanjiLayout = QGridLayout()

        # Kanji ui group
        self.day, self.week, self.month, self.year = \
        QLabel(KANJI), QLabel(KANJI), QLabel(KANJI), QLabel(KANJI)

        self.dayLabel, self.weekLabel, self.monthLabel, self.yearLabel = \
        QLabel('<b>Day</b>'), QLabel('<b>Week</b>'), \
        QLabel('<b>Month</b>'), QLabel('<b>Year</b>')

        # Main layout
        self.showAbout = QPushButton('A&bout')
        # DB controls (top)
        self.showDB, self.availableDB, self.changeDB = \
        QPushButton('&Change DB (active:)'), QComboBox(), QPushButton('&Remap')
        # General controls (bottom)
        self.getAll, self.showStats, self.quitApp, self.authGen, self.methodCombo = \
        QPushButton('&Get all'), QPushButton('&Stats'), QPushButton('&Quit'), \
        QPushButton('&Auth'), QComboBox()
        # Notifications
        self.progressBar = QProgressBar()
        self.statusMessage = QLabel()
        # About
        self.aboutBox = QMessageBox()

    def compose_ui(self):
        """
        Fill layouts and groups, initialize filters.
        """
        self.kanjiLayout.addWidget(self.day, 0, 0)
        self.kanjiLayout.addWidget(self.week, 0, 1)
        self.kanjiLayout.addWidget(self.dayLabel, 1, 0)
        self.kanjiLayout.addWidget(self.weekLabel, 1, 1)

        self.kanjiLayout.addWidget(self.month, 2, 0)
        self.kanjiLayout.addWidget(self.year, 2, 1)
        self.kanjiLayout.addWidget(self.monthLabel, 3, 0)
        self.kanjiLayout.addWidget(self.yearLabel, 3, 1)

        self.kanjiGroup.setLayout(self.kanjiLayout)

        self.layout.addWidget(self.showDB, 0, 0, 1, 2)
        self.layout.addWidget(self.availableDB, 1, 0)
        self.layout.addWidget(self.changeDB, 1, 1)
        self.layout.addWidget(self.kanjiGroup, 2, 0, 1, 2)
        self.layout.addWidget(self.getAll, 3, 0)
        self.layout.addWidget(self.showStats, 3, 1)
        self.layout.addWidget(self.methodCombo, 4, 0)
        self.layout.addWidget(self.authGen, 4, 1)
        #self.layout.addWidget(self.quitApp, 5, 0, 1, 2)
        self.layout.addWidget(self.quitApp, 5, 0)
        self.layout.addWidget(self.showAbout, 5, 1)
        self.layout.addWidget(self.progressBar, 6, 0, 1, 2)
        self.layout.addWidget(self.statusMessage, 7, 0, 1, 2)

        self.setLayout(self.layout)

        self.eFilter = LabelEventFilter()

    def on_start(self):
        """
        Additional procedures run on application start.
        """
        # Let's initialize even some stuff!
        self.al = None
        self.auth_thread = None
        self.init_backend()

        choose_db(str(self.availableDB.currentText()))
        self.showDB.setText("&Change DB (active: %s)" %
                            self.availableDB.currentText())

        self.stats = StatsUI(self.al, self)

    def init_composition(self):
        """
        Window composition and general params.
        """
        self.setWindowTitle(NAME + ' ' + __version__)
        desktop = QApplication.desktop()
        self.setGeometry((desktop.width() - WIDTH) / 2,
                         (desktop.height() - HEIGHT) / 2, WIDTH, HEIGHT)

    def init_contents(self):
        """
        Setting up qt controls.
        """
        self.changeDB.hide()
        self.availableDB.hide()
        self.availableDB.addItems(dbs.keys())

        self.kanjiGroup.setAlignment(Qt.AlignCenter)
        self.kanjiGroup.setStyleSheet(
            "QGroupBox { border: 1px solid gray; border-radius: 3px; }")

        self.day.setAlignment(Qt.AlignCenter)
        self.week.setAlignment(Qt.AlignCenter)
        self.month.setAlignment(Qt.AlignCenter)
        self.year.setAlignment(Qt.AlignCenter)
        self.dayLabel.setAlignment(Qt.AlignCenter)
        self.weekLabel.setAlignment(Qt.AlignCenter)
        self.monthLabel.setAlignment(Qt.AlignCenter)
        self.yearLabel.setAlignment(Qt.AlignCenter)

        self.day.setFont(QFont(PRETTY_FONT, KANJI_SIZE))
        self.week.setFont(QFont(PRETTY_FONT, KANJI_SIZE))
        self.month.setFont(QFont(PRETTY_FONT, KANJI_SIZE))
        self.year.setFont(QFont(PRETTY_FONT, KANJI_SIZE))

        self.methodCombo.addItems(RandomMess.algs.keys())
        self.methodCombo.setCurrentIndex(1)

        self.statusMessage.setAlignment(Qt.AlignCenter)
        self.statusMessage.hide()
        self.statusMessage.setMaximumHeight(MESSAGE_HEIGHT)
        self.statusMessage.setStyleSheet(WARNING_STYLE)

        self.progressBar.setMaximum(0)
        self.progressBar.setMaximumHeight(PROGRESS_HEIGHT)
        self.progressBar.hide()

        QToolTip.setFont(QFont(PRETTY_FONT, TOOLTIP_FONT_SIZE))

        self.getAll.setToolTip('Randomly select all 4 kanji')
        self.methodCombo.setToolTip('Choose algorithm for randomness')
        self.authGen.setToolTip('Authorize on remote RNG services')
        self.showStats.setToolTip(
            'Show/hide dialog with comprehensive statistics')
        self.quitApp.setToolTip('Close application')
        self.showDB.setToolTip('Show/hide available databases')
        self.availableDB.setToolTip('Available kanji frequency charts db')
        self.changeDB.setToolTip('Pick new kanji from currently selected db')

        # About dialog
        self.aboutBox.layout().itemAt(1).widget().setAlignment(Qt.AlignLeft)

        self.aboutBox.setTextFormat(Qt.RichText)
        self.aboutBox.setText('Version:\t<b>' + __version__ +
                              '</b><br/>Python:\t<b>' +
                              platform.python_version() + '</b>' +
                              '<br/>Platform:\t<b>' + platform.system() + ' ' +
                              platform.release() + '</b>' +
                              '<br/>Author:\t<b>' + __author__ + '</b>' +
                              app_about)
        self.aboutBox.setWindowTitle('About ' + app_name)
        self.aboutBox.setIconPixmap(QPixmap(paths['icon']))

    def init_actions(self):
        """
        Binding events/handlers.
        """
        self.showDB.clicked.connect(self.show_available_db)
        self.changeDB.clicked.connect(self.change_db)

        self.quitApp.clicked.connect(self.close)
        self.getAll.clicked.connect(self.get_all)
        self.authGen.clicked.connect(self.auth_task)
        self.showStats.clicked.connect(self.show_stats)
        self.methodCombo.currentIndexChanged.connect(self.update_alg)

        self.showAbout.clicked.connect(self.app_help)

        # Mouse events for labels
        self.day.setAttribute(Qt.WA_Hover, True)
        self.week.setAttribute(Qt.WA_Hover, True)
        self.month.setAttribute(Qt.WA_Hover, True)
        self.year.setAttribute(Qt.WA_Hover, True)
        self.day.installEventFilter(self.eFilter)
        self.week.installEventFilter(self.eFilter)
        self.month.installEventFilter(self.eFilter)
        self.year.installEventFilter(self.eFilter)

    ##### actions #####

    def show_stats(self):
        if self.stats.isVisible():
            self.stats.hide()
        else:
            self.stats.show()

    def show_available_db(self):
        if self.availableDB.isVisible():
            self.availableDB.hide()
            self.changeDB.hide()
        else:
            self.availableDB.show()
            self.changeDB.show()

    def change_db(self):
        try:
            choose_db(str(self.availableDB.currentText()))
            self.availableDB.hide()
            self.changeDB.hide()
            self.show_message_then_hide("DB successfully remaped!", False)
            self.showDB.setText("&Change DB (active: %s)" %
                                self.availableDB.currentText())

            self.stats.update_stat_info()
            self.stats.refresh_plot()
        except NoDbException as e:
            self.show_message_then_hide(e.message)

    def get_all(self):
        self.random_kanji_task = RandomKanjiTask(self.al)
        self.random_kanji_task.done.connect(self.update_kanji)
        self.show_progress('Selecting kanji...')
        self.random_kanji_task.start()

    def update_kanji(self, results):
        if results['success']:
            kanji_set = results['kanji_set']
            for_a_day = kanji_set.pop()
            for_a_week = kanji_set.pop()
            for_a_month = kanji_set.pop()
            for_a_year = kanji_set.pop()

            self.day.setText(for_a_day.character)
            self.dayLabel.setText('<b>Day:</b> ' + str(for_a_day.frequency) +
                                  ' | ' + str(for_a_day.dominance) + '%')
            self.week.setText(for_a_week.character)
            self.weekLabel.setText('<b>Week:</b> ' +
                                   str(for_a_week.frequency) + ' | ' +
                                   str(for_a_week.dominance) + '%')
            self.month.setText(for_a_month.character)
            self.monthLabel.setText('<b>Month:</b> ' +
                                    str(for_a_month.frequency) + ' | ' +
                                    str(for_a_month.dominance) + '%')
            self.year.setText(for_a_year.character)
            self.yearLabel.setText('<b>Year:</b> ' +
                                   str(for_a_year.frequency) + ' | ' +
                                   str(for_a_year.dominance) + '%')

            self.kanji_tooltip(self.day)
            self.kanji_tooltip(self.week)
            self.kanji_tooltip(self.month)
            self.kanji_tooltip(self.year)

            if self.stats.isVisible():
                self.stats.update_stat_info()
                self.stats.refresh_plot()

            self.hide_message()
        else:
            self.show_message_then_hide(results['message'])

        self.hide_progress()

    def pretty_font(self):
        pass

    def update_alg(self):
        self.al.set_active(str(self.methodCombo.currentText()))

    def init_backend(self):
        self.al = RandomMess()
        self.update_alg()

    def auth_task(self):
        self.auth_thread = AuthorizationTask(self.al)
        self.auth_thread.done.connect(self.auth_complete)
        #self.auth_thread.run()
        # IT DOESN't work on windows as it should!
        self.auth_thread.start()
        self.show_progress('Authorizing on RNG services...')

    def auth_complete(self, success):
        self.hide_message()
        self.hide_progress()
        if success:
            self.show_message_then_hide("Successfully authenticated!", False)
        else:
            self.show_message_then_hide("Sorry, could not authenticate.")

    def show_message_then_hide(self, message, error=True):
        if error:
            self.statusMessage.setStyleSheet(WARNING_STYLE)
        else:
            self.statusMessage.setStyleSheet(NOTE_STYLE)

        self.statusMessage.setText(message)
        self.statusMessage.show()
        QTimer.singleShot(MESSAGE_TIMEOUT, self.hide_message)

    def show_progress(self, message):
        self.statusMessage.setStyleSheet(NOTE_STYLE)
        self.statusMessage.setText(message)
        self.statusMessage.show()
        self.progressBar.show()

    def hide_message(self):
        self.statusMessage.setText('')
        self.statusMessage.hide()

    def hide_progress(self):
        self.progressBar.hide()

    def toggle_kanji_info(self, label, info):
        label.setToolTip(info.info())

    def kanji_tooltip(self, label):
        found = JDIC.search(label.text())
        if found:
            label.setToolTip(found.info())
        else:
            label.setToolTip('No such kanji in kanjidic2!')

    def kanji_info(self, kanji):
        pass

    def app_help(self):
        self.aboutBox.show()

        #### Utility events ####

    def resizeEvent(self, QResizeEvent):
        self.updateStatsPosition()
        self.updateStatsSize()

    def moveEvent(self, QMoveEvent):
        self.updateStatsPosition()
        self.updateStatsSize()

    def updateStatsPosition(self):
        self.stats.move(self.x() + self.width() + 20, self.y())

    def updateStatsSize(self):
        self.stats.resize(QSize(self.stats.width(), self.height()))
Exemplo n.º 13
0
class _TransferWidget(QFrame):
    cancel = pyqtSignal()
    cancelBeforeTransfer = pyqtSignal(int) # transfer ID
    retry = pyqtSignal(object, object, int) # filesOrData, peerID, transfer ID
    
    def __init__(self, parent, logger, filesOrData, name, targetDir, numFiles, totalSize, peerID, transferID, down):
        super(_TransferWidget, self).__init__(parent)
        
        self.logger = logger
        self._filesOrData = filesOrData
        self._targetDir = targetDir
        self._numFiles = numFiles
        self._totalSize = totalSize
        self._targetFile = None
        self._peerID = peerID
        self._transferID = transferID
        self._transferring = True
        self._down = down
        self._success = False
        self._connectedToThread = False
        self._currentFile = None
        
        self._initLayout()
        
        if type(filesOrData) is list and len(filesOrData) is 1:
            self._setCurrentFile(filesOrData[0])
        elif name:
            f = NamedTemporaryFile(suffix=name, delete=True)
            f.flush()
            self._setCurrentFile(f.name, name)
            f.close()
        else:
            self._setCurrentFile(None)
        self.reset()
        
    def _initLayout(self):
        layout = QVBoxLayout(self)
        layout.setContentsMargins(5, 5, 5, 5)
        layout.setSpacing(0)
        
        nameLayout = QHBoxLayout()
        nameLayout.setContentsMargins(0, 0, 0, 0)
        
        self._fileIconLabel = QLabel(self)
        nameLayout.addWidget(self._fileIconLabel, 0, Qt.AlignLeft)
        
        self._nameLabel = QLabel(self)
        nameLayout.addSpacing(5)
        nameLayout.addWidget(self._nameLabel, 1, Qt.AlignLeft)
        
        layout.addLayout(nameLayout)
        
        progressWidget = QWidget(self)
        progressLayout = QHBoxLayout(progressWidget)
        progressLayout.setSpacing(5)
        progressLayout.setContentsMargins(0, 0, 0, 0)
        
        iconLabel = QLabel(progressWidget)
        if self._down:
            picFile = get_settings().get_resource("images", "down.png")
        else:
            picFile = get_settings().get_resource("images", "up.png")
        iconLabel.setPixmap(QPixmap(picFile))
        iconLabel.setFixedSize(15,15)
        progressLayout.addWidget(iconLabel, 0, Qt.AlignBottom)
        
        self._progress = QProgressBar(progressWidget)
        self._progress.setMinimum(0)
        self._progress.setMaximum(100)
        if getPlatform() == PLATFORM_MAC:
            self._progress.setAttribute(Qt.WA_MacMiniSize)
            self._progress.setMaximumHeight(16)
        progressLayout.addWidget(self._progress, 1)
        
        self._button = QPushButton(progressWidget)
        self._button.clicked.connect(self._buttonClicked)
        progressLayout.addSpacing(5)
        progressLayout.addWidget(self._button, 0, Qt.AlignCenter)
        
        layout.addWidget(progressWidget, 0, Qt.AlignBottom)
        
        self._statusLabel = QLabel(self)
        if getPlatform() == PLATFORM_MAC:
            self._statusLabel.setAttribute(Qt.WA_MacSmallSize)
        layout.addWidget(self._statusLabel)
        
        self.setObjectName(u"__transfer_widget")
        self.setFrameShape(QFrame.StyledPanel)
        self.setStyleSheet("QFrame#__transfer_widget{border-width: 1px; border-top-style: none; border-right-style: none; border-bottom-style: solid; border-left-style: none; border-color:palette(mid)}");
            
        self.setSizePolicy(QSizePolicy.MinimumExpanding, QSizePolicy.Fixed)
        
    def reset(self):
        self._transferring = True
        self._statusLabel.setText(u"Waiting for data..." if self._down else u"Waiting for peer...")
        self._checkButtonFunction()
        self._progress.setMaximum(0)
        
    def isFinished(self):
        return not self._transferring
    
    def isSuccessful(self):
        return self._success
    
    def getFilePath(self):
        if self._numFiles is 1:
            return self._currentFile
        
    def _setFileIcon(self, curPath):
        if os.path.exists(curPath):
            fileInfo = QFileInfo(curPath)
            iconProvider = QFileIconProvider()
            icon = iconProvider.icon(fileInfo)
            self._fileIconLabel.setPixmap(icon.pixmap(16,16))
        
    def _setCurrentFile(self, path, dispName=None):
        if get_peers() is not None:
            peerName = get_peers().getDisplayedPeerName(self._peerID)
        else:
            peerName = u"<unknown peer>"
            
        if not path:
            if self._down:
                text = u"%d %s (total %s) \u2190 %s"
            else:
                text = u"%d %s (total %s) \u2192 %s"
            text = text % (self._numFiles, u"file" if self._numFiles is 1 else "files", formatSize(self._totalSize), peerName)
        else:
            if self._down:
                text = u"%s (%stotal %s) \u2190 %s"
            else:
                text = u"%s (%stotal %s) \u2192 %s"
            if dispName is None:
                dispName = os.path.basename(path)
            
            numFilesS = u"" if self._numFiles is 1 else u"%d files, " % self._numFiles
            text = text % (dispName, numFilesS, formatSize(self._totalSize), peerName)
            self._setFileIcon(path)
            
        self._currentFile = path
        self._nameLabel.setText(text)
        
    def _setIcon(self, baseName):
        if baseName is None:
            self._button.setStyleSheet("""
                QPushButton {min-width: 15px;
                             max-width: 15px;
                             min-height: 15px;
                             max-height: 15px;
                             margin: 0px;
                             padding: 0px;
                             border:none;
                }
            """)
        else:
            defPath = get_settings().get_resource("images", "%s32.png" % baseName)
            pressPath = get_settings().get_resource("images", "%s32p.png" % baseName)
            self._button.setStyleSheet("""
                QPushButton {min-width: 15px;
                             max-width: 15px;
                             min-height: 15px;
                             max-height: 15px;
                             margin: 0px;
                             padding: 0px;
                             border:none;
                             border-image: url(%s);
                }
                QPushButton:pressed {
                             border-image: url(%s);
                }
            """ % (defPath, pressPath)
            )
        
    def _checkButtonFunction(self):
        if self._transferring:
            self._setIcon("cancel")
        elif self._down:
            if self._success:
                self._setIcon("reveal")
            else:
                self._setIcon(None)
        else:
            if self._success:
                self._setIcon("reveal")
            else:
                self._setIcon("retry")
    
    def _reveal(self):
        filePath = self.getFilePath()
        if filePath:
            revealFile(filePath, self.logger)
        elif self._down:
            openFile(self._targetDir, self.logger)
        elif self._currentFile and os.path.exists(self._currentFile):
            revealFile(self._currentFile, self.logger)
    
    def _buttonClicked(self):
        if self._transferring:
            if self._connectedToThread:
                self.cancel.emit()
            else:
                self.cancelBeforeTransfer.emit(self._transferID)
        elif self._down:
            if self._success:
                self._reveal()
        else:
            if self._success:
                self._reveal()
            else:
                self.retry.emit(self._filesOrData, self._peerID, self._transferID)
                
    @loggingSlot(object, int)
    def nextFile(self, nameOrPath, _size):
        self._setCurrentFile(nameOrPath)
        
    def connectDataThread(self, dataThread):
        if not dataThread.isRunning():
            self.transferError(dataThread, u"Transfer didn't start.")
            return
        self._connectedToThread = True
        dataThread.progressChanged.connect(self.progressChanged)
        dataThread.errorOnTransfer.connect(self.transferError)
        dataThread.successfullyTransferred.connect(self.successfullyTransferred)
        dataThread.transferCanceled.connect(self.transferCanceled)
        dataThread.nextFile.connect(self.nextFile)
        self.cancel.connect(dataThread.cancelTransfer)

    def disconnectDataThread(self, dataThread):
        if self._connectedToThread:
            self._connectedToThread = False   
            dataThread.progressChanged.disconnect(self.progressChanged)
            dataThread.errorOnTransfer.disconnect(self.transferError)
            dataThread.successfullyTransferred.disconnect(self.successfullyTransferred)
            dataThread.transferCanceled.disconnect(self.transferCanceled)
            dataThread.nextFile.disconnect(self.nextFile)
            self.cancel.disconnect(dataThread.cancelTransfer)
    
    @loggingSlot(int, int)
    def progressChanged(self, newVal, maxVal):
        if newVal is 0:
            self._transferring = True
            self._progress.setMaximum(maxVal)
            self._statusLabel.setText(u"Receiving data" if self._down else u"Sending data")
        self._progress.setValue(newVal)
    
    @pyqtSlot(QThread)
    @loggingSlot(QThread, object)
    def successfullyTransferred(self, thread, _path=None):
        self._transferring = False
        self._success = True
        self._statusLabel.setText(u"Transfer finished successfully")
        self.disconnectDataThread(thread)
        self._checkButtonFunction()
    
    @loggingSlot(QThread, object)
    def transferError(self, thread, message=None):
        if not self._transferring:
            return
        self._transferring = False
        self._statusLabel.setText(u"Error transferring file (%s)" % message)
        self.disconnectDataThread(thread)
        self._checkButtonFunction()
        if self._progress.maximum() == 0:
            self._progress.setMaximum(100)
    
    @loggingSlot(QThread)
    def transferCanceled(self, thread):
        self._transferring = False
        self._statusLabel.setText(u"Transfer canceled")
        self.disconnectDataThread(thread)
        self._checkButtonFunction()
        
    def canceledBeforeTransfer(self, isTimeout):
        self._progress.setMaximum(100)
        self._transferring = False
        if isTimeout:
            self._statusLabel.setText(u"Transfer timed out")
        else:
            self._statusLabel.setText(u"Transfer canceled")
        self._checkButtonFunction()
Exemplo n.º 14
0
class ThumbnailWidget(QFrame):

    def __init__(self, parent, svg_data="", text=""):
        QFrame.__init__(self, parent)

        self.setFrameStyle(QFrame.StyledPanel)

        self.label = QLabel(text, self)
        self.label.setWordWrap(True)

        self.label.setSizePolicy(QSizePolicy.Ignored,
                                 QSizePolicy.Expanding)
        self.label.setAlignment(Qt.AlignCenter)
        self.label.setAttribute(Qt.WA_TransparentForMouseEvents)

        self.svg = SVGThumbnailWidget(svg_data, parent=self)
        self.svg.setAttribute(Qt.WA_TransparentForMouseEvents)

        layout = QVBoxLayout()
        layout.addWidget(self.label, stretch=1, alignment=Qt.AlignCenter)
        layout.addWidget(self.svg, stretch=4, alignment=Qt.AlignCenter)

        self.setLayout(layout)
        self.setSizePolicy(QSizePolicy.Fixed, QSizePolicy.Fixed)

        self._selected = False

    def setSelected(self, val):
        if self._selected != val:
            self._selected = val
            self.svg.setSelected(val)

    def getSelected(self):
        return self._selected

    selected = property(getSelected, setSelected)

    def setData(self, data):
        self.svg.setData(data)

    def setImageSize(self, width, height):
        self.svg.setFixedSize(width, height)

    def paintEvent(self, event):
        QFrame.paintEvent(self, event)

    def mousePressEvent(self, event):
        if event.button() & Qt.LeftButton:
            parent = self.parent()
            if event.modifiers() & Qt.ControlModifier:
                self.setSelected(not self._selected)
            else:
                for child in parent.findChildren(ThumbnailWidget):
                    child.setSelected(False)

                self.setSelected(True)

            parent.selectionChanged.emit()

        super(ThumbnailWidget, self).mousePressEvent(event)

    def mouseDoubleClickEvent(self, event):
        self._bigimage = BigSvgWidget()
        self._bigimage.load(QByteArray(self.svg._data))
        self._bigimage.show()

    def customEvent(self, event):
        self.layout().invalidate()
        self.update()
Exemplo n.º 15
0
class QuadStatusBar(QHBoxLayout):
    def __init__(self, parent=None ):
        QHBoxLayout.__init__(self, parent)
        self.setContentsMargins(0,4,0,0)
        self.setSpacing(0)   
        
    def createQuadViewStatusBar(self, xbackgroundColor, xforegroundColor, ybackgroundColor, yforegroundColor, zbackgroundColor, zforegroundColor, graybackgroundColor, grayforegroundColor):             
        
        self.xLabel = QLabel()
        self.xLabel.setAttribute(Qt.WA_TransparentForMouseEvents, True)
        self.addWidget(self.xLabel)
        pixmap = QPixmap(25*10, 25*10)
        pixmap.fill(xbackgroundColor)
        painter = QPainter()
        painter.begin(pixmap)
        pen = QPen(xforegroundColor)
        painter.setPen(pen)
        painter.setRenderHint(QPainter.Antialiasing)
        font = QFont()
        font.setBold(True)
        font.setPixelSize(25*10-30)
        path = QPainterPath()
        path.addText(QPointF(50, 25*10-50), font, "X")
        brush = QBrush(xforegroundColor)
        painter.setBrush(brush)
        painter.drawPath(path)        
        painter.setFont(font)
        painter.end()
        pixmap = pixmap.scaled(QSize(20,20),Qt.KeepAspectRatio, Qt.SmoothTransformation)
        self.xLabel.setPixmap(pixmap)
        self.xSpinBox = QSpinBox()
        self.xSpinBox.setAttribute(Qt.WA_TransparentForMouseEvents, True)
        self.xSpinBox.setEnabled(False)
        self.xSpinBox.setAlignment(Qt.AlignCenter)
        self.xSpinBox.setToolTip("xSpinBox")
        self.xSpinBox.setButtonSymbols(QAbstractSpinBox.NoButtons)
        self.xSpinBox.setMaximumHeight(20)
        self.xSpinBox.setMaximum(9999)
        font = self.xSpinBox.font()
        font.setPixelSize(14)
        self.xSpinBox.setFont(font)
        self.xSpinBox.setStyleSheet("QSpinBox { color: " + str(xforegroundColor.name()) + "; font: bold; background-color: " + str(xbackgroundColor.name()) + "; border:0;}")
        self.addWidget(self.xSpinBox)
        
        self.yLabel = QLabel()
        self.yLabel.setAttribute(Qt.WA_TransparentForMouseEvents, True)
        self.addWidget(self.yLabel)
        pixmap = QPixmap(25*10, 25*10)
        pixmap.fill(ybackgroundColor)
        painter = QPainter()
        painter.begin(pixmap)
        pen = QPen(yforegroundColor)
        painter.setPen(pen)
        painter.setRenderHint(QPainter.Antialiasing)
        font = QFont()
        font.setBold(True)
        font.setPixelSize(25*10-30)
        path = QPainterPath()
        path.addText(QPointF(50, 25*10-50), font, "Y")
        brush = QBrush(yforegroundColor)
        painter.setBrush(brush)
        painter.drawPath(path)        
        painter.setFont(font)
        painter.end()
        pixmap = pixmap.scaled(QSize(20,20),Qt.KeepAspectRatio, Qt.SmoothTransformation)
        self.yLabel.setPixmap(pixmap)
        self.ySpinBox = QSpinBox()
        self.ySpinBox.setAttribute(Qt.WA_TransparentForMouseEvents, True)
        self.ySpinBox.setEnabled(False)
        self.ySpinBox.setAlignment(Qt.AlignCenter)
        self.ySpinBox.setToolTip("ySpinBox")
        self.ySpinBox.setButtonSymbols(QAbstractSpinBox.NoButtons)
        self.ySpinBox.setMaximumHeight(20)
        self.ySpinBox.setMaximum(9999)
        font = self.ySpinBox.font()
        font.setPixelSize(14)
        self.ySpinBox.setFont(font)
        self.ySpinBox.setStyleSheet("QSpinBox { color: " + str(yforegroundColor.name()) + "; font: bold; background-color: " + str(ybackgroundColor.name()) + "; border:0;}")
        self.addWidget(self.ySpinBox)
        
        self.zLabel = QLabel()
        self.zLabel.setAttribute(Qt.WA_TransparentForMouseEvents, True)
        self.addWidget(self.zLabel)
        pixmap = QPixmap(25*10, 25*10)
        pixmap.fill(zbackgroundColor)
        painter = QPainter()
        painter.begin(pixmap)
        pen = QPen(zforegroundColor)
        painter.setPen(pen)
        painter.setRenderHint(QPainter.Antialiasing)
        font = QFont()
        font.setBold(True)
        font.setPixelSize(25*10-30)
        path = QPainterPath()
        path.addText(QPointF(50, 25*10-50), font, "Z")
        brush = QBrush(zforegroundColor)
        painter.setBrush(brush)
        painter.drawPath(path)        
        painter.setFont(font)
        painter.end()
        pixmap = pixmap.scaled(QSize(20,20),Qt.KeepAspectRatio, Qt.SmoothTransformation)
        self.zLabel.setPixmap(pixmap)
        self.zSpinBox = QSpinBox()
        self.zSpinBox.setAttribute(Qt.WA_TransparentForMouseEvents, True)
        self.zSpinBox.setEnabled(False)
        self.zSpinBox.setAlignment(Qt.AlignCenter)
        self.zSpinBox.setToolTip("zSpinBox")
        self.zSpinBox.setButtonSymbols(QAbstractSpinBox.NoButtons)
        self.zSpinBox.setMaximumHeight(20)
        self.zSpinBox.setMaximum(9999)
        font = self.zSpinBox.font()
        font.setPixelSize(14)
        self.zSpinBox.setFont(font)
        self.zSpinBox.setStyleSheet("QSpinBox { color: " + str(zforegroundColor.name()) + "; font: bold; background-color: " + str(zbackgroundColor.name()) + "; border:0;}")
        self.addWidget(self.zSpinBox)
        
        self.addSpacing(4)
        
        self.grayScaleLabel = QLabel()
        self.grayScaleLabel.setAttribute(Qt.WA_TransparentForMouseEvents, True)
        self.addWidget(self.grayScaleLabel)
        pixmap = QPixmap(610, 250)
        pixmap.fill(graybackgroundColor)
        painter = QPainter()
        painter.begin(pixmap)
        pen = QPen(grayforegroundColor)
        painter.setPen(pen)
        painter.setRenderHint(QPainter.Antialiasing)
        font = QFont()
        font.setBold(True)
        font.setPixelSize(25*10-30)
        path = QPainterPath()
        path.addText(QPointF(50, 25*10-50), font, "Gray")
        brush = QBrush(grayforegroundColor)
        painter.setBrush(brush)
        painter.drawPath(path)        
        painter.setFont(font)
        painter.end()
        pixmap = pixmap.scaled(QSize(61,20),Qt.KeepAspectRatio, Qt.SmoothTransformation)
        
        """
        self.grayScaleLabel.setPixmap(pixmap)
        self.grayScaleSpinBox = QSpinBox()
        self.grayScaleSpinBox.setAttribute(Qt.WA_TransparentForMouseEvents, True)
        self.grayScaleSpinBox.setEnabled(False)
        self.grayScaleSpinBox.setAlignment(Qt.AlignCenter)
        self.grayScaleSpinBox.setToolTip("grayscaleSpinBox")
        self.grayScaleSpinBox.setButtonSymbols(QAbstractSpinBox.NoButtons)
        self.grayScaleSpinBox.setMaximum(255)
        self.grayScaleSpinBox.setMaximumHeight(20)
        self.grayScaleSpinBox.setMaximum(255)
        font = self.grayScaleSpinBox.font()
        font.setPixelSize(14)
        self.grayScaleSpinBox.setFont(font)
        self.grayScaleSpinBox.setStyleSheet("QSpinBox { color: " + str(grayforegroundColor.name()) + "; font: bold; background-color: " + str(graybackgroundColor.name()) + "; border:0;}")
        self.addWidget(self.grayScaleSpinBox)
        """
        
        self.addStretch()
        
        self.positionCheckBox = QCheckBox()
        self.positionCheckBox.setChecked(True)
        self.positionCheckBox.setCheckable(True)
        self.positionCheckBox.setText("Position")
        self.addWidget(self.positionCheckBox)
        
        self.addSpacing(20)
        
        self.channelLabel = QLabel("Channel:")
        self.addWidget(self.channelLabel)
        
        self.channelSpinBox = QSpinBox()
        self.addWidget(self.channelSpinBox)
        self.addSpacing(20)
        
        self.timeLabel = QLabel("Time:")
        self.addWidget(self.timeLabel)
        
        self.timeSpinBox = QSpinBox()
        self.addWidget(self.timeSpinBox)
    """    
    def setGrayScale(self, gray):
        self.grayScaleSpinBox.setValue(gray)
    """
        
    def setMouseCoords(self, x, y, z):
        self.xSpinBox.setValue(x)
        self.ySpinBox.setValue(y)
        self.zSpinBox.setValue(z)