class RatingControl(QObject, CheckClickedMixin):
    """
    Controls for visualizing the votes and subscription information for channels.
    """

    rating_colors = {
        "BACKGROUND": QColor("#444444"),
        "FOREGROUND": QColor("#BBBBBB"),
        # "SUBSCRIBED_HOVER": QColor("#FF5722"),
    }

    clicked = pyqtSignal(QModelIndex)

    def __init__(self, column_name, parent=None):
        QObject.__init__(self, parent=parent)
        self.column_name = column_name
        self.last_index = QModelIndex()
        self.font = None
        # For some reason, on MacOS default inter-character spacing for some symbols
        # is too wide. We have to adjust it manually.
        if DARWIN or WINDOWS:
            self.font = QFont()
            self.font.setLetterSpacing(QFont.PercentageSpacing, 60.0)

    def paint(self, painter, rect, _index, votes=0):
        draw_text(painter, rect, format_votes(1.0), color=self.rating_colors["BACKGROUND"], font=self.font)
        draw_text(painter, rect, format_votes(votes), color=self.rating_colors["FOREGROUND"], font=self.font)
Beispiel #2
0
def setFontMetrics():
    """ Application must be running before you mess
    too much with Fonts in Qt5
    """
    global SEQUENCEFONT
    global SEQUENCEFONTMETRICS
    global SEQUENCEFONTCHARWIDTH
    global SEQUENCEFONTCHARHEIGHT
    global SEQUENCEFONTEXTRAWIDTH
    global SEQUENCETEXTXCENTERINGOFFSET
    global SEQUENCETEXTYCENTERINGOFFSET
    SEQUENCEFONT = QFont("Monaco")
    if hasattr(QFont, 'Monospace'):
        SEQUENCEFONT.setStyleHint(QFont.Monospace)
    SEQUENCEFONT.setFixedPitch(True)
    SEQUENCEFONTH = int(PATH_BASE_WIDTH / 3.)
    SEQUENCEFONT.setPixelSize(SEQUENCEFONTH)
    SEQUENCEFONTMETRICS = QFontMetricsF(SEQUENCEFONT)
    SEQUENCEFONTCHARWIDTH = SEQUENCEFONTMETRICS.width("A")
    SEQUENCEFONTCHARHEIGHT = SEQUENCEFONTMETRICS.height()
    SEQUENCEFONTEXTRAWIDTH = PATH_BASE_WIDTH - SEQUENCEFONTCHARWIDTH
    SEQUENCEFONT.setLetterSpacing(QFont.AbsoluteSpacing,
                                 SEQUENCEFONTEXTRAWIDTH)
    SEQUENCETEXTXCENTERINGOFFSET = SEQUENCEFONTEXTRAWIDTH / 4.
    SEQUENCETEXTYCENTERINGOFFSET = PATH_BASE_WIDTH * 0.6
Beispiel #3
0
    def seed_img(self, is_seed = True):

        if is_seed:
            try:
                cseed = self.get_seed()
            except UserCancelled:
                return
            except InvalidPassword as e:
                self.d.show_error(str(e))
                return
            if not cseed:
                self.d.show_message(_("This wallet has no seed"))
                return
            txt = cseed.upper()
        else:
            txt = self.txt.upper()

        img = QImage(self.SIZE[0], self.SIZE[1], QImage.Format_Mono)
        bitmap = QBitmap.fromImage(img, Qt.MonoOnly)
        bitmap.fill(Qt.white)
        painter = QPainter()
        painter.begin(bitmap)
        QFontDatabase.addApplicationFont(os.path.join(os.path.dirname(__file__), 'SourceSansPro-Bold.otf') )
        if len(txt) < 102 :
            fontsize = 15
            linespace = 15
            max_letters = 17
            max_lines = 6
            max_words = 3
        else:
            fontsize = 12
            linespace = 10
            max_letters = 21
            max_lines = 9
            max_words = int(max_letters/4)

        font = QFont('Source Sans Pro', fontsize, QFont.Bold)
        font.setLetterSpacing(QFont.PercentageSpacing, 100)
        font.setPixelSize(fontsize)
        painter.setFont(font)
        seed_array = txt.split(' ')

        for n in range(max_lines):
            nwords = max_words
            temp_seed = seed_array[:nwords]
            while len(' '.join(map(str, temp_seed))) > max_letters:
               nwords = nwords - 1
               temp_seed = seed_array[:nwords]
            painter.drawText(QRect(0, linespace*n , self.SIZE[0], self.SIZE[1]), Qt.AlignHCenter, ' '.join(map(str, temp_seed)))
            del seed_array[:nwords]

        painter.end()
        img = bitmap.toImage()
        if (self.rawnoise == False):
            self.make_rawnoise()

        self.make_cypherseed(img, self.rawnoise, False, is_seed)
        return img
Beispiel #4
0
    def seed_img(self, is_seed = True):

        if is_seed:
            try:
                cseed = self.get_seed()
            except UserCancelled:
                return
            except InvalidPassword as e:
                self.d.show_error(str(e))
                return
            if not cseed:
                self.d.show_message(_("This wallet has no seed"))
                return
            txt = cseed.upper()
        else:
            txt = self.txt.upper()

        img = QImage(self.SIZE[0], self.SIZE[1], QImage.Format_Mono)
        bitmap = QBitmap.fromImage(img, Qt.MonoOnly)
        bitmap.fill(Qt.white)
        painter = QPainter()
        painter.begin(bitmap)
        QFontDatabase.addApplicationFont(os.path.join(os.path.dirname(__file__), 'SourceSansPro-Bold.otf') )
        if len(txt) < 102 :
            fontsize = 15
            linespace = 15
            max_letters = 17
            max_lines = 6
            max_words = 3
        else:
            fontsize = 12
            linespace = 10
            max_letters = 21
            max_lines = 9
            max_words = int(max_letters/4)

        font = QFont('Source Sans Pro', fontsize, QFont.Bold)
        font.setLetterSpacing(QFont.PercentageSpacing, 100)
        font.setPixelSize(fontsize)
        painter.setFont(font)
        seed_array = txt.split(' ')

        for n in range(max_lines):
            nwords = max_words
            temp_seed = seed_array[:nwords]
            while len(' '.join(map(str, temp_seed))) > max_letters:
               nwords = nwords - 1
               temp_seed = seed_array[:nwords]
            painter.drawText(QRect(0, linespace*n , self.SIZE[0], self.SIZE[1]), Qt.AlignHCenter, ' '.join(map(str, temp_seed)))
            del seed_array[:nwords]

        painter.end()
        img = bitmap.toImage()
        if (self.rawnoise == False):
            self.make_rawnoise()

        self.make_cypherseed(img, self.rawnoise, False, is_seed)
        return img
Beispiel #5
0
    def init_ui(self):
        self.setStyle(QStyleFactory.create("Windows"))

        self.setView(QListView())

        font = QFont()
        font.setLetterSpacing(QFont.AbsoluteSpacing, 0.8)
        font.setPixelSize(11)
        font.setCapitalization(QFont.AllUppercase)
        self.setFont(font)
Beispiel #6
0
 def draw(self):
     if len(hetaData) == 0:
         return
     font = QFont()
     color = QColor()
     font.setPointSize(self.fontSize)
     font.setFamily("Microsoft YaHei")
     font.setLetterSpacing(QFont.AbsoluteSpacing, 0)
     index = 0
     lock.acquire()
     frame = hetaData.pop(0)
     lock.release()
     maxHet = frame["maxHet"]
     minHet = frame["minHet"]
     frame = frame["frame"]
     p = QPainter(self.cameraBuffer)
     p.fillRect(0, 0, self.width, self.height + self.textLineHeight,
                QBrush(QColor(Qt.black)))
     # draw camera
     color = QColor()
     for yIndex in range(int(self.height / self.pixelSize)):
         for xIndex in range(int(self.width / self.pixelSize)):
             tempData = constrain(
                 mapValue(frame[index], minHet, maxHet, minHue, maxHue),
                 minHue, maxHue)
             color.setHsvF(tempData / 360, 1.0, 1.0)
             p.fillRect(xIndex * self.pixelSize, yIndex * self.pixelSize,
                        self.pixelSize, self.pixelSize, QBrush(color))
             index = index + 1
     self.cameraItem.setPixmap(self.cameraBuffer)
     # draw text
     p = QPainter(self.hetTextBuffer)
     p.fillRect(0, 0, self.width, self.height + self.textLineHeight,
                QBrush(QColor(Qt.black)))
     hetDiff = maxHet - minHet
     bastNum = round(minHet)
     interval = round(hetDiff / 5)
     for i in range(5):
         hue = constrain(
             mapValue((bastNum + (i * interval)), minHet, maxHet, minHue,
                      maxHue), minHue, maxHue)
         color.setHsvF(hue / 360, 1.0, 1.0)
         p.setPen(color)
         p.setFont(font)
         p.drawText(i * self.textInterval, self.fontSize + 3,
                    str(bastNum + (i * interval)) + "°")
     self.hetTextItem.setPixmap(self.hetTextBuffer)
     # draw center het text
     cneter = round(frame[self.centerIndex], 1)
     centerText = "<font color=white>%s</font>"
     self.centerTextItem.setFont(font)
     self.centerTextItem.setHtml(centerText % (str(cneter) + "°"))
     self.frameCount = self.frameCount + 1
     print("picture->" + str(self.frameCount))
Beispiel #7
0
    def init_ui(self):
        self.layout = QVBoxLayout()
        self.titleLabel = QLabel("STATUS")
        self.progress = CustomProgressBar()
        self.progress.setText("Waiting")

        font = QFont()
        font.setLetterSpacing(QFont.AbsoluteSpacing, 2)
        font.setPixelSize(11.5)
        self.titleLabel.setFont(font)
        self.titleLabel.setObjectName("titleLabel")

        self.layout.addWidget(self.titleLabel)
        self.layout.addWidget(self.progress)

        self.setLayout(self.layout)
        self.layout.setContentsMargins(15, 15, 15, 15)
        self.setObjectName("progressPanel")
        self.setAutoFillBackground(True)
        self.show()
Beispiel #8
0
    def update_subscribe_button(self, remote_response=None):
        # A safeguard against race condition that happens when the user changed
        # the channel view before the response came in
        if self.isHidden():
            return

        if remote_response and "subscribed" in remote_response:
            self.contents_widget.model.channel_info["subscribed"] = remote_response["subscribed"]

        self.subscribe_button.setChecked(bool(remote_response["subscribed"]))
        self._adjust_tooltip(bool(remote_response["subscribed"]))

        # Update rating display
        votes = remote_response['votes']
        self.channel_rating_label.setText(format_votes_rich_text(votes))
        if DARWIN or WINDOWS:
            font = QFont()
            font.setLetterSpacing(QFont.PercentageSpacing, 60.0)
            self.channel_rating_label.setFont(font)

        self.channel_rating_label.setToolTip(get_votes_rating_description(votes))
class MonoFont:
    def __init__(self, name, size):
        self.font = QFont(name, size)
        self.font.setKerning(False)
        self.ascent = int(QFontMetricsF(self.font).ascent())
        self.charWidth = QFontMetricsF(self.font).width("X")
        self.charHeight = int(QFontMetricsF(self.font).height())
        self.charOffset = 0  # can introduce extra linespacing here

        self.bold = QFont(self.font)
        self.bold.setBold(True)

        self.under = QFont(self.font)
        self.under.setUnderline(True)

        # align character width properly
        if self.charWidth % 1.0 < 0.5:
            adjust = -(self.charWidth % 1.0)
        else:
            adjust = 1.0 - (self.charWidth % 1.0)

        self.charWidth += adjust
        self.font.setLetterSpacing(QFont.AbsoluteSpacing, adjust)
        self.bold.setLetterSpacing(QFont.AbsoluteSpacing, adjust)
        self.under.setLetterSpacing(QFont.AbsoluteSpacing, adjust)
Beispiel #10
0
    def init_ui(self):
        self.layout = QVBoxLayout()
        self.layout.setContentsMargins(0, 0, 0, 0)
        self.setContentsMargins(0, 0, 0, 0)
        self.titleLabel = QLabel("Neural Network")
        self.progressModule = ProgressModule()
        self.layout.addWidget(self.progressModule)
        self.menu = MenuModule()
        self.menu.selectionModel().selectionChanged.connect(self.selected_item)
        font = QFont()
        font.setLetterSpacing(QFont.AbsoluteSpacing, 2)
        font.setPixelSize(11.5)
        menuLabel = QLabel("MENU")
        menuLabel.setFont(font)
        menuLabel.setObjectName("menuLabel")

        self.layout.addWidget(menuLabel)
        self.layout.addWidget(self.menu)
        self.setObjectName("menuPanel")

        self.setLayout(self.layout)
        self.setAutoFillBackground(True)
    def init_ui(self):

        self.layout = QVBoxLayout()
        self.setObjectName("tablePanel")

        self.training_label = QLabel("Training set")
        self.layout.addWidget(self.training_label)
        font = QFont()
        font.setLetterSpacing(QFont.AbsoluteSpacing, 2)
        font.setPixelSize(11.5)
        font.setCapitalization(QFont.AllUppercase)
        self.training_label.setFont(font)

        self.trainingTable = Datatable()
        self.empty_label = QLabel("Currently empty")
        self.trainingTable.setVisible(False)
        self.trainingTable.added.connect(self.added_to_table)
        self.trainingViewAll = CustomPushButton("View all")
        self.trainingViewAll.clicked.connect(self.clicked_training_view_all)
        self.trainingViewAll.setVisible(False)
        self.layout.addWidget(self.trainingTable)
        self.layout.addWidget(self.empty_label)
        self.layout.addWidget(self.trainingViewAll)

        self.testing_label = QLabel("Test set")
        self.layout.addWidget(self.testing_label)
        self.testing_label.setFont(font)
        self.testing_quantity = QLabel("0 items")
        self.testingViewAll = CustomPushButton("View all")
        self.testingViewAll.clicked.connect(self.clicked_testing_view_all)
        self.layout.addWidget(self.testing_quantity)
        self.layout.addWidget(self.testingViewAll)
        self.testingViewAll.setVisible(False)

        self.setContentsMargins(5, 0, 5, 0)
        self.setLayout(self.layout)
        self.setAutoFillBackground(True)
Beispiel #12
0
    def splash_screen():
        path = pkg_resources.resource_filename(
            __name__, "icons/orange-splash-screen.png")
        pm = QPixmap(path)

        version = QCoreApplication.applicationVersion()
        size = 21 if len(version) < 5 else 16
        font = QFont("Helvetica")
        font.setPixelSize(size)
        font.setBold(True)
        font.setItalic(True)
        font.setLetterSpacing(QFont.AbsoluteSpacing, 2)
        metrics = QFontMetrics(font)
        br = metrics.boundingRect(version).adjusted(-5, 0, 5, 0)
        br.moveCenter(QPoint(436, 224))

        p = QPainter(pm)
        p.setRenderHint(QPainter.Antialiasing)
        p.setRenderHint(QPainter.TextAntialiasing)
        p.setFont(font)
        p.setPen(QColor("#231F20"))
        p.drawText(br, Qt.AlignCenter, version)
        p.end()
        return pm, QRect(88, 193, 200, 20)
Beispiel #13
0
    def load(self, path: str, is_first_call: bool = True) -> None:
        if path == self._path:
            return

        theme_full_path = os.path.join(path, "theme.json")
        Logger.log(
            "d", "Loading theme file: {theme_full_path}".format(
                theme_full_path=theme_full_path))
        try:
            with open(theme_full_path, encoding="utf-8") as f:
                data = json.load(f)
        except EnvironmentError as e:
            Logger.error(
                "Unable to load theme file at {theme_full_path}: {err}".format(
                    theme_full_path=theme_full_path, err=e))
            return
        except UnicodeDecodeError:
            Logger.error(
                "Theme file at {theme_full_path} is corrupt (invalid UTF-8 bytes)."
                .format(theme_full_path=theme_full_path))
            return

        # Iteratively load inherited themes
        try:
            theme_id = data["metadata"]["inherits"]
            self.load(Resources.getPath(Resources.Themes, theme_id),
                      is_first_call=False)
        except FileNotFoundError:
            Logger.log("e", "Could not find inherited theme %s", theme_id)
        except KeyError:
            pass  # No metadata or no inherits keyword in the theme.json file

        if "colors" in data:
            for name, color in data["colors"].items():
                try:
                    c = QColor(color[0], color[1], color[2], color[3])
                except IndexError:  # Color doesn't have enough components.
                    Logger.log(
                        "w",
                        "Colour {name} doesn't have enough components. Need to have 4, but had {num_components}."
                        .format(name=name, num_components=len(color)))
                    continue  # Skip this one then.
                self._colors[name] = c

        fonts_dir = os.path.join(path, "fonts")
        if os.path.isdir(fonts_dir):
            for root, dirnames, filenames in os.walk(fonts_dir):
                for filename in filenames:
                    if filename.lower().endswith(".ttf"):
                        QFontDatabase.addApplicationFont(
                            os.path.join(root, filename))

        if "fonts" in data:
            system_font_size = QCoreApplication.instance().font().pointSize()
            for name, font in data["fonts"].items():
                q_font = QFont()
                q_font.setFamily(
                    font.get("family",
                             QCoreApplication.instance().font().family()))

                if font.get("bold"):
                    q_font.setBold(font.get("bold", False))
                else:
                    q_font.setWeight(font.get("weight", 50))

                q_font.setLetterSpacing(QFont.AbsoluteSpacing,
                                        font.get("letterSpacing", 0))
                q_font.setItalic(font.get("italic", False))
                q_font.setPointSize(int(
                    font.get("size", 1) * system_font_size))
                q_font.setCapitalization(QFont.AllUppercase if font.get(
                    "capitalize", False) else QFont.MixedCase)

                self._fonts[name] = q_font

        if "sizes" in data:
            for name, size in data["sizes"].items():
                s = QSizeF()
                s.setWidth(round(size[0] * self._em_width))
                s.setHeight(round(size[1] * self._em_height))

                self._sizes[name] = s

        iconsdir = os.path.join(path, "icons")
        if os.path.isdir(iconsdir):
            for icon in os.listdir(iconsdir):
                name = os.path.splitext(icon)[0]
                self._icons[name] = QUrl.fromLocalFile(
                    os.path.join(iconsdir, icon))

        imagesdir = os.path.join(path, "images")
        if os.path.isdir(imagesdir):
            for image in os.listdir(imagesdir):
                name = os.path.splitext(image)[0]
                self._images[name] = QUrl.fromLocalFile(
                    os.path.join(imagesdir, image))

        styles = os.path.join(path, "styles.qml")
        if os.path.isfile(styles):
            c = QQmlComponent(self._engine, styles)
            context = QQmlContext(self._engine, self._engine)
            context.setContextProperty("Theme", self)
            self._styles = c.create(context)

            if c.isError():
                for error in c.errors():
                    Logger.log("e", error.toString())

        Logger.log("d", "Loaded theme %s", path)
        self._path = path

        # only emit the theme loaded signal once after all the themes in the inheritance chain have been loaded
        if is_first_call:
            self.themeLoaded.emit()
Beispiel #14
0
    def load(self, path):
        if path == self._path:
            return

        self._path = path

        with open(os.path.join(self._path, "theme.json")) as f:
            Logger.log("d", "Loading theme file: %s",
                       os.path.join(self._path, "theme.json"))
            data = json.load(f)

        self._initializeDefaults()

        if "colors" in data:
            for name, color in data["colors"].items():
                c = QColor(color[0], color[1], color[2], color[3])
                self._colors[name] = c

        fontsdir = os.path.join(self._path, "fonts")
        if os.path.isdir(fontsdir):
            for file in os.listdir(fontsdir):
                if "ttf" in file:
                    QFontDatabase.addApplicationFont(
                        os.path.join(fontsdir, file))

        if "fonts" in data:
            for name, font in data["fonts"].items():
                f = QFont()
                f.setFamily(
                    font.get("family",
                             QCoreApplication.instance().font().family()))

                f.setBold(font.get("bold", False))
                f.setLetterSpacing(QFont.AbsoluteSpacing,
                                   font.get("letterSpacing", 0))
                f.setItalic(font.get("italic", False))
                f.setPixelSize(font.get("size", 1) * self._em_height)
                f.setCapitalization(QFont.AllUppercase if font.get(
                    "capitalize", False) else QFont.MixedCase)

                self._fonts[name] = f

        if "sizes" in data:
            for name, size in data["sizes"].items():
                s = QSizeF()
                s.setWidth(round(size[0] * self._em_width))
                s.setHeight(round(size[1] * self._em_height))

                self._sizes[name] = s

        iconsdir = os.path.join(self._path, "icons")
        if os.path.isdir(iconsdir):
            for icon in os.listdir(iconsdir):
                name = os.path.splitext(icon)[0]
                self._icons[name] = QUrl.fromLocalFile(
                    os.path.join(iconsdir, icon))

        imagesdir = os.path.join(self._path, "images")
        if os.path.isdir(imagesdir):
            for image in os.listdir(imagesdir):
                name = os.path.splitext(image)[0]
                self._images[name] = QUrl.fromLocalFile(
                    os.path.join(imagesdir, image))

        styles = os.path.join(self._path, "styles.qml")
        if os.path.isfile(styles):
            c = QQmlComponent(self._engine, styles)
            context = QQmlContext(self._engine, self._engine)
            context.setContextProperty("Theme", self)
            self._styles = c.create(context)

            if c.isError():
                for error in c.errors():
                    Logger.log("e", error.toString())

        Logger.log("d", "Loaded theme %s", self._path)
        self.themeLoaded.emit()
Beispiel #15
0
    def load(self, path):
        self._path = path

        with open(os.path.join(self._path, "theme.json")) as f:
            data = json.load(f)

        self._initializeDefaults()

        if "colors" in data:
            for name, color in data["colors"].items():
                c = QColor(color[0], color[1], color[2], color[3])
                self._colors[name] = c

        fontsdir = os.path.join(self._path, "fonts")
        if os.path.isdir(fontsdir):
            for file in os.listdir(fontsdir):
                if "ttf" in file:
                    QFontDatabase.addApplicationFont(os.path.join(fontsdir, file))

        if "fonts" in data:
            for name, font in data["fonts"].items():
                f = QFont()

                if not sys.platform == "win32":
                    # Excluding windows here as a workaround for bad font rendering
                    f.setFamily(font.get("family", QCoreApplication.instance().font().family()))

                f.setStyleName(font.get("style", "Regular"))
                f.setBold(font.get("bold", False))
                f.setLetterSpacing(QFont.AbsoluteSpacing, font.get("letterSpacing", 0))
                f.setItalic(font.get("italic", False))
                f.setPixelSize(font.get("size", 1) * self._em_height)
                f.setCapitalization(QFont.AllUppercase if font.get("capitalize", False) else QFont.MixedCase)

                self._fonts[name] = f

        if "sizes" in data:
            for name, size in data["sizes"].items():
                s = QSizeF()
                s.setWidth(round(size[0] * self._em_width))
                s.setHeight(round(size[1] * self._em_height))

                self._sizes[name] = s

        styles = os.path.join(self._path, "styles.qml")
        if os.path.isfile(styles):
            c = QQmlComponent(self._engine, styles)
            self._styles = c.create()

            if c.isError():
                for error in c.errors():
                    Logger.log("e", error.toString())

        iconsdir = os.path.join(self._path, "icons")
        if os.path.isdir(iconsdir):
            for icon in os.listdir(iconsdir):
                name = os.path.splitext(icon)[0]
                self._icons[name] = QUrl.fromLocalFile(os.path.join(iconsdir, icon))

        imagesdir = os.path.join(self._path, "images")
        if os.path.isdir(imagesdir):
            for image in os.listdir(imagesdir):
                name = os.path.splitext(image)[0]
                self._images[name] = QUrl.fromLocalFile(os.path.join(imagesdir, image))

        Logger.log("d", "Loaded theme %s", self._path)
        self.themeLoaded.emit()
Beispiel #16
0
    def load(self, path: str, is_first_call: bool = True) -> None:
        if path == self._path:
            return

        theme_full_path = os.path.join(path, "theme.json")
        Logger.log(
            "d", "Loading theme file: {theme_full_path}".format(
                theme_full_path=theme_full_path))
        try:
            with open(theme_full_path, encoding="utf-8") as f:
                data = json.load(f)
        except EnvironmentError as e:
            Logger.error(
                "Unable to load theme file at {theme_full_path}: {err}".format(
                    theme_full_path=theme_full_path, err=e))
            return
        except UnicodeDecodeError:
            Logger.error(
                "Theme file at {theme_full_path} is corrupt (invalid UTF-8 bytes)."
                .format(theme_full_path=theme_full_path))
            return
        except json.JSONDecodeError:
            Logger.error(
                "Theme file at {theme_full_path} is corrupt (invalid JSON syntax)."
                .format(theme_full_path=theme_full_path))
            return

        # Iteratively load inherited themes
        try:
            theme_id = data["metadata"]["inherits"]
            self.load(Resources.getPath(Resources.Themes, theme_id),
                      is_first_call=False)
        except FileNotFoundError:
            Logger.log("e", "Could not find inherited theme %s", theme_id)
        except KeyError:
            pass  # No metadata or no inherits keyword in the theme.json file

        if "colors" in data:
            for name, value in data["colors"].items():

                if not is_first_call and isinstance(value, str):
                    # Keep parent theme string colors as strings and parse later
                    self._colors[name] = value
                    continue

                if isinstance(value, str) and is_first_call:
                    # value is reference to base_colors color name
                    try:
                        color = data["base_colors"][value]
                    except IndexError:
                        Logger.log(
                            "w",
                            "Colour {value} could not be found in base_colors".
                            format(value=value))
                        continue
                else:
                    color = value

                try:
                    c = QColor(color[0], color[1], color[2], color[3])
                except IndexError:  # Color doesn't have enough components.
                    Logger.log(
                        "w",
                        "Colour {name} doesn't have enough components. Need to have 4, but had {num_components}."
                        .format(name=name, num_components=len(color)))
                    continue  # Skip this one then.
                self._colors[name] = c

        if "base_colors" in data:
            for name, color in data["base_colors"].items():
                try:
                    c = QColor(color[0], color[1], color[2], color[3])
                except IndexError:  # Color doesn't have enough components.
                    Logger.log(
                        "w",
                        "Colour {name} doesn't have enough components. Need to have 4, but had {num_components}."
                        .format(name=name, num_components=len(color)))
                    continue  # Skip this one then.
                self._colors[name] = c

        if is_first_call and self._colors:
            #Convert all string value colors to their referenced color
            for name, color in self._colors.items():
                if isinstance(color, str):
                    try:
                        c = self._colors[color]
                        self._colors[name] = c
                    except:
                        Logger.log(
                            "w",
                            "Colour {name} {color} does".format(name=name,
                                                                color=color))

        fonts_dir = os.path.join(path, "fonts")
        if os.path.isdir(fonts_dir):
            for root, dirnames, filenames in os.walk(fonts_dir):
                for filename in filenames:
                    if filename.lower().endswith(".ttf"):
                        QFontDatabase.addApplicationFont(
                            os.path.join(root, filename))

        if "fonts" in data:
            system_font_size = QCoreApplication.instance().font().pointSize()
            for name, font in data["fonts"].items():
                q_font = QFont()
                q_font.setFamily(
                    font.get("family",
                             QCoreApplication.instance().font().family()))

                if font.get("bold"):
                    q_font.setBold(font.get("bold", False))
                else:
                    q_font.setWeight(font.get("weight", 50))

                q_font.setLetterSpacing(QFont.AbsoluteSpacing,
                                        font.get("letterSpacing", 0))
                q_font.setItalic(font.get("italic", False))
                q_font.setPointSize(int(
                    font.get("size", 1) * system_font_size))
                q_font.setCapitalization(QFont.AllUppercase if font.get(
                    "capitalize", False) else QFont.MixedCase)

                self._fonts[name] = q_font

        if "sizes" in data:
            for name, size in data["sizes"].items():
                s = QSizeF()
                s.setWidth(round(size[0] * self._em_width))
                s.setHeight(round(size[1] * self._em_height))

                self._sizes[name] = s

        iconsdir = os.path.join(path, "icons")
        if os.path.isdir(iconsdir):
            try:
                for base_path, _, icons in os.walk(iconsdir):
                    detail_level = base_path.split(os.sep)[-1]
                    if detail_level not in self._icons:
                        self._icons[detail_level] = {}
                    for icon in icons:
                        name = os.path.splitext(icon)[0]
                        self._icons[detail_level][name] = QUrl.fromLocalFile(
                            os.path.join(base_path, icon))
            except EnvironmentError:  # Exception when calling os.walk, e.g. no access rights.
                pass  # Won't get any icons then. Images will show as black squares.

            deprecated_icons_file = os.path.join(iconsdir,
                                                 "deprecated_icons.json")
            if os.path.isfile(deprecated_icons_file):
                try:
                    with open(deprecated_icons_file, encoding="utf-8") as f:
                        data = json.load(f)
                        for icon in data:
                            self._deprecated_icons[icon] = data[icon]
                except (UnicodeDecodeError, json.decoder.JSONDecodeError,
                        EnvironmentError):
                    Logger.logException(
                        "w", "Could not parse deprecated icons list %s",
                        deprecated_icons_file)

        imagesdir = os.path.join(path, "images")
        if os.path.isdir(imagesdir):
            for image in os.listdir(imagesdir):
                name = os.path.splitext(image)[0]
                self._images[name] = QUrl.fromLocalFile(
                    os.path.join(imagesdir, image))

        Logger.log("d", "Loaded theme %s", path)
        Logger.info(f"System's em size is {self._em_height}px.")
        self._path = path

        # only emit the theme loaded signal once after all the themes in the inheritance chain have been loaded
        if is_first_call:
            self.themeLoaded.emit()
Beispiel #17
0
    def setupChartWithData(self, data, linecolor='#422F8A'):
        """
        Chart gets updated displaying the new data.

        Data has to be expressed on a dictionary form:
            - keys are timestamps
            - values are total balance for that timestamp
        """
        self.chart = QChart()

        self.chart.setTheme(QChart.ChartThemeDark)
        self.chart.setAnimationOptions(QChart.SeriesAnimations)
        self.chart.setBackgroundBrush(QBrush(QColor("transparent")))
        #         self.chart.setTitle("")
        #         self.chart.setTitleBrush(QBrush(QColor('white')))

        # Axis X (Dates)
        self.x_axis = QDateTimeAxis()
        self.x_axis.setTickCount(11)
        self.x_axis.setLabelsAngle(70)
        font = QFont()
        font.setFamily('Roboto')
        font.setLetterSpacing(QFont.PercentageSpacing, 110)
        font.setPointSize(8)
        self.x_axis.setLabelsFont(font)
        self.x_axis.setFormat("dd-MM-yy")
        self.x_axis.setTitleText(self.tr('Date'))
        self.x_axis.setTitleVisible(False)
        self.x_axis.setLineVisible(False)
        self.x_axis.setGridLineVisible(False)

        # Axis Y (Balances)
        self.y_axis = QValueAxis()
        if data != {}:
            self.y_axis.setMax(max(data.values()) * 1.05)
            self.y_axis.setMin(min(data.values()) * 0.95)
        # self.y_axis.setMinorGridLineVisible(False)
        self.y_axis.setLineVisible(False)
        self.y_axis.setGridLineColor(QColor("#ECE9F1"))

        self.chart.addAxis(self.y_axis, Qt.AlignLeft)
        self.chart.addAxis(self.x_axis, Qt.AlignBottom)

        # Series
        self.btcseries = QSplineSeries()
        for date in data:
            balance = data[date]
            date = QDateTime(datetime.fromtimestamp(int(float(date))))
            self.btcseries.append(date.toMSecsSinceEpoch(), balance)

        self.btcseries.setName("BTC")
        pen = QPen(QColor(linecolor))
        pen.setWidth(3)
        self.btcseries.setPen(pen)

        # Series functionality
        self.btcseries.hovered.connect(self.selectPoint)

        self.chart.addSeries(self.btcseries)
        self.btcseries.attachAxis(self.x_axis)
        self.btcseries.attachAxis(self.y_axis)

        self.setChart(self.chart)
        self.setRenderHint(QPainter.Antialiasing)
        self.setStyleSheet("border: 0px; background-color: rgba(0,0,0,0); ")

        self.chart.legend().hide()
Beispiel #18
0
class MainWindow(QWidget):
    def __init__(self):
        super(MainWindow, self).__init__()
        self.displayWindow()
        self.btn_a.clicked.connect(lambda x: self.onClickButton("clear"))
        self.btn_b.clicked.connect(lambda x: self.onClickButton("eval"))
        self.btn_c.clicked.connect(lambda x: self.onClickButton("add_drop"))
        self.btn_d.clicked.connect(lambda x: self.onClickButton("others"))
        self.count = 0

        with open("ticket.log", "w") as fi:
            fi.write("")

    def midpoint(self, obj_a, obj_b):
        x = (obj_a.width() // 2) - (obj_b.width() // 2)
        y = (obj_a.height() // 2) - (obj_b.height() // 2)

        return x, y

    def onClickButton(self, name):
        self.count += 1

        if name == "clear":
            code = "CL"
        elif name == "eval":
            code = "EV"
        elif name == "add_drop":
            code = "AD"
        else:
            code = "OT"

        self.ticket = f"{self.count:03d}{code}"
        self.popWindow(self.ticket)

        # Exporting ticket code
        with open("ticket.log", "a") as fo:
            fo.write(f"{self.ticket},{name}\n")

    def createButton(self, name, pos_y):
        btn = QPushButton(name, self)
        btn.setFixedSize(self.ui_width - 50, 50)
        btn.setCursor(Qt.PointingHandCursor)
        btn_x, btn_y = self.midpoint(self, btn)
        btn.move(btn_x, pos_y)
        btn.setStyleSheet("""
            QPushButton {
                background: rgba(211, 141, 0, 1);
                font-size: 20px;
                font-weight: normal;
                border-radius: 8px;
            }
            QPushButton::hover {
                background: rgba(255, 227, 15, 1);
            }
            """)

        return btn

    def popWindow(self, ticket):

        self.pw = QWidget()
        self.pw.setWindowModality(2)
        self.pw.setWindowFlags(Qt.WindowCloseButtonHint)
        self.pw.setFixedSize(250, 190)
        self.pw.setWindowTitle(f"Ticket Code: {ticket}")
        pw_x, pw_y = self.midpoint(self, self.pw)
        self.pw.move(self.mapToParent(QPoint(pw_x - 1, pw_y + 30)))
        self.pw.setStyleSheet("""
            QWidget {
                background: rgba(255, 255, 255, 1);
            }
            """)

        pw_label_a = QLabel("Your Ticket Code:", self.pw)
        pw_label_a.setFixedSize(173, 38)
        pw_lx, pw_ly = self.midpoint(self.pw, pw_label_a)
        pw_label_a.move(pw_lx, 30)
        pw_label_a.setStyleSheet("""
            QLabel {
                color: #333333;
                font-weight: bold;
                font-size: 20px;
            }
            """)

        pw_label_b = QLabel(f"{ticket}", self.pw)
        pw_label_b.setFixedSize(220, 60)
        pw_bx, pw_by = self.midpoint(self.pw, pw_label_b)
        pw_label_b.move(pw_bx, pw_by)
        pw_label_b.setFont(self.font_b)
        pw_label_b.setStyleSheet("""
            QLabel {
                color: #000000;
                font-weight: bold;
                font-size: 55px;
                border: 1px solid #ffffff;
            }
            """)

        self.pw.show()

    def displayWindow(self):
        self.ui_width = 320
        self.ui_height = 450
        self.move(180, 70)
        self.setWindowFlags(Qt.WindowCloseButtonHint)
        self.setFixedSize(self.ui_width, self.ui_height)
        self.setWindowTitle("IT Chairman's Office Que System")
        self.setStyleSheet("""
            QWidget {
                background: rgba(0, 0, 72, 1);
            }
            """)

        self.font_a = QFont()
        self.font_a.setLetterSpacing(QFont.AbsoluteSpacing, 10)

        self.font_b = QFont()
        self.font_b.setLetterSpacing(QFont.AbsoluteSpacing, 3.0)

        label_a = QLabel("WELCOME", self)
        label_a.setGeometry(5, 10, self.ui_width, 40)
        label_a.setFont(self.font_a)
        label_a.setStyleSheet("""
            QLabel {
                qproperty-alignment: AlignCenter;
                color: #ffffff;
                font-size: 40px;
                font-weight: 600;
            }
            """)

        label_b = QLabel("Please select any\noption below", self)
        label_b.setGeometry(0, 70, self.ui_width, 60)
        label_b.setFont(self.font_b)
        label_b.setStyleSheet("""
            QLabel {
                qproperty-alignment: AlignCenter;
                color: #ffffff;
                font-size: 22px;
                font-weight: 400;
            }
            """)

        self.btn_a = self.createButton("Clearance", 150)
        self.btn_b = self.createButton("Evaluation", 215)
        self.btn_c = self.createButton("Adding / Dropping", 280)
        self.btn_d = self.createButton("Others", 345)
 def init_ui(self):
     font = QFont()
     font.setLetterSpacing(QFont.AbsoluteSpacing, 0.8)
     font.setPixelSize(11)
     font.setCapitalization(QFont.AllUppercase)
     self.setFont(font)
Beispiel #20
0
    def load(self, path, is_first_call = True):
        if path == self._path:
            return

        with open(os.path.join(path, "theme.json"), encoding = "utf-8") as f:
            Logger.log("d", "Loading theme file: %s", os.path.join(path, "theme.json"))
            data = json.load(f)

        # Iteratively load inherited themes
        try:
            theme_id = data["metadata"]["inherits"]
            self.load(Resources.getPath(Resources.Themes, theme_id), is_first_call = False)
        except FileNotFoundError:
            Logger.log("e", "Could not find inherited theme %s", theme_id)
        except KeyError:
            pass # No metadata or no inherits keyword in the theme.json file

        if "colors" in data:
            for name, color in data["colors"].items():
                c = QColor(color[0], color[1], color[2], color[3])
                self._colors[name] = c

        fontsdir = os.path.join(path, "fonts")
        if os.path.isdir(fontsdir):
            for file in os.listdir(fontsdir):
                if "ttf" in file:
                    QFontDatabase.addApplicationFont(os.path.join(fontsdir, file))

        if "fonts" in data:
            system_font_size = QCoreApplication.instance().font().pointSize()
            for name, font in data["fonts"].items():
                f = QFont()
                f.setFamily(font.get("family", QCoreApplication.instance().font().family()))

                if font.get("bold"):
                    f.setBold(font.get("bold", False))
                else:
                    f.setWeight(font.get("weight", 50))

                f.setLetterSpacing(QFont.AbsoluteSpacing, font.get("letterSpacing", 0))
                f.setItalic(font.get("italic", False))
                f.setPointSize(int(font.get("size", 1) * system_font_size))
                f.setCapitalization(QFont.AllUppercase if font.get("capitalize", False) else QFont.MixedCase)

                self._fonts[name] = f

        if "sizes" in data:
            for name, size in data["sizes"].items():
                s = QSizeF()
                s.setWidth(round(size[0] * self._em_width))
                s.setHeight(round(size[1] * self._em_height))

                self._sizes[name] = s

        iconsdir = os.path.join(path, "icons")
        if os.path.isdir(iconsdir):
            for icon in os.listdir(iconsdir):
                name = os.path.splitext(icon)[0]
                self._icons[name] = QUrl.fromLocalFile(os.path.join(iconsdir, icon))

        imagesdir = os.path.join(path, "images")
        if os.path.isdir(imagesdir):
            for image in os.listdir(imagesdir):
                name = os.path.splitext(image)[0]
                self._images[name] = QUrl.fromLocalFile(os.path.join(imagesdir, image))

        styles = os.path.join(path, "styles.qml")
        if os.path.isfile(styles):
            c = QQmlComponent(self._engine, styles)
            context = QQmlContext(self._engine, self._engine)
            context.setContextProperty("Theme", self)
            self._styles = c.create(context)

            if c.isError():
                for error in c.errors():
                    Logger.log("e", error.toString())

        Logger.log("d", "Loaded theme %s", path)
        self._path = path

        # only emit the theme loaded signal once after all the themes in the inheritance chain have been loaded
        if is_first_call:
            self.themeLoaded.emit()
Beispiel #21
0
class MainWindow(QWidget):
    def __init__(self):
        super(MainWindow, self).__init__()
        self.threadpool = QThreadPool()
        self.displayWindow()
        self.callWindow()
        self.combo.activated.connect(lambda x: self.priorityStatus(x))
        self.df_index = 0
        self.cl_index = 0
        self.ev_index = 0
        self.ad_index = 0
        self.ot_index = 0
        self.curr_prio = 0
        self.called = []

    def displayWindow(self):

        self.setWindowTitle("Next Ticket Window")
        self.setGeometry(520, 100, 550, 260)
        self.setStyleSheet("""
            QWidget {
                background: rgb(0, 0, 72);
            }
            """)

        self.font1 = QFont()
        self.font1.setLetterSpacing(QFont.AbsoluteSpacing, 1.3)
        self.font1.setPixelSize(20)

        self.label1 = QLabel("Ticket Code", self)
        self.label1.setFixedSize(150, 40)
        mid_x1 = (self.width() - self.label1.width()) // 2
        self.label1.move(mid_x1, 10)
        self.label1.setFont(self.font1)
        self.label1.setStyleSheet("""
            QLabel {
                color:  rgba(255, 255, 255, 1);
                border: 1px solid rgba(255, 255, 255, 0.0);
                font-weight: 700;
                }
            """)
        self.label1.setAlignment(Qt.AlignCenter)

        font2 = QFont()
        font2.setLetterSpacing(QFont.AbsoluteSpacing, 1.3)
        font2.setPixelSize(60)

        self.label2 = QLabel("--------", self)
        self.label2.setFixedSize(350, 100)
        mid_x2 = (self.width() - self.label2.width()) // 2
        self.label2.move(mid_x2, 50)
        self.label2.setFont(font2)
        self.label2.setStyleSheet("""
            QLabel {
                color:  rgb(0, 0, 0);
                background: rgba(211, 141, 0, 1);
                border-radius: 10px;
                font-weight: 900;
                }
            """)
        self.label2.setAlignment(Qt.AlignCenter)

        self.label3 = QLabel("Proceed inside for", self)
        self.label3.setFixedSize(220, 40)
        mid_x3 = (self.width() - self.label3.width()) // 2
        self.label3.move(mid_x3, 170)
        self.label3.setFont(self.font1)
        self.label3.setStyleSheet("""
            QLabel {
                color:  rgba(255, 255, 255, 1);
                border: 1px solid rgba(255, 255, 255, 0.0);
                font-weight: 700;
                }
            """)
        self.label3.setAlignment(Qt.AlignCenter)

        font3 = QFont()
        font3.setPixelSize(30)
        font3.setLetterSpacing(QFont.AbsoluteSpacing, 1.3)

        self.label4 = QLabel("##########", self)
        self.label4.setFixedSize(320, 40)
        mid_x4 = (self.width() - self.label4.width()) // 2
        self.label4.move(mid_x4, 200)
        self.label4.setFont(font3)
        self.label4.setStyleSheet("""
            QLabel {
                color:  rgba(211, 141, 0, 1);
                border: 1px solid rgba(255, 255, 255, 0.0);
                font-weight: 700;
                }
            """)
        self.label4.setAlignment(Qt.AlignCenter)

    def callWindow(self):
        self.w2 = QWidget()
        self.w2.setStyleSheet("""
            QWidget {
                background: rgb(0, 0, 72);
            }
            """)
        self.w2.setWindowTitle("Caller Window")
        self.w2.setGeometry(520, 400, 550, 150)

        # Call next button
        self.call_button = QPushButton("Call Next Ticket", self.w2)
        self.call_button.setGeometry(130, 50, 350, 45)
        self.call_button.clicked.connect(self.onButtonClick)
        self.call_button.setFont(self.font1)
        self.call_button.setStyleSheet("""
            QPushButton {
                background: rgba(211, 141, 0, 1);
                border-radius: 10px;
                color: rgba(0, 0, 0, 1);
                font-weight: 700;
            }
            QPushButton:hover {
                background: rgba(255, 227, 15, 1);
            }
            """)
        mid_btn = (self.w2.width() - self.call_button.width()) // 2
        self.call_button.move(mid_btn, self.call_button.y())

        # Dropdown menu
        self.cb_label = QLabel("Set Priority", self.w2)
        self.cb_label.setFont(self.font1)
        self.cb_label.move(100, 20)
        self.cb_label.setStyleSheet("""
            QLabel {
                font-size: 17px;
                font-weight: 900;
                color: rgba(255, 255, 255, 1);
            }
            """)

        self.combo = QComboBox(self.w2)
        self.combo.addItems([
            "Default", "Clearance", "Evaluation", "Adding - Dropping",
            "Other Concerns"
        ])

        self.combo.setGeometry(220, 20, 230, 23)

        self.combo.setStyleSheet("""
            QComboBox {
                color: rgba(0, 0, 0, 1);
                background: rgba(255, 255, 255, 1);
                font-size: 13px;
            }
            QComboBox::item {
                background: #ffffff;
                border-top: 1px solid #dddddd;
                height: 20px;
            }

            QComboBox::item::selected {
                background: rgba(200, 200, 200, 1);
            }

            QComboBox:on {
                background: green;
            }
            """)

        # Notification
        self.font2 = QFont()
        self.font2.setLetterSpacing(QFont.AbsoluteSpacing, 1.4)
        self.label_notif = QLabel("* Ticket Status *", self.w2)
        self.label_notif.setFont(self.font2)
        self.label_notif.setFixedWidth(330)
        notif_x = (self.w2.width() // 2) - (self.label_notif.width() // 2)
        self.label_notif.move(notif_x, 100)
        self.label_notif.setAlignment(Qt.AlignCenter)
        self.label_notif.setStyleSheet("""
            QLabel {
                font-size: 10px;
                color: #ffffff;
            }
            """)

        self.w2.show()

    def onButtonClick(self):
        worker = Worker(self.magic)
        self.threadpool.start(worker)

    def priorityStatus(self, s):
        if s == 0:
            self.label_notif.setText("* Processing default tickets *")
        elif s == 1:
            self.label_notif.setText("* Processing clearance tickets *")
        elif s == 2:
            self.label_notif.setText("* Processing evaluation tickets *")
        elif s == 3:
            self.label_notif.setText("* Processing add - drop tickets *")
        else:
            self.label_notif.setText("* Processing other tickets *")

        self.curr_prio = s

    def showCurrentTicket(self, ticket):
        self.label2.setText(f"{ticket[0]}")
        self.setWindowTitle(f"Next Ticket Code: {ticket[0]}")

        if ticket[1] == "clear":
            self.label4.setText("Clearance")
        elif ticket[1] == "eval":
            self.label4.setText("Evaluation")
        elif ticket[1] == "add_drop":
            self.label4.setText("Adding / Dropping")
        else:
            self.label4.setText("Other concerns")

    def processPrio(self):
        def processTickets(f_label, p_label, index):
            tickets = [x for x in self.all_tickets if x[1] == f_label]

            if index < len(tickets):
                xx_ticket = tickets[index]

                if xx_ticket not in self.called:
                    self.showCurrentTicket(xx_ticket)
                    self.called.append(xx_ticket)
                else:
                    self.label_notif.setText(f"{xx_ticket} already called")

                return 1
            else:
                self.label_notif.setText(f"* {p_label} tickets done. ")
                return 0

        self.priorityStatus(self.curr_prio)

        if self.curr_prio == 0:
            f_label = None
            p_label = "Default"

            if self.df_index < len(self.all_tickets):
                df_ticket = self.all_tickets[self.df_index]

                if df_ticket not in self.called:
                    self.showCurrentTicket(df_ticket)
                    self.called.append(df_ticket)
                else:
                    self.label_notif.setText(f"{df_ticket} already called")

                self.df_index += 1
            else:
                self.label_notif.setText(f"{p_label} tickets done.")

        elif self.curr_prio == 1:
            f_label = "clear"
            p_label = "Clearance"

            to_add = processTickets(f_label, p_label, self.cl_index)
            self.cl_index += to_add

        elif self.curr_prio == 2:
            f_label = "eval"
            p_label = "Evaluation"

            to_add = processTickets(f_label, p_label, self.ev_index)
            self.ev_index += to_add

        elif self.curr_prio == 3:
            f_label = "add_drop"
            p_label = "Add - Drop"

            to_add = processTickets(f_label, p_label, self.ad_index)
            self.ad_index += to_add

        else:
            f_label = "others"
            p_label = "Other Concerns"
            ot_tickets = [x for x in self.all_tickets if x[1] == f_label]

            to_add = processTickets(f_label, p_label, self.ot_index)
            self.ot_index += to_add

    def magic(self):

        # Generating list of tickets from file including new ones
        self.all_tickets = []

        with open("ticket.log", "r") as fi:
            for entry in fi:
                if entry != "":
                    self.all_tickets.append(tuple(entry.strip().split(",")))

        self.processPrio()
Beispiel #22
0
    def load(self, path: str, is_first_call: bool = True) -> None:
        if path == self._path:
            return

        with open(os.path.join(path, "theme.json"), encoding = "utf-8") as f:
            Logger.log("d", "Loading theme file: %s", os.path.join(path, "theme.json"))
            data = json.load(f)

        # Iteratively load inherited themes
        try:
            theme_id = data["metadata"]["inherits"]
            self.load(Resources.getPath(Resources.Themes, theme_id), is_first_call = False)
        except FileNotFoundError:
            Logger.log("e", "Could not find inherited theme %s", theme_id)
        except KeyError:
            pass  # No metadata or no inherits keyword in the theme.json file

        if "colors" in data:
            for name, color in data["colors"].items():
                c = QColor(color[0], color[1], color[2], color[3])
                self._colors[name] = c

        fonts_dir = os.path.join(path, "fonts")
        if os.path.isdir(fonts_dir):
            for file in os.listdir(fonts_dir):
                if "ttf" in file:
                    QFontDatabase.addApplicationFont(os.path.join(fonts_dir, file))

        if "fonts" in data:
            system_font_size = QCoreApplication.instance().font().pointSize()
            for name, font in data["fonts"].items():
                q_font = QFont()
                q_font.setFamily(font.get("family", QCoreApplication.instance().font().family()))

                if font.get("bold"):
                    q_font.setBold(font.get("bold", False))
                else:
                    q_font.setWeight(font.get("weight", 50))

                q_font.setLetterSpacing(QFont.AbsoluteSpacing, font.get("letterSpacing", 0))
                q_font.setItalic(font.get("italic", False))
                q_font.setPointSize(int(font.get("size", 1) * system_font_size))
                q_font.setCapitalization(QFont.AllUppercase if font.get("capitalize", False) else QFont.MixedCase)

                self._fonts[name] = q_font

        if "sizes" in data:
            for name, size in data["sizes"].items():
                s = QSizeF()
                s.setWidth(round(size[0] * self._em_width))
                s.setHeight(round(size[1] * self._em_height))

                self._sizes[name] = s

        iconsdir = os.path.join(path, "icons")
        if os.path.isdir(iconsdir):
            for icon in os.listdir(iconsdir):
                name = os.path.splitext(icon)[0]
                self._icons[name] = QUrl.fromLocalFile(os.path.join(iconsdir, icon))

        imagesdir = os.path.join(path, "images")
        if os.path.isdir(imagesdir):
            for image in os.listdir(imagesdir):
                name = os.path.splitext(image)[0]
                self._images[name] = QUrl.fromLocalFile(os.path.join(imagesdir, image))

        styles = os.path.join(path, "styles.qml")
        if os.path.isfile(styles):
            c = QQmlComponent(self._engine, styles)
            context = QQmlContext(self._engine, self._engine)
            context.setContextProperty("Theme", self)
            self._styles = c.create(context)

            if c.isError():
                for error in c.errors():
                    Logger.log("e", error.toString())

        Logger.log("d", "Loaded theme %s", path)
        self._path = path

        # only emit the theme loaded signal once after all the themes in the inheritance chain have been loaded
        if is_first_call:
            self.themeLoaded.emit()
Beispiel #23
0
    def __init__(self, parent, path=""):
        #super().__init__()
        super(TextEdit, self).__init__(parent)

        self.parent = parent
        self.path = path

        font = QFont("Monospace", 8)  #QFont()
        #font.setFamily("Monospace")
        font.setStyleHint(QFont.Monospace)
        font.setStyle(QFont.StyleNormal)
        font.setStyleStrategy(QFont.PreferDefault)
        font.setWeight(QFont.ExtraLight)
        font.setCapitalization(QFont.MixedCase)
        font.setHintingPreference(QFont.PreferDefaultHinting)
        font.setLetterSpacing(QFont.PercentageSpacing, 100.0)
        font.setStretch(QFont.AnyStretch)

        font.setBold(False)
        font.setFixedPitch(True)
        font.setItalic(False)
        font.setKerning(True)
        font.setOverline(False)  # sobrelinea
        #font.setPixelSize(8) #font.setPointSize(8) font.setPointSizeF(8)
        font.setStrikeOut(False)  # tachado
        #font.setStyleName()
        font.setUnderline(False)
        #font.setWordSpacing(1)
        print(font.toString())

        charFormat = QTextCharFormat()
        charFormat.setFont(font)

        #self.setTabStopWidth(4)
        self.setCursorWidth(5)
        self.setCurrentCharFormat(charFormat)
        #print(self.document().defaultTextOption())

        #FIXME: Usaremos qss
        pal = QPalette()
        bgc = QColor(39, 40, 34)
        pal.setColor(QPalette.Base, bgc)
        textc = QColor(255, 255, 255)
        pal.setColor(QPalette.Text, textc)
        self.setPalette(pal)

        self.setLineWrapMode(QPlainTextEdit.NoWrap)

        #self.setTextBackgroundColor(QColor(0, 255, 255))
        #self.setTextColor(QColor(0, 255, 255))
        #self.setFontWeight(QFont.Normal)

        #cursor = self.textCursor()
        #cursor.movePosition(QTextCursor.End)
        #self.setDocumentTitle("Coso")

        #self.syntaxHighlighter = PythonHighlighter(self.document())

        # Señales
        #self.blockCountChanged.connect(self.__newBlock)
        #self.cursorPositionChanged.connect()
        #self.selectionChanged.connect(self.__changedSelection)
        #self.textChanged.connect(self.__changedText)
        #self.updateRequest.connect((const QRect &rect, int dy)
        #self.modificationChanged.connect(self.__chanedModification)

        #self.copyAvailable.connect(self.__copyAvailable)
        #self.undoAvailable.connect(self.__undoAvailable)
        #self.redoAvailable.connect(self.__redoAvailable)

        if os.path.exists(self.path):
            file = open(self.path, 'r')
            data = file.read()
            texto = self.__limpiar_codigo(data)
            self.setPlainText(texto)
            self.document().setModified(data != texto)
            if data != texto:
                print("El texto fue corregido al abrir el archivo.")
        else:
            self.setPlainText(
                "#!/usr/bin/python3\n# -*- coding: utf-8 -*-\n\n")
            self.document().setModified(True)

        self.setFocus()
Beispiel #24
0
    def draw(self):
        global minHue
        global maxHue
        global maxHet
        global minHet
        global device_commonOffset
        global evaluate_mode
        if len(displayData) == 0:
            return
        font = QFont()
        color = QColor()
        font.setPointSize(self.fontSize)
        #font.setFamily("Microsoft YaHei")
        font.setLetterSpacing(QFont.AbsoluteSpacing, 0)
        index = 0
        lock.acquire()
        frame = displayData.pop(0)
        lock.release()
        p = QPainter(self.cameraBuffer)
        p.fillRect(0, 0, self.width, self.height + self.textLineHeight,
                   QBrush(QColor(Qt.black)))
        # draw camera
        color = QColor()
        cneter = 0.0
        if chip == "90640":
            if self.centerIndex == 0:
                centerIndex = 12 * 32 + 16
            for yIndex in range(int(self.height / self.pixelSize)):
                for xIndex in range(int(self.width / self.pixelSize)):
                    color.setHsvF(frame[index] / 360, 1.0, 1.0)
                    p.fillRect(xIndex * self.pixelSize,
                               yIndex * self.pixelSize, self.pixelSize,
                               self.pixelSize, QBrush(color))
                    index = index + 1
            cneter = round(
                mapValue(frame[self.centerIndex], minHue, maxHue, minHet,
                         maxHet), 1)
        elif chip == "90621":
            if self.centerIndex == 0 or self.centerIndex >= 64:
                self.centerIndex = 2 * 16 + 8

            cneter = round(
                mapValue(frame[self.centerIndex], minHue, maxHue, minHet,
                         maxHet), 1)
            for yIndex in range(int(self.height / self.pixelSize / 6)):
                for xIndex in range(int(self.width / self.pixelSize / 2)):
                    color.setHsvF(frame[index] / 360, 1.0, 1.0)
                    p.fillRect(xIndex * self.pixelSize * 2,
                               yIndex * self.pixelSize * 2 + 160,
                               self.pixelSize * 2, self.pixelSize * 2,
                               QBrush(color))
                    index = index + 1
        elif chip == "90641":
            if self.centerIndex == 0 or self.centerIndex >= 192:
                self.centerIndex = 6 * 16 + 8

            cneter = round(
                mapValue(frame[self.centerIndex], minHue, maxHue, minHet,
                         maxHet), 1)
            for yIndex in range(int(self.height / self.pixelSize / 2)):
                for xIndex in range(int(self.width / self.pixelSize / 2)):
                    color.setHsvF(frame[index] / 360, 1.0, 1.0)
                    p.fillRect(xIndex * self.pixelSize * 2,
                               yIndex * self.pixelSize * 2, self.pixelSize * 2,
                               self.pixelSize * 2, QBrush(color))
                    index = index + 1
        else:
            print("Dsiplay Error: can't detect any chip type!")

        self.cameraItem.setPixmap(self.cameraBuffer)
        self.frameCount = self.frameCount + 1

        # draw text
        p = QPainter(self.hetTextBuffer)
        p.fillRect(0, 0, self.width + 200, self.height + self.textLineHeight,
                   QBrush(QColor(Qt.black)))

        version = self.dataThread.getID()
        p.setPen(QColor(Qt.white))
        p.setFont(font)
        p.drawText(0, self.fontSize, " max:" + '{:.2f}'.format(maxHet))
        p.drawText(self.textInterval, self.fontSize,
                   " min:" + '{:.2f}'.format(minHet))
        p.drawText(self.textInterval * 2, self.fontSize,
                   "offset:" + '{:.2f}'.format(device_commonOffset))
        p.drawText(self.textInterval * 3, self.fontSize,
                   "mode:" + detect_status)
        p.drawText(self.textInterval * 4, self.fontSize, evaluate_mode)
        p.drawText(self.textInterval * 5, self.fontSize,
                   "ID:" + str(version[0]))
        p.drawText(self.textInterval * 6, self.fontSize,
                   "ver:" + str(version[1] & 0xff))
        p.drawText(self.textInterval * 7, self.fontSize, chip)
        self.hetTextItem.setPixmap(self.hetTextBuffer)
        cneter = round(
            mapValue(frame[self.centerIndex], minHue, maxHue, minHet, maxHet),
            1)
        centerText = "<font color=white>%s</font>"
        self.centerTextItem.setFont(font)
        self.centerTextItem.setHtml(centerText % (str(cneter) + "°"))
        # draw version text
        self.versionTextItem.setFont(font)
Beispiel #25
0
class Window(QWidget):
    def __init__(self, parent=None):
        super(Window, self).__init__(parent)

        self.setWindowTitle("Calculator")

        self.display = QGroupBox(self)
        self.inside_display = QVBoxLayout()

        self.display_font = QFont("Menlo", 16)
        self.display_font.setLetterSpacing(QFont.AbsoluteSpacing, 2)

        self.lines = []
        for i in range(2 * LINES_TO_SHOW + 1):
            self.add_line()
        self.display.setLayout(self.inside_display)

        self.grid = "7 8 9r" \
           "4 5 6r" \
           "1 2 3r"
        self.grid = [li.split() for li in self.grid.split("r")]

        self.grid_layout = QGridLayout()

        for i, row in enumerate(self.grid):
            for j, column in enumerate(row):
                self.add_button(column, i, j)

        self.add_button("DEL", 0, 3)
        self.add_button("AC", 0, 4)
        self.add_button("x", 1, 3)
        self.add_button("÷", 1, 4)
        self.add_button("+", 2, 3)
        self.add_button("-", 2, 4)
        self.add_button("0", 3, 0)
        self.add_button("(", 3, 1)
        self.add_button(")", 3, 2)
        self.add_button(".", 3, 3)
        self.add_button("=", 3, 4)

        self.layout = QVBoxLayout()
        self.layout.addWidget(self.display)
        self.layout.addLayout(self.grid_layout)

        self.setLayout(self.layout)
        self.setFixedSize(self.sizeHint())

        self.previous_result = None
        self.previous_expressions = []
        self.current_expression = 0
        self.saved_expression = ""

    def add_button(self, button_str, x, y, clicked_str=None):
        if clicked_str is None:
            clicked_str = button_str
        button = QPushButton(button_str)
        self.grid_layout.addWidget(button, x, y)
        button.clicked.connect(lambda: self.button_pressed(clicked_str))

    def add_line(self, equals=None):
        line = QLabel()
        line.setFont(self.display_font)
        line.setLineWidth(2)

        if equals is not None:
            line.setAlignment(Qt.AlignRight)
            line.setText(equals)

        self.lines.append(line)
        self.inside_display.addWidget(line)

    def button_pressed(self, key_str):
        if key_str in ("x", "÷", "+", "-") and len(self.lines[-1].text()) == 0:
            # Check if this is the first key of the line pressed.
            # If it is, add ANS to the beginning
            self.button_pressed("ANS")
        if key_str == "DEL":
            self.delete_pressed()
        elif key_str == "AC":
            self.clear_pressed()
        elif key_str == "=":
            self.equals_pressed()
        elif key_str == "ANS" and self.previous_result is None:
            return
        else:
            self.lines[-1].setText(self.lines[-1].text() + key_str)

    def delete_pressed(self):
        current_line = self.lines[-1].text()
        if current_line.endswith("ANS"):
            to_delete = 3
            # Deletes all 3 characters of ANS
        else:
            to_delete = 1
        self.lines[-1].setText(current_line[:-to_delete])

    def clear_pressed(self):
        self.lines[-1].setText("")

    def equals_pressed(self):
        to_eval = self.lines[-1].text()
        self.previous_expressions.append(to_eval)
        to_eval = to_eval.replace("x", "*").replace("÷", "/")

        try:
            if "()" in to_eval or re.match(".*[^+\-*/(]\(.*", to_eval):
                # Checks if there is a non operator before the opening brackets
                # This avoids it trying to call an int as a function in eval
                raise SyntaxError

            if re.match(".*[^+\-*/(]ANS.*", to_eval) or \
             re.match(".*ANS[^+\-*/)].*", to_eval):
                # Checks if there is a non operator before or after the the ANS
                raise SyntaxError

            to_eval = to_eval.replace("ANS", str(self.previous_result))
            result = eval(to_eval)

            if result >= 10**13:
                raise ValueError

        except SyntaxError:
            result = "SYNTAX ERROR"
        except (ValueError, ZeroDivisionError):
            result = "MATH ERROR"
        else:
            # If it passes
            self.previous_result = result

            # Convert from 5.0 to 5
            if int(result) == result and isinstance(result, float):
                result = int(result)

            result = "=" + str(result)

        self.add_line(result)
        self.add_line()

        self.clear_top()
        self.current_expression = 0

    def clear_top(self):
        while len(self.lines) > 2 * LINES_TO_SHOW + 1:
            self.inside_display.removeWidget(self.lines[0])
            self.lines[0].deleteLater()
            del self.lines[0]

    def load_expression(self, up=True):
        if self.current_expression == 0:
            self.saved_expression = self.lines[-1].text()
        if up:
            if len(self.previous_expressions) < abs(self.current_expression -
                                                    1):
                # We have gone as far back as possible
                return
            self.current_expression -= 1
        else:
            if self.current_expression + 1 > 0:
                # We have returned to the original value
                return
            self.current_expression += 1
        if self.current_expression == 0:
            # We have returned to the start
            expression_to_load = self.saved_expression
        else:
            expression_to_load = self.previous_expressions[
                self.current_expression]
        self.lines[-1].setText(expression_to_load)

    def keyPressEvent(self, QKeyEvent):
        text, key = QKeyEvent.text().lower(), QKeyEvent.key()
        if text in ("0", "1", "2", "3", "4", "5", "6", "7", "8", "9", "x", "÷",
                    "+", "-", "(", ")", ".", "="):
            self.button_pressed(text)
        elif text == "*":
            self.button_pressed("x")
        elif text == "/":
            self.button_pressed("÷")
        elif text == "a":
            self.button_pressed("ANS")
        elif key == 16777219:  # DEL
            self.button_pressed("DEL")
        elif key == 16777220:  # Enter
            self.button_pressed("=")
        elif key in (16777235, 16777238):  # Up  or Page Up
            self.load_expression(up=True)
        elif key in (16777237, 16777239):  # Down  or Page Down
            self.load_expression(up=False)
        elif key == 16777216:  # Escape
            app.quit()
Beispiel #26
0
    def displayWindow(self):

        self.setWindowTitle("Next Ticket Window")
        self.setGeometry(520, 100, 550, 260)
        self.setStyleSheet("""
            QWidget {
                background: rgb(0, 0, 72);
            }
            """)

        self.font1 = QFont()
        self.font1.setLetterSpacing(QFont.AbsoluteSpacing, 1.3)
        self.font1.setPixelSize(20)

        self.label1 = QLabel("Ticket Code", self)
        self.label1.setFixedSize(150, 40)
        mid_x1 = (self.width() - self.label1.width()) // 2
        self.label1.move(mid_x1, 10)
        self.label1.setFont(self.font1)
        self.label1.setStyleSheet("""
            QLabel {
                color:  rgba(255, 255, 255, 1);
                border: 1px solid rgba(255, 255, 255, 0.0);
                font-weight: 700;
                }
            """)
        self.label1.setAlignment(Qt.AlignCenter)

        font2 = QFont()
        font2.setLetterSpacing(QFont.AbsoluteSpacing, 1.3)
        font2.setPixelSize(60)

        self.label2 = QLabel("--------", self)
        self.label2.setFixedSize(350, 100)
        mid_x2 = (self.width() - self.label2.width()) // 2
        self.label2.move(mid_x2, 50)
        self.label2.setFont(font2)
        self.label2.setStyleSheet("""
            QLabel {
                color:  rgb(0, 0, 0);
                background: rgba(211, 141, 0, 1);
                border-radius: 10px;
                font-weight: 900;
                }
            """)
        self.label2.setAlignment(Qt.AlignCenter)

        self.label3 = QLabel("Proceed inside for", self)
        self.label3.setFixedSize(220, 40)
        mid_x3 = (self.width() - self.label3.width()) // 2
        self.label3.move(mid_x3, 170)
        self.label3.setFont(self.font1)
        self.label3.setStyleSheet("""
            QLabel {
                color:  rgba(255, 255, 255, 1);
                border: 1px solid rgba(255, 255, 255, 0.0);
                font-weight: 700;
                }
            """)
        self.label3.setAlignment(Qt.AlignCenter)

        font3 = QFont()
        font3.setPixelSize(30)
        font3.setLetterSpacing(QFont.AbsoluteSpacing, 1.3)

        self.label4 = QLabel("##########", self)
        self.label4.setFixedSize(320, 40)
        mid_x4 = (self.width() - self.label4.width()) // 2
        self.label4.move(mid_x4, 200)
        self.label4.setFont(font3)
        self.label4.setStyleSheet("""
            QLabel {
                color:  rgba(211, 141, 0, 1);
                border: 1px solid rgba(255, 255, 255, 0.0);
                font-weight: 700;
                }
            """)
        self.label4.setAlignment(Qt.AlignCenter)
    def setupChartWithData(self):
        """
        Chart gets updated displaying the new data.

        Data has to be expressed on a dictionary form:
            - keys are timestamps
            - values are total balance for that timestamp
        """
        self.chart = QChart()
        self.chart.setTheme(QChart.ChartThemeDark)
        self.chart.setAnimationOptions(QChart.SeriesAnimations)
        self.chart.setBackgroundBrush(QBrush(QColor("transparent")))

        # Series
        self.barseries = QBarSeries()

        currentyear, currentmonth = datetime.today().year, datetime.today(
        ).month
        dates, amounts = [], []
        # Get 5 previous month numbers
        for _ in range(5):
            dates.append((currentmonth, currentyear))
            currentmonth -= 1
            if currentmonth == 0:
                currentmonth = 12
                currentyear -= 1
        # Get amounts for each month
        for d in dates:
            month, year = d
            amounts.append(
                dbhandler.get_total_wealth_on_month(month, year=year))

        # Iterate months and amount and insert them into the histogram appropiately
        barset = QBarSet('Total wealth')
        labelsfont = QFont()
        labelsfont.setFamily('Inter')
        labelsfont.setBold(True)
        barset.setLabelFont(labelsfont)
        barset.setColor(QColor("#D3EABD"))
        x_values = []
        for d, a in zip(reversed(dates), reversed(amounts)):
            if a > 0:
                barset.append(int(a))
                x_values.append(calendar.month_name[d[0]])

        self.barseries.append(barset)
        self.barseries.setName("Last Months")
        self.barseries.setLabelsVisible(True)
        self.barseries.setBarWidth(0.2)
        self.barseries.setLabelsPosition(QAbstractBarSeries.LabelsOutsideEnd)
        self.chart.addSeries(self.barseries)

        # Axis X (Dates)
        self.x_axis = QBarCategoryAxis()
        self.x_axis.setTitleText(self.tr('Date'))
        labelsfont = QFont()
        labelsfont.setFamily('Roboto')
        labelsfont.setLetterSpacing(QFont.AbsoluteSpacing, 1)
        labelsfont.setWeight(QFont.Light)
        labelsfont.setPointSize(9)
        self.x_axis.setLabelsFont(labelsfont)
        self.x_axis.setGridLineVisible(False)
        self.x_axis.setLineVisible(False)
        self.x_axis.setLinePenColor(QColor("#D3EABD"))
        self.x_axis.setTitleVisible(False)

        self.x_axis.append(x_values)
        self.chart.addAxis(self.x_axis, Qt.AlignBottom)

        # Axis Y (Balances)
        self.y_axis = QValueAxis()
        self.y_axis.setMax(max(amounts) * 1.3)
        self.y_axis.setMin(min(amounts) * 0.95)
        self.y_axis.hide()

        labelsfont = QFont()
        labelsfont.setPointSize(4)
        self.y_axis.setLabelsFont(labelsfont)
        self.chart.addAxis(self.y_axis, Qt.AlignLeft)

        # Attach axis to series
        self.barseries.attachAxis(self.x_axis)
        self.barseries.attachAxis(self.y_axis)

        # Legend
        self.chart.legend().hide()

        # Set up chart on ChartView
        self.setChart(self.chart)
        self.setRenderHint(QPainter.Antialiasing)
        self.setStyleSheet("border: 0px; background-color: rgba(0,0,0,0)")
Beispiel #28
0
class HexViewWidget(QTableWidget):
    bytesChanged = pyqtSignal()

    def __init__(self, content=None, max_bytes_per_line=16, width=1,
                 read_only=False, parent=None):
        super(HexViewWidget, self).__init__(parent)
        self.parent = parent
        self._max_bytes_per_line = max_bytes_per_line
        self._bytes_per_line = max_bytes_per_line
        self._width = width
        self._read_only = read_only
        self.setShowGrid(False)
        header = self.horizontalHeader()
        header.setMinimumSectionSize(15)
        header.setDefaultSectionSize(15)
        self.selectionModel().selectionChanged.connect(self.selection_changed)
        self.ascii_font = QFont()
        self.ascii_font.setLetterSpacing(QFont.AbsoluteSpacing, 4)
        self.bold_font = QFont()
        self.bold_font.setBold(True)
        self.current_selection = []
        self.horizontalHeader().setStretchLastSection(True)
        if content:
            self.content = content
        else:
            self.content = bytearray()

    def _reconstruct_table(self):
        try:
            self.itemChanged.disconnect(self._item_changed)
        except:
            pass
        self.clear()
        rows = []
        for i in range(0, len(self._data), self._bytes_per_line):
            rows.append(self._data[i:i+self._bytes_per_line])
        self.setRowCount(len(rows))
        cols = self._bytes_per_line // self._width + 1  # ascii
        self.setColumnCount(cols)
        self._process_headers()
        for y, row in enumerate(rows):
            self._process_row(y, row)
        self.itemChanged.connect(self._item_changed)

    def _process_headers(self):
        cols = self.columnCount()
        self.setColumnWidth(cols - 1, 150)
        self.horizontalHeader().setSectionResizeMode(cols - 1, QHeaderView.Stretch)
        self.setStyleSheet('QTableView::item {padding: 0px 5px 0px 5px;}')
        for i in range(cols - 1):
            self.horizontalHeader().setSectionResizeMode(i, QHeaderView.ResizeToContents)
        header_labels = []
        for i in range(0, self._bytes_per_line, self._width):
            header_labels.append('{:X}'.format(i))
        header_labels.append('ASCII')
        row_labels = []
        for i in range(0, len(self._data), self._bytes_per_line):
            row_labels.append('{:X}'.format(i))
        self.setHorizontalHeaderLabels(header_labels)
        self.setVerticalHeaderLabels(row_labels)

    def _process_row(self, y, row):
        cols = self.columnCount()
        for x, i in enumerate(range(0, len(row), self._width)):
            block = row[i:i+self._width]
            item = QTableWidgetItem(codecs.encode(block, 'hex').decode())
            if block in bytes(string.printable, 'ascii'):
                item.setFont(self.bold_font)
            item.setTextAlignment(Qt.AlignHCenter | Qt.AlignVCenter)
            item.setData(Qt.UserRole, block)  # store original data
            if self._read_only:
                item.setFlags(Qt.ItemIsSelectable | Qt.ItemIsEnabled)
            else:
                item.setFlags(Qt.ItemIsSelectable | Qt.ItemIsEnabled | Qt.ItemIsEditable)
            self.setItem(y, x, item)

        # process remaining, unfilled cells
        for j in range(x+1, cols):
            item = QTableWidgetItem()
            item.setFlags(Qt.NoItemFlags)
            item.setTextAlignment(Qt.AlignHCenter)
            self.setItem(y, j, item)

        text = self._bytes_to_ascii(row)
        item = QTableWidgetItem(text)
        item.setFlags(Qt.NoItemFlags)
        text_widget = QPlainTextEdit()
        # Prevent vertical scrollbars in ASCII view
        def _fix_widget_size():
            if text_widget.verticalScrollBar():
                text_widget.setMinimumWidth(text_widget.width() + 25)
        text_widget.textChanged.connect(_fix_widget_size)
        text_widget.setReadOnly(True)
        text_widget.setFrameStyle(QFrame.NoFrame)
        text_widget.setPlainText(text)
        text_widget.setFont(self.ascii_font)
        text_widget.setLineWrapMode(QPlainTextEdit.NoWrap)
        text_widget.setVerticalScrollBarPolicy(Qt.ScrollBarAlwaysOff)
        self.setColumnWidth(cols - 1, 250)
        if self._read_only:
            item.setFlags(Qt.ItemIsSelectable | Qt.ItemIsEnabled)
        else:
            item.setFlags(Qt.ItemIsSelectable | Qt.ItemIsEnabled | Qt.ItemIsEditable)
        item.setFlags(Qt.NoItemFlags)
        self.setCellWidget(y, cols - 1, text_widget)

    def _bytes_to_ascii(self, data):
        if not isinstance(data, (bytes, bytearray)):
            data = codecs.encode(data, 'utf8')
        allowed = (set(string.printable.encode()) - set(string.whitespace.encode())) | {b' '}
        allowed = [ord(x) if isinstance(x, str) else x for x in allowed]
        return ''.join([chr(c) if c in allowed else '.' for c in data])

    def _item_changed(self, item):
        def reset_hex_text(orig_data):
            text = codecs.encode(orig_data, 'hex').decode()
            item.setText(text)
        col = item.column()
        row = item.row()
        text = item.text()
        orig_data = item.data(Qt.UserRole)
        offset = row * self._bytes_per_line
        if col != self.columnCount() - 1:  # hex part
            text = text.strip()
            fmt = '{{:>0{}}}'.format(self._width * 2)
            text = fmt.format(text)
            if len(text) != self._width * 2:
                reset_hex_text(orig_data)
                return
            offset += col * self._width
            try:
                value = codecs.decode(text, 'hex')
            except ValueError:
                reset_hex_text(orig_data)
                return
        else:  # ascii part
            if len(orig_data) != len(text):
                text = self._bytes_to_ascii(orig_data)
                item.setText(text)
                return
            value = bytearray()
            for a, b in zip(orig_data, text.encode()):
                if b == b'.'[0]:
                    value.append(a)
                else:
                    value.append(b)
        self._data[offset:offset+len(value)] = value
        self.bytesChanged.emit()
        self._reconstruct_table()

    @property
    def width(self):
        return self._width

    @width.setter
    def width(self, val):
        if val not in (1, 2, 2**2, 2**3, 2**4, 2**5, 2**6):
            raise ValueError('Width not power of 2')
        self._width = val
        self._reconstruct_table()

    @property
    def content(self):
        return self._data

    @content.setter
    def content(self, content):
        assert isinstance(content, bytearray), TypeError('bytearray required. Got ' + type(content).__name__)
        self._data = content
        if self._data:
            self._bytes_per_line = min(len(self._data), self._max_bytes_per_line)
        self._reconstruct_table()

    @property
    def bytes_per_line(self):
        return self._bytes_per_line

    @bytes_per_line.setter
    def bytes_per_line(self, val):
        self._max_bytes_per_line = val
        self._bytes_per_line = min(self._max_bytes_per_line, self._bytes_per_line)
        self._reconstruct_table()

    def to_bytes(self):
        return self.content

    @property
    def selected_data(self):
        data = ''
        for i in self.selectedItems():
            data += i.text()
        data = codecs.decode(data, 'hex')
        data = bytearray(data)
        return data

    @property
    def selection_count(self):
        return len(self.selectedItems())

    # TODO: implement synchronization with ASCII field
    def selection_changed(self):
        # Check if items from the previous selection
        # are still selected.
        for sel in self.current_selection:
            _widget = self.item(sel[0], sel[1])
            if not _widget.isSelected() and not _widget in self.selectedItems():
                self.current_selection.remove(sel)
                ascii_widget = self.cellWidget(sel[0], self.columnCount() - 1)
                cursor = ascii_widget.textCursor()
                cursor.select(QTextCursor.Document)
                cursor.setCharFormat(QTextCharFormat())
                cursor.clearSelection()
                ascii_widget.setTextCursor(cursor)
        for i in self.selectedItems():
            if not (i.row(), i.column()) in self.current_selection:
                self.current_selection.append((i.row(), i.column()))
            ascii_widget = self.cellWidget(i.row(), self.columnCount() - 1)
            cursor = ascii_widget.textCursor()
            char_format = QTextCharFormat()
            cursor.select(QTextCursor.Document)
            cursor.mergeCharFormat(char_format)
            cursor.clearSelection()
            char_format.setBackground(QBrush(QColor('darkCyan')))
            cursor.setPosition(i.column())
            cursor.setPosition(i.column() + 1, QTextCursor.KeepAnchor)
            cursor.mergeCharFormat(char_format)
Beispiel #29
0
class CustomBase:
    def __init__(self):
        self.wish_name_font = QFont()
        self.wish_name_font.setFamily("Yu Gothic UI Semibold")
        self.wish_name_font.setPointSize(14)
        self.wish_name_font.setBold(True)
        self.wish_name_font.setWeight(75)
        self.wish_name_font.setLetterSpacing(QFont.AbsoluteSpacing, 2)

        self.wish_fields_font = QFont()
        self.wish_fields_font.setFamily("Yu Gothic UI Light")
        self.wish_fields_font.setPointSize(13)
        self.wish_fields_font.setBold(False)
        self.wish_fields_font.setWeight(50)
        self.wish_fields_font.setLetterSpacing(QFont.AbsoluteSpacing, 1)

        self.buttons_font = QFont()
        self.buttons_font.setFamily("Yu Gothic UI Semibold")
        self.buttons_font.setPointSize(14)
        self.buttons_font.setBold(True)
        self.buttons_font.setWeight(75)
        self.buttons_font.setLetterSpacing(QFont.AbsoluteSpacing, 1)

    def _set_blur(self, value):
        blur = QGraphicsBlurEffect()
        blur.setBlurRadius(value)
        self.setGraphicsEffect(blur)

    blur = pyqtProperty(float, fset=_set_blur)

    def do_blur(self, dur, value):
        self.anim = QPropertyAnimation(self, b'blur')
        self.anim.setDuration(dur)
        self.anim.setStartValue(1)
        self.anim.setEndValue(value)
        self.anim.start()

    def do_unblur(self, dur, value):
        self.anim = QPropertyAnimation(self, b'blur')
        self.anim.setDuration(dur)
        self.anim.setStartValue(value)
        self.anim.setEndValue(1)
        self.anim.start()

    def do_slide_in_animation(self, duration, h):
        self.anim = QPropertyAnimation(self, b'geometry')
        self.anim.setDuration(duration)
        self.anim.setStartValue(
            QRect(self.frameGeometry().left(),
                  self.frameGeometry().top() - h,
                  self.frameGeometry().width(),
                  self.frameGeometry().height()))

        self.anim.setEndValue(
            QRect(self.frameGeometry().left(),
                  self.frameGeometry().top(),
                  self.frameGeometry().width(),
                  self.frameGeometry().height()))
        self.anim.start()

    def do_slide_out_animation(self, duration, h):
        self.anim = QPropertyAnimation(self, b'geometry')
        self.anim.setDuration(duration)
        self.anim.setStartValue(
            QRect(self.frameGeometry().left(),
                  self.frameGeometry().top(),
                  self.frameGeometry().width(),
                  self.frameGeometry().height()))

        self.anim.setEndValue(
            QRect(self.frameGeometry().left(),
                  self.frameGeometry().top() + h,
                  self.frameGeometry().width(),
                  self.frameGeometry().height()))
        self.anim.start()