Example #1
0
class ImageLabel(QtWidgets.QLabel):
    ResizeSignal = QtCore.Signal(int)

    def __init__(self, parent):
        super(ImageLabel, self).__init__(parent)
        self.setSizePolicy(QtWidgets.QSizePolicy.Ignored,
                           QtWidgets.QSizePolicy.Ignored)
        self.setText("")
        self.pix = QPixmap()
        self.setPixmap(self.pix)
        self.ResizeSignal.connect(self.resizeEvent)
        self.installEventFilter(self)

    def eventFilter(self, watched: QtCore.QObject,
                    event: QtCore.QEvent) -> bool:
        if (event.type() == QtCore.QEvent.Resize):
            if not self.pix.isNull():
                pixmap = self.pix.scaled(
                    self.width(), self.height(),
                    QtCore.Qt.AspectRatioMode.KeepAspectRatio,
                    QtCore.Qt.TransformationMode.SmoothTransformation)
                if pixmap.width() != self.width() or pixmap.height(
                ) != self.height():
                    self.ResizeSignal.emit(0)
        return super().eventFilter(watched, event)

    def resizeEvent(self, _):
        if not self.pix.isNull():
            size = self.size()
            self.setPixmap(
                self.pix.scaled(
                    size, QtCore.Qt.AspectRatioMode.KeepAspectRatio,
                    QtCore.Qt.TransformationMode.SmoothTransformation))

    #Paint event that is currently not needed
    # def paintEvent(self, event):
    #     if not self.pix.isNull():
    #         size = self.size()
    #         painter = QPainter()
    #         point = QtCore.QPoint(0, 0)
    #         scaledPix = self.setPixmap(self.pix.scaled(size, QtCore.Qt.AspectRatioMode.KeepAspectRatio, QtCore.Qt.TransformationMode.SmoothTransformation))
    #         point.setX((size.width() - scaledPix.width() / 2))
    #         point.setY((size.height() - scaledPix.height() / 2))
    #         painter.drawPixmap(point, scaledPix)

    def changePixmap(self, img):
        self.pix = img
        self.repaint()
        self.ResizeSignal.emit(1)

    def clearPixmap(self):
        self.pix = QPixmap()
        self.setPixmap(self.pix)
        self.repaint()
Example #2
0
    def paint(self, painter, option, index):
        super(Delegate, self).paint(painter, option, index)

        # HOVER
        if option.state & QStyle.State_MouseOver:
            painter.fillRect(option.rect, QColor("#F1F1F1"))
        else:
            painter.fillRect(option.rect, Qt.transparent)

        # SELECTED
        if option.state & QStyle.State_Selected:
            painter.fillRect(option.rect, QColor("#F1F1F1"))

        # DRAW ICON
        icon = QPixmap()
        icon.load(index.data()[1])
        icon = icon.scaled(24, 24, Qt.IgnoreAspectRatio,
                           Qt.SmoothTransformation)

        left = 24  # margin left
        icon_pos = QRect(left, ((self._height - icon.height()) / 2) +
                         option.rect.y(), icon.width(), icon.height())
        painter.setRenderHint(QPainter.Antialiasing)
        painter.setRenderHint(QPainter.SmoothPixmapTransform)
        painter.drawPixmap(icon_pos, icon)

        # DRAW TEXT
        font = QFont("Roboto Black", 12)
        text_pos = QRect((left * 2) + icon.width(), option.rect.y(),
                         option.rect.width(), option.rect.height())
        painter.setFont(font)
        painter.setPen(Qt.black)
        painter.drawText(text_pos, Qt.AlignVCenter, index.data()[0])
Example #3
0
    def PreviewWindow(self):

        self.statusBar().showMessage('Tablecloth preview generated.')
        self.statusBar().removeWidget(self.progress_bar)
        # Now you can go back to rigging
        self.ChangeAppStatus(True)

        self.preview_wid = QWidget()
        self.preview_wid.resize(600, 600)
        self.preview_wid.setWindowTitle("Tablecloth preview")

        tablecloth = QPixmap(tempfile.gettempdir()+"\\Table_Dif.jpg")

        tablecloth_preview_title = QLabel(self)
        tablecloth_preview_title.setText("Tablecloth preview (1/4 scale)")
        tablecloth_preview = QLabel(self)
        tablecloth_preview.setPixmap(tablecloth.scaled(512,512))
        confirm = QPushButton(self)
        confirm.setText("Confirm")
        confirm.clicked.connect(self.GenerateImage)
        confirm.clicked.connect(self.preview_wid.close)

        vbox = QVBoxLayout()
        vbox.setAlignment(QtCore.Qt.AlignCenter)
        vbox.addWidget(tablecloth_preview_title)
        vbox.addWidget(tablecloth_preview)
        vbox.addWidget(confirm)
        self.preview_wid.setLayout(vbox)

        self.preview_wid.setWindowModality(QtCore.Qt.ApplicationModal)
        self.preview_wid.activateWindow()
        self.preview_wid.raise_()
        self.preview_wid.show()
Example #4
0
    def update(self):
        for i, fact in enumerate(self.game.factories):
            img = QPixmap('pictures/factory1.png')
            self.money[i].setText(str(fact.money))
            if i == self.game.cur_factory:
                self.money[i].setFont(QFont('Times', 24, QFont.Bold))
                img = img.scaled(280, 280, QtCore.Qt.KeepAspectRatio)
            else:
                self.money[i].setFont(QFont('Times', 14))
                img = img.scaled(200, 200, QtCore.Qt.KeepAspectRatio)

            self.pictures[i].setPixmap(img)

        self.level.setText(f'Уровень: {self.game.cur_level}')
        self.river.setText(
            f'Процент загрязнения реки: {self.game.river.mud_level}%')
Example #5
0
    def paintEvent(self, event):
        super(Profile, self).paintEvent(event)

        # DRAW BACKGROUND IMAGE
        p = QPainter(self)
        p.setRenderHint(QPainter.Antialiasing)

        image = QPixmap()
        image.load("res/img/back.jpg")
        image = image.scaled(self.width(), self.height(), Qt.IgnoreAspectRatio,
                             Qt.SmoothTransformation)
        p.drawPixmap(self.rect(), image)
Example #6
0
 def __chose_image(self):
     dir = os.getcwd()
     path = QFileDialog.getOpenFileName(
         self, 'Open Image', dir, "Image Files (*.png *.jpg *.bmp *.jpeg)")
     if path[0] != '':
         self.image = path[0].split(
             '/')[-1] if path[0] != '' else self.image
         im = cv2.imread(self.image, 0)
         ret, trash = cv2.threshold(im, 240, 255, cv2.THRESH_BINARY)
         self.image_bw = self.image.split('.')[0] + '_binary.jpg'
         cv2.imwrite(self.image_bw, trash)
         image = QPixmap(self.image_bw)
         new_image = image.scaled(540, 249, Qt.KeepAspectRatio,
                                  Qt.FastTransformation)
         self.put_image(widget=self.ui.sourceLabel, image=new_image)
Example #7
0
 def browser(self):
     """Slot function to initialize image thumbnails for the
     'browse mode.'"""
     while self.h_box2.itemAt(0):
         self.h_box2.takeAt(0).widget().deleteLater()
     index = (self.index + (len(self.files) - 2)) % len(self.files)
     for i, file in enumerate(self.files):
         file = self.dir_now + '/' + self.files[index]
         label = ClickableLabel(self, file)
         self.h_box2.addWidget(label)
         pix = QPixmap(file)
         if (pix.size().width() > self.browse_bar.width() / 5
                 or pix.size().height() > 100):
             pix = pix.scaled(self.browse_bar.width() / 5, 100,
                              Qt.KeepAspectRatio)
         label.setPixmap(pix)
         index = (index + 1) % len(self.files)
         if i == 4:
             break
Example #8
0
    def paintAvatar(self):
        # DRAW PROFILE IMAGE
        image = QPixmap()
        image.load("res/img/icons/user.png")
        image = image.scaled(54, 54, Qt.IgnoreAspectRatio,
                             Qt.SmoothTransformation)

        _margin = 16
        _margin_text = 24

        self.avatar = QLabel(self)
        self.avatar.setCursor(Qt.PointingHandCursor)
        self.avatar.setAttribute(Qt.WA_TranslucentBackground)
        self.avatar.setPixmap(image)
        self.avatar.move(self.rect().x() + _margin, self.rect().y() + _margin)

        self.username = QLabel(self)
        self.username.setStyleSheet("color: white;")
        self.username.setFont(QFont("Roboto Light", 14))
        self.username.setCursor(Qt.PointingHandCursor)
        self.username.setAttribute(Qt.WA_TranslucentBackground)
        self.username.setText("dryerem19")
        self.username.move(self.rect().x() + _margin_text, self.height() - 50)
Example #9
0
def generate_pixmap_from_temp(width, height, ext) -> QPixmap:
    pixmap = QPixmap(f'{settings.TEMP_DIR}/{ext}')
    pixmap = pixmap.scaled(calculate_image_width(width),
                           calculate_image_height(height),
                           aspectMode=Qt.KeepAspectRatio)
    return pixmap
 def scale_pixmap(pixmap: QPixmap, width: int, height: int):
     scaled_pixmap = pixmap.scaled(width, height, Qt.KeepAspectRatio,
                                   Qt.SmoothTransformation)
     return scaled_pixmap
Example #11
0
    def __init__(self, game):
        super().__init__()

        self.game = game
        self.level = QLabel(f'Уровень: {self.game.cur_level}')
        self.river = QLabel(
            f'Процент загрязнения реки: {self.game.river.mud_level}%')
        self.level.setFont(QFont('Times', 28))
        self.river.setFont(QFont('Times', 24))

        self.money = []
        self.pictures = []
        for i, fact in enumerate(game.factories):
            label = QLabel()
            img = QPixmap('pictures/factory1.png')

            self.money.append(QLabel(str(fact.money)))
            if i == self.game.cur_factory:
                self.money[i].setFont(QFont('Times', 24, QFont.Bold))
                img = img.scaled(280, 280, QtCore.Qt.KeepAspectRatio)
            else:
                self.money[i].setFont(QFont('Times', 14))
                img = img.scaled(200, 200, QtCore.Qt.KeepAspectRatio)

            label.setPixmap(img)
            self.pictures.append(label)

        self.button_work = QPushButton('Работать')
        self.button_work_and_clean = QPushButton('Работать и очистить реку')
        self.button_do_nothing = QPushButton('Простаивать')

        self.main_layout = QtWidgets.QVBoxLayout(self)
        self.main_layout.addWidget(self.level)
        self.main_layout.addWidget(self.river)

        self.factories_layout = QtWidgets.QHBoxLayout()
        for picture in self.pictures:
            self.factories_layout.addWidget(picture)
            picture.setAlignment(QtCore.Qt.AlignCenter)

        self.money_layout = QtWidgets.QHBoxLayout()
        for money in self.money:
            self.money_layout.addWidget(money)
            money.setAlignment(QtCore.Qt.AlignCenter)

        self.main_layout.addLayout(self.factories_layout)
        self.main_layout.addLayout(self.money_layout)
        self.main_layout.addWidget(self.button_work)
        self.main_layout.addWidget(self.button_work_and_clean)
        self.main_layout.addWidget(self.button_do_nothing)

        self.button_work_and_clean.clicked.connect(self.work_and_clean)
        self.button_work.clicked.connect(self.work)
        self.button_do_nothing.clicked.connect(self.do_nothing)

        with open('style.css') as f:
            style = f.read()
            self.level.setStyleSheet(style)
            self.button_work.setStyleSheet(style)
            self.button_work_and_clean.setStyleSheet(style)
            self.button_do_nothing.setStyleSheet(style)
Example #12
0
    def draw_grid(self,
                  art: QPixmap,
                  painter: typing.Optional[QPainter] = None):
        rows = self.rows
        columns = self.cols
        if self.row_clues:
            x_filled_portion = 0.97 * rows / (rows + 1)
            y_filled_portion = 0.97 * columns / (columns + 1)
            scaled_art = art.scaled(self.rect.width() * x_filled_portion,
                                    self.rect.height() * y_filled_portion,
                                    Qt.AspectRatioMode.KeepAspectRatio)
        else:
            filled_portion = 0.84
            scaled_art = art.scaled(self.rect.width() * filled_portion,
                                    self.rect.height() * filled_portion,
                                    Qt.AspectRatioMode.KeepAspectRatio)
        cell_height = scaled_art.height() / rows
        cell_width = scaled_art.width() / columns
        if self.row_clues:
            left_clue_border = round(
                (self.rect.width() - scaled_art.width() - cell_width) / 3)
            top_clue_border = round(
                (self.rect.height() - scaled_art.height() - cell_height) / 3)
            min_border = min(left_clue_border, top_clue_border)
            left_clue_border = round((3 * left_clue_border - min_border) / 2)
            top_clue_border = round((3 * top_clue_border - min_border) / 2)
            left_border = left_clue_border + cell_width + min_border
            top_border = top_clue_border + cell_height + min_border
        else:
            left_border = int((self.rect.width() - scaled_art.width()) / 2)
            top_border = int((self.rect.height() - scaled_art.height()) / 2)
            left_clue_border = top_clue_border = None
        if painter is None:
            painter = QPainter(self.target)
        if self.background:
            painter.fillRect(self.rect, self.background)
        painter.translate(0, self.rect.top())
        if not self.row_clues:
            self.draw_letters(cell_width, cell_height, left_border, top_border,
                              painter)
        is_grid_filled = (self.selected_row is not None
                          or self.selected_column is not None)
        self.row_clue_rects.clear()
        for i, clue in enumerate(self.row_clues):
            clue_rect = QRect(left_clue_border,
                              round(top_border + i * cell_height),
                              round(cell_width), round(cell_height))
            self.row_clue_rects.append(clue_rect)
            painter.drawPixmap(clue_rect, clue)
            if is_grid_filled:
                for j in range(self.cols):
                    painter.drawPixmap(round(left_border + j * cell_width),
                                       round(top_border + i * cell_height),
                                       round(cell_width), round(cell_height),
                                       clue)
        self.column_clue_rects.clear()
        for j, clue in enumerate(self.column_clues):
            clue_rect = QRect(round(left_border + j * cell_width),
                              top_clue_border, round(cell_width),
                              round(cell_height))
            self.column_clue_rects.append(clue_rect)
            painter.drawPixmap(clue_rect, clue)
            if is_grid_filled:
                for i in range(self.rows):
                    y = round(top_border + i * cell_height)
                    painter.drawPixmap(round(left_border + j * cell_width), y,
                                       round(cell_width), round(cell_height),
                                       clue)
        if is_grid_filled:
            painter.drawPixmap(left_border, top_border,
                               round(self.cols * cell_width),
                               round(self.rows * cell_height), scaled_art)
        painter.setPen(QPen(QColor('lightgrey'), round(cell_width / 50)))
        if self.row_clues:
            painter.drawRect(left_clue_border, top_border, round(cell_width),
                             round(cell_height * rows))
            painter.drawRect(left_border, top_clue_border,
                             round(cell_width * columns), round(cell_height))
        painter.drawRect(left_border, top_border, round(cell_width * columns),
                         round(cell_height * rows))
        for i in range(1, rows):
            y = round(top_border + i * cell_height)
            painter.drawLine(left_border, y,
                             round(left_border + cell_width * columns), y)
            if self.row_clues:
                painter.drawLine(left_clue_border, y,
                                 round(left_clue_border + cell_width), y)
        for j in range(1, columns):
            x = round(left_border + j * cell_width)
            painter.drawLine(x, top_border, x,
                             round(top_border + cell_height * rows))
            if self.row_clues:
                painter.drawLine(x, top_clue_border, x,
                                 round(top_clue_border + cell_height))

        painter.setPen(QPen(QColor('blue'), round(cell_width / 25)))
        if self.selected_row is not None:
            painter.drawRect(
                left_clue_border,
                round(top_border + cell_height * self.selected_row),
                round(cell_width), round(cell_height))
        if self.selected_column is not None:
            painter.drawRect(
                round(left_border + cell_width * self.selected_column),
                top_clue_border, round(cell_width), round(cell_height))
        painter.translate(0, -self.rect.top())
Example #13
0
class ItemInfoBox(QWidget):
    def __init__(self, item: Item):
        super().__init__()
        layout = QGridLayout(self)

        meta = item.meta

        # infobox spans one row and two columns.
        SPAN = (1, 2)

        # wikipedia-style info box at the side
        title = TitleLabel(f"<h2><i>{meta.title}</i></h2>")
        layout.addWidget(title, 0, 0, *SPAN)

        self.cover = QPixmap()

        try:
            manga_path = CACHE.root / meta.hash
            cover_path = next(manga_path.glob("cover.*"))

        except StopIteration:
            self.cover.load(":/missing.jpg")

        else:
            self.cover.load(str(cover_path))

        self.cover = self.cover.scaled(
            int(self.width() / 2),
            self.height(),
            Qt.KeepAspectRatio,
            Qt.SmoothTransformation,
        )

        self.cover_label = QLabel()
        self.cover_label.setScaledContents(True)
        self.cover_label.setPixmap(self.cover)

        layout.addWidget(self.cover_label, 1, 0, *SPAN)

        if meta.alt_titles is not None:
            _alt_titles = "<br>".join(f"<i>{t}</i>" if _is_ascii(t) else t
                                      for t in meta.alt_titles)

        else:
            _alt_titles = "(empty)"

        alt_titles = TitleLabel(_alt_titles)
        alt_titles.setStyleSheet("background-color: #DDDDFF; color: black;")
        layout.addWidget(alt_titles, 2, 0, *SPAN)

        genre_header = SubtitleLabel("Genre")
        layout.addWidget(genre_header, 3, 0)

        if meta.genres is not None:
            _genres = "<br>".join(_normalize(g) for g in meta.genres)

        else:
            _genres = "(empty)"

        genres = QLabel(_genres)
        layout.addWidget(genres, 3, 1)

        manga_header = TitleLabel("<b>Manga</b>")
        layout.addWidget(manga_header, 4, 0, *SPAN)

        author_header = SubtitleLabel("Authored by")
        layout.addWidget(author_header, 5, 0)

        if meta.authors is not None:
            _authors = "<br>".join(a for a in meta.authors)

        else:
            _authors = "(empty)"

        authors = QLabel(_authors)
        layout.addWidget(authors, 5, 1)

        source_header = SubtitleLabel("Source")
        layout.addWidget(source_header, 6, 0)

        source = QLabel(f'<a href="{meta.url}">{meta.url}</b>')
        source.setWordWrap(True)
        source.setOpenExternalLinks(True)
        layout.addWidget(source, 6, 1)

        langs_header = SubtitleLabel("Languages")
        layout.addWidget(langs_header, 7, 0)

        manga = CACHE[meta.hash]
        langs_set = set()

        for chapter in manga["chapters"].values():
            langs_set.update(chapter.keys())

        langs = QLabel("<br>".join(common.describe_langs(list(langs_set))))
        layout.addWidget(langs, 7, 1)
def test_board_size_2(pixmap_differ: PixmapDiffer):
    actual: QPainter
    expected: QPainter
    with pixmap_differ.create_painters(240, 240,
                                       'margo_board_size_2') as (actual,
                                                                 expected):
        expected_scene = QGraphicsScene(0, 0, 240, 240)
        full_board = MargoDisplay.load_pixmap('board-1.png')
        width = full_board.width()
        height = full_board.height()
        top_height = round(height * 0.28)
        left_width = round(width * 0.28)
        right_width = round(width * 0.279)
        bottom_height = round(height * 0.29)
        assembled_board = QPixmap(left_width + right_width,
                                  top_height + bottom_height)
        assembled_board.fill(Qt.transparent)
        assembled_painter = QPainter(assembled_board)
        # top left
        assembled_painter.drawPixmap(0, 0, left_width, top_height, full_board,
                                     0, 0, left_width, top_height)
        # top right
        assembled_painter.drawPixmap(left_width, 0, right_width, top_height,
                                     full_board, width - right_width, 0,
                                     right_width, top_height)
        # bottom left
        assembled_painter.drawPixmap(0, top_height, left_width, bottom_height,
                                     full_board, 0, height - bottom_height,
                                     left_width, bottom_height)
        # bottom right
        assembled_painter.drawPixmap(left_width, top_height, right_width,
                                     bottom_height, full_board,
                                     width - right_width,
                                     height - bottom_height, right_width,
                                     bottom_height)
        assembled_painter.end()
        scaled_board = assembled_board.scaled(232, 240, Qt.KeepAspectRatio,
                                              Qt.SmoothTransformation)
        board_item = expected_scene.addPixmap(scaled_board)
        board_item.setPos(4, 0)
        white_ball = MargoDisplay.load_pixmap('ball-w-shadow-1.png',
                                              QSize(103, 103))
        black_ball = MargoDisplay.load_pixmap('ball-b-shadow-1.png',
                                              QSize(103, 103))

        expected_scene.addPixmap(white_ball).setPos(23, 108)
        expected_scene.addPixmap(black_ball).setPos(113, 18)
        expected_scene.render(expected)

        display = MargoDisplay(size=2)

        trigger_resize(display, 292, 240)
        display.resize(348, 264)
        board_text = """\
  A C
3 . B 3

1 W . 1
  A C
>B
"""
        display.update_board(SpargoState(board_text, size=2))

        render_display(display, actual)
Example #15
0
    def __init__(self):
        super().__init__()

        # Declare Widgets
        self.homepage_label = QLabel('Home')
        self.search_label = QLabel('Find an Image!')
        self.srch_box = QLineEdit()  # input field for search
        self.srch_btn = QPushButton("Search")

        # Create U.I. Layout
        mbox = QVBoxLayout()  # Main layout

        vbox = QVBoxLayout()  # Layout for search feature
        vbox.addWidget(self.homepage_label)
        vbox.addWidget(self.search_label)
        vbox.addWidget(self.srch_box)
        vbox.addWidget(self.srch_btn)

        gbox1 = QGroupBox()  # Set group for search feature layout
        gbox1.setLayout(vbox)
        mbox.addWidget(gbox1)

        # Home Images
        images = []
        images = self.getHomepageImages()

        # Create layout for images
        vbox2 = QHBoxLayout()  # horizontal layout

        i = 0
        for img in images:  # iterate through images list
            self.label = QLabel()

            pixmap1 = QPixmap(img)  # set image
            pixmap1 = pixmap1.scaled(300, 300, Qt.KeepAspectRatio)

            self.label.setPixmap(pixmap1)

            temp_vbox = QVBoxLayout()
            temp_vbox.addWidget(self.label)

            gbox2 = QGroupBox()  # group box for current image
            gbox2.setLayout(temp_vbox)
            gbox2.setStyleSheet("background-color: grey")

            vbox2.addWidget(gbox2)
            i += 1

        gbox3 = QGroupBox()  # main group box for images
        gbox3.setLayout(vbox2)
        mbox.addWidget(gbox3)
        self.setLayout(mbox)

        # Styling
        self.setStyleSheet("""
            color: orange;
            font-family: Comfortaa;
            """)
        self.srch_btn.setStyleSheet(":hover { background-color:cyan }")
        gbox1.setStyleSheet("""
            font-size: 18px
            """)

        # Listeners
        self.srch_btn.clicked.connect(self.find_images)
Example #16
0
class MainWindow(QMainWindow):
    def __init__(self):
        super(MainWindow, self).__init__()
        self.ui = Ui_MainWindow()
        self.ui.setupUi(self)
        self.art_scene = QGraphicsScene(self)
        self.art_scene.addText('Open an image file.')
        self.ui.art_view.setScene(self.art_scene)
        self.symbols_scene = QGraphicsScene(self)
        self.ui.symbols_view.setScene(self.symbols_scene)
        self.ui.action_exit.triggered.connect(self.close)
        self.ui.action_open_art.triggered.connect(self.open_image)
        self.ui.action_open_words.triggered.connect(self.open_words)
        self.ui.action_save.triggered.connect(self.save_pdf)
        self.ui.action_save_png.triggered.connect(self.save_png)
        self.ui.action_shuffle.triggered.connect(self.shuffle)
        self.ui.action_sort.triggered.connect(self.sort)
        self.ui.rows.valueChanged.connect(self.on_options_changed)
        self.ui.columns.valueChanged.connect(self.on_options_changed)
        self.ui.word_clues_radio.toggled.connect(self.on_options_changed)
        self.ui.symbol_clues_radio.toggled.connect(self.on_options_changed)

        self.word_layout = QGridLayout(self.ui.word_content)
        self.ui.word_scroll.setWidgetResizable(True)
        self.word_labels: typing.Dict[str, QLabel] = {}
        self.word_shuffler = WordShuffler([])

        self.clues = None

        self.pixmap = self.scaled_pixmap = self.mini_pixmap = None
        self.sliced_pixmap_item: typing.Optional[QGraphicsPixmapItem] = None
        self.sliced_image: typing.Optional[QImage] = None
        self.selection_grid: typing.Optional[SelectionGrid] = None
        self.cells = []
        self.art_shuffler: typing.Optional[ArtShuffler] = None
        self.symbols_source_pixmap_item: typing.Optional[
            QGraphicsPixmapItem] = None
        self.symbols_pixmap_item: typing.Optional[QGraphicsPixmapItem] = None
        self.symbols_image: typing.Optional[QImage] = None
        self.symbols_shuffler: typing.Optional[ArtShuffler] = None
        self.selected_row: typing.Optional[int] = None
        self.selected_column: typing.Optional[int] = None
        self.settings = QSettings()
        self.image_path: typing.Optional[str] = self.settings.value(
            'image_path')
        self.words_path: typing.Optional[str] = self.settings.value(
            'words_path')

        self.dirty_letters = set()
        self.timer = QTimer()
        self.timer.setInterval(500)
        self.timer.setSingleShot(True)
        # noinspection PyUnresolvedReferences
        self.timer.timeout.connect(self.on_dirty)

        self.row_count = self.column_count = 0
        self.clue_type = ClueType.words
        self.ui.rows.setValue(self.settings.value('row_count', 6, int))
        self.ui.columns.setValue(self.settings.value('column_count', 4, int))
        clue_type_name = self.settings.value('clue_type', ClueType.words.name)
        try:
            clue_type = ClueType[clue_type_name]
        except KeyError:
            clue_type = ClueType.words
        if clue_type == ClueType.words:
            self.ui.word_clues_radio.setChecked(True)
        else:
            self.ui.symbol_clues_radio.setChecked(True)
        self.row_clues: typing.List[QPixmap] = []
        self.column_clues: typing.List[QPixmap] = []
        self.on_options_changed()

    def on_dirty(self):
        for letter in self.dirty_letters:
            self.word_labels[letter].setText(
                self.word_shuffler.make_display(letter))
            self.settings.setValue(f'word_{letter}',
                                   self.word_shuffler[letter])
        if self.dirty_letters:
            self.clues = self.word_shuffler.make_clues()
            self.art_shuffler.clues = dict(self.clues)
            self.dirty_letters.clear()
            self.on_selection_moved()

        if self.pixmap is not None:
            x, y, width, height = self.get_selected_fraction()
            self.settings.setValue('x', x)
            self.settings.setValue('y', y)
            self.settings.setValue('width', width)
            self.settings.setValue('height', height)

        new_rows = self.ui.rows.value()
        new_columns = self.ui.columns.value()
        if self.ui.word_clues_radio.isChecked():
            new_clue_type = ClueType.words
        else:
            new_clue_type = ClueType.symbols
        if (new_rows, new_columns,
                new_clue_type) == (self.row_count, self.column_count,
                                   self.clue_type):
            return
        self.settings.setValue('row_count', new_rows)
        self.settings.setValue('column_count', new_columns)
        self.settings.setValue('clue_type', new_clue_type.name)
        self.row_count, self.column_count = new_rows, new_columns
        self.clue_type = new_clue_type

        word_count = (self.row_count * self.column_count)
        while self.word_layout.count():
            layout_item = self.word_layout.takeAt(0)
            layout_item.widget().deleteLater()
        self.word_labels.clear()

        self.row_clues.clear()
        self.column_clues.clear()
        if self.image_path is not None:
            self.load_image(self.image_path)

        if self.words_path is not None:
            self.load_words(self.words_path)

        letters = [chr(65 + i) for i in range(word_count)]
        if self.word_shuffler.needs_blank:
            letters.insert(0, '')
        word_fields = {}
        for i, letter in enumerate(letters):
            word_field = QLineEdit()
            self.word_layout.addWidget(word_field, i, 0)
            # noinspection PyUnresolvedReferences
            word_field.textEdited.connect(partial(self.on_word_edited, letter))

            word_label = QLabel()
            self.word_layout.addWidget(word_label, i, 1)
            self.word_labels[letter] = word_label
            word_fields[letter] = word_field
        for i, letter in enumerate(letters):
            word = self.settings.value(f'word_{letter}', '')
            self.word_shuffler[letter] = word
            self.dirty_letters.add(letter)
            word_fields[letter].setText(word)

    def on_options_changed(self, *_):
        self.timer.start()

    def shuffle(self):
        self.clues = self.word_shuffler.make_clues()
        if self.art_shuffler is not None:
            self.art_shuffler.shuffle()
            self.on_selection_moved()

    def sort(self):
        if self.art_shuffler is not None:
            self.art_shuffler.sort()
            self.on_selection_moved()

    def open_words(self):
        word_filter = 'Text files (*.txt)'
        if self.words_path is None:
            words_folder = None
        else:
            words_folder = str(Path(self.words_path).parent)
        file_name, _ = QFileDialog.getOpenFileName(self,
                                                   "Open a words file.",
                                                   dir=words_folder,
                                                   filter=word_filter)
        if not file_name:
            return
        self.settings.setValue('words_path', file_name)
        self.load_words(file_name)

    def load_words(self, words_path):
        with open(words_path) as f:
            choice = 0
            if choice == 0:
                self.word_shuffler = WordShuffler(f)
            else:
                self.word_shuffler = WordStripper(f)

    def open_image(self):
        formats = QImageReader.supportedImageFormats()
        patterns = (f'*.{fmt.data().decode()}' for fmt in formats)
        image_filter = f'Images ({" ".join(patterns)})'
        if self.image_path is None:
            image_folder = None
        else:
            image_folder = str(Path(self.image_path).parent)
        file_name, _ = QFileDialog.getOpenFileName(self,
                                                   "Open an image file.",
                                                   dir=image_folder,
                                                   filter=image_filter)
        if not file_name:
            return
        self.settings.setValue('image_path', file_name)
        self.load_image(file_name)

    def load_image(self, image_path):
        self.pixmap = QPixmap(image_path)
        if self.pixmap.isNull():
            self.pixmap = None
        self.image_path = image_path
        self.scale_image()

    def scale_image(self):
        if self.pixmap is None:
            return

        if self.selection_grid is None:
            x = self.settings.value('x', 0.0, float)
            y = self.settings.value('y', 0.0, float)
            width = self.settings.value('width', 1.0, float)
            height = self.settings.value('height', 1.0, float)
        else:
            x, y, width, height = self.get_selected_fraction()
        self.art_scene.clear()
        self.cells.clear()
        view_size = self.ui.art_view.maximumViewportSize()
        if view_size.width() == 0:
            return
        self.art_scene.setSceneRect(0, 0, view_size.width(),
                                    view_size.height())
        display_size = QSize(view_size.width() * 0.99 / 2,
                             view_size.height() * 0.99)
        self.scaled_pixmap = self.pixmap.scaled(
            display_size, aspectMode=Qt.AspectRatioMode.KeepAspectRatio)
        self.art_scene.addPixmap(self.scaled_pixmap)
        scaled_size = self.scaled_pixmap.size()
        self.selection_grid = SelectionGrid(scaled_size.width() * x,
                                            scaled_size.height() * y,
                                            scaled_size.width() * width,
                                            scaled_size.height() * height,
                                            row_count=self.row_count,
                                            column_count=self.column_count)
        self.selection_grid.on_moved = self.on_selection_moved
        self.art_scene.addItem(self.selection_grid)
        self.sliced_image = QImage(display_size,
                                   QImage.Format.Format_ARGB32_Premultiplied)
        self.check_clues()
        self.art_shuffler = ArtShuffler(self.selection_grid.row_count,
                                        self.selection_grid.column_count,
                                        self.sliced_image,
                                        QRect(0, 0, display_size.width(),
                                              display_size.height()),
                                        clues=self.clues,
                                        row_clues=self.row_clues,
                                        column_clues=self.column_clues)
        self.sliced_pixmap_item = self.art_scene.addPixmap(
            QPixmap.fromImage(self.sliced_image))
        self.sliced_pixmap_item.setPos(display_size.width(), 0)

        self.symbols_scene.clear()
        self.symbols_source_pixmap_item = self.symbols_scene.addPixmap(
            self.scaled_pixmap)
        self.symbols_image = QImage(display_size,
                                    QImage.Format.Format_ARGB32_Premultiplied)
        if self.symbols_shuffler is not None:
            selected_row = self.symbols_shuffler.selected_row
            selected_column = self.symbols_shuffler.selected_column
        else:
            selected_row = 0
            selected_column = None
        self.symbols_shuffler = ArtShuffler(self.selection_grid.row_count,
                                            self.selection_grid.column_count,
                                            self.symbols_image,
                                            QRect(0, 0, display_size.width(),
                                                  display_size.height()),
                                            row_clues=self.row_clues,
                                            column_clues=self.column_clues)
        self.symbols_shuffler.selected_row = selected_row
        self.symbols_shuffler.selected_column = selected_column
        self.symbols_pixmap_item = ClickablePixmapItem(
            QPixmap.fromImage(self.symbols_image))
        self.symbols_pixmap_item.on_click = self.on_symbols_clicked
        self.symbols_scene.addItem(self.symbols_pixmap_item)

        self.symbols_pixmap_item.setPos(display_size.width(), 0)

        self.on_selection_moved()

    def on_symbols_clicked(self, event: QGraphicsSceneMouseEvent):
        self.symbols_scene.clearSelection()
        self.symbols_shuffler.select_clue(event.pos().toPoint())
        self.on_selection_moved()

    def on_word_edited(self, letter, word):
        self.word_shuffler[letter] = word
        self.dirty_letters.add(letter)
        self.timer.start()

    def get_selected_fraction(self):
        selection_rect = self.selection_grid.rect()
        selection_pos = self.selection_grid.pos()
        size = self.scaled_pixmap.size()
        x = (selection_pos.x() + selection_rect.x()) / size.width()
        width = selection_rect.width() / size.width()
        y = (selection_pos.y() + selection_rect.y()) / size.height()
        height = selection_rect.height() / size.height()
        return x, y, width, height

    def on_selection_moved(self):
        selected_pixmap = self.get_selected_pixmap()
        self.art_shuffler.draw(selected_pixmap)
        self.sliced_pixmap_item.setPixmap(QPixmap.fromImage(self.sliced_image))

        selected_pixmap = self.get_selected_pixmap()
        cell_width = (selected_pixmap.width() /
                      self.selection_grid.column_count)
        cell_height = (selected_pixmap.height() /
                       self.selection_grid.row_count)
        self.row_clues.clear()
        self.column_clues.clear()
        for i in range(self.selection_grid.row_count):
            clue_image = selected_pixmap.copy(0, i * cell_height, cell_width,
                                              cell_height)
            self.row_clues.append(clue_image)
        for j in range(self.selection_grid.column_count):
            clue_image = selected_pixmap.copy(j * cell_width, 0, cell_width,
                                              cell_height)
            self.column_clues.append(clue_image)
        self.symbols_shuffler.row_clues = self.row_clues
        self.symbols_shuffler.column_clues = self.column_clues

        self.symbols_shuffler.draw_grid(selected_pixmap)
        self.symbols_pixmap_item.setPixmap(
            QPixmap.fromImage(self.symbols_image))
        self.timer.start()

    def get_selected_pixmap(self) -> QPixmap:
        x, y, width, height = self.get_selected_fraction()
        original_size = self.pixmap.size()
        selected_pixmap = self.pixmap.copy(x * original_size.width(),
                                           y * original_size.height(),
                                           width * original_size.width(),
                                           height * original_size.height())
        return selected_pixmap

    def resizeEvent(self, event: QResizeEvent):
        super().resizeEvent(event)
        self.scale_image()

    def save_pdf(self):
        pdf_folder = self.settings.value('pdf_folder')
        file_name, _ = QFileDialog.getSaveFileName(self,
                                                   "Save a PDF file.",
                                                   dir=pdf_folder,
                                                   filter='Documents (*.pdf)')
        if not file_name:
            return
        self.settings.setValue('pdf_folder', os.path.dirname(file_name))
        writer = QPdfWriter(file_name)
        writer.setPageSize(QPageSize(QPageSize.Letter))
        writer.setTitle('Sliced Art Puzzle')
        writer.setCreator('Don Kirkby')
        self.paint_puzzle(writer)

    def save_png(self):
        pdf_folder = self.settings.value('pdf_folder')
        file_name, _ = QFileDialog.getSaveFileName(self,
                                                   "Save an image file.",
                                                   dir=pdf_folder,
                                                   filter='Images (*.png)')
        if not file_name:
            return
        writer = QPixmap(1000, 2000)
        self.paint_puzzle(writer)
        writer.save(file_name)
        self.settings.setValue('pdf_folder', os.path.dirname(file_name))

    def paint_puzzle(self, writer: QPaintDevice):
        self.check_clues()
        painter = QPainter(writer)
        try:
            print_shuffler = ArtShuffler(self.art_shuffler.rows,
                                         self.art_shuffler.cols,
                                         writer,
                                         QRect(0, 0, writer.width(),
                                               round(writer.height() / 2)),
                                         clues=self.clues,
                                         row_clues=self.row_clues,
                                         column_clues=self.column_clues)
            print_shuffler.cells = self.art_shuffler.cells[:]
            print_shuffler.is_shuffled = self.art_shuffler.is_shuffled
            selected_pixmap = self.get_selected_pixmap()
            print_shuffler.draw(selected_pixmap, painter)

            print_shuffler.rect.moveTop(writer.height() / 2)
            print_shuffler.draw_grid(selected_pixmap, painter)
        finally:
            painter.end()

    def check_clues(self):
        if self.clue_type == ClueType.words:
            if self.clues is None:
                self.clues = self.word_shuffler.make_clues()
            self.row_clues.clear()
            self.column_clues.clear()
        else:
            self.clues = None
def test_board_size_3(pixmap_differ: PixmapDiffer):
    actual: QPainter
    expected: QPainter
    with pixmap_differ.create_painters(240, 240,
                                       'margo_board_size_3') as (actual,
                                                                 expected):
        expected_scene = QGraphicsScene(0, 0, 240, 240)
        full_board = MargoDisplay.load_pixmap('board-1.png')
        width = full_board.width()
        height = full_board.height()
        top_height = round(height * 0.28)
        mid_height = round(height * 0.21)
        bottom_height = round(height * 0.29)
        left_width = round(width * 0.28)
        mid_width = round(width * 0.22)
        right_width = round(width * 0.279)
        assembled_board = QPixmap(left_width + mid_width + right_width,
                                  top_height + mid_height + bottom_height)
        assembled_board.fill(Qt.transparent)
        assembled_painter = QPainter(assembled_board)
        # top left
        assembled_painter.drawPixmap(0, 0, left_width, top_height, full_board,
                                     0, 0, left_width, top_height)
        # top middle
        assembled_painter.drawPixmap(left_width, 0, mid_width, top_height,
                                     full_board, left_width, 0, mid_width,
                                     top_height)
        # top right
        assembled_painter.drawPixmap(left_width + mid_width, 0, right_width,
                                     top_height, full_board,
                                     width - right_width, 0, right_width,
                                     top_height)
        # left middle
        assembled_painter.drawPixmap(0, top_height, left_width, mid_height,
                                     full_board, 0, top_height, left_width,
                                     mid_height)
        # middle middle
        assembled_painter.drawPixmap(left_width, top_height, mid_width,
                                     mid_height, full_board, left_width,
                                     top_height, mid_width, mid_height)
        # right middle
        assembled_painter.drawPixmap(left_width + mid_width, top_height,
                                     right_width, mid_height, full_board,
                                     width - right_width, top_height,
                                     right_width, mid_height)
        # bottom left
        assembled_painter.drawPixmap(0, top_height + mid_height, left_width,
                                     bottom_height, full_board, 0,
                                     height - bottom_height, left_width,
                                     bottom_height)
        # bottom middle
        assembled_painter.drawPixmap(left_width, top_height + mid_height,
                                     mid_width, bottom_height, full_board,
                                     left_width, height - bottom_height,
                                     mid_width, bottom_height)
        # bottom right
        assembled_painter.drawPixmap(left_width + mid_width,
                                     top_height + mid_height, right_width,
                                     bottom_height, full_board,
                                     width - right_width,
                                     height - bottom_height, right_width,
                                     bottom_height)
        assembled_painter.end()
        scaled_board = assembled_board.scaled(240, 240, Qt.KeepAspectRatio,
                                              Qt.SmoothTransformation)
        board_item = expected_scene.addPixmap(scaled_board)
        board_item.setPos(2, 0)
        white_ball = MargoDisplay.load_pixmap('ball-w-shadow-1.png',
                                              QSize(76, 76))
        black_ball = MargoDisplay.load_pixmap('ball-b-shadow-1.png',
                                              QSize(76, 76))

        expected_scene.addPixmap(white_ball).setPos(15, 145)
        expected_scene.addPixmap(black_ball).setPos(81, 79)
        expected_scene.render(expected)

        display = MargoDisplay(size=3)
        display.resize(348, 264)

        board_text = """\
  A C E
5 . . . 5

3 . B . 3

1 W . . 1
  A C E
>B
"""
        display.update_board(SpargoState(board_text, size=3))

        render_display(display, actual)
Example #18
0
    def __init__(self):
        super().__init__()

        # Declare Widgets
        self.homepage_label = QLabel('Home')
        self.search_label = QLabel('Find an Image!')
        self.srch_box = QLineEdit()  # input field for search
        self.srch_btn = QPushButton("Search")

        # Create U.I. Layout
        mbox = QVBoxLayout()

        vbox = QVBoxLayout()
        vbox.addWidget(self.homepage_label)
        vbox.addWidget(self.search_label)
        vbox.addWidget(self.srch_box)
        vbox.addWidget(self.srch_btn)

        gbox1 = QGroupBox()
        gbox1.setLayout(vbox)
        mbox.addWidget(gbox1)

        # Homes Images Layout
        images = []
        images = self.getHomepageImages()

        # Create layout for images
        vbox2 = QHBoxLayout()

        i = 0
        for img in images:
            self.label = QLabel()
            # pic = Image.open(requests.get(img['urls']['thumb'], stream=True).raw)

            pixmap1 = QPixmap(img)

            pixmap1 = pixmap1.scaled(300, 300, Qt.KeepAspectRatio)

            self.label.setPixmap(pixmap1)

            temp_vbox = QVBoxLayout()
            temp_vbox.addWidget(self.label)

            gbox2 = QGroupBox()
            gbox2.setLayout(temp_vbox)
            gbox2.setStyleSheet("background-color: grey")

            vbox2.addWidget(gbox2)
            i += 1

        gbox3 = QGroupBox()
        gbox3.setLayout(vbox2)
        mbox.addWidget(gbox3)
        self.setLayout(mbox)

        # Styling
        self.setStyleSheet("""
            color: orange;
            font-family: Comfortaa;
            """)
        self.srch_btn.setStyleSheet(":hover { background-color:cyan }")
        gbox1.setStyleSheet("""
            font-size: 18px
            """)

        # Listeners
        self.srch_btn.clicked.connect(self.find_images)
Example #19
0
    def draw(self, art: QPixmap, painter: typing.Optional[QPainter] = None):
        filled_portion = 0.6 if self.is_shuffled and not self.row_clues else 0.9
        scaled_art = art.scaled(self.rect.width() * filled_portion,
                                self.rect.height() * filled_portion,
                                Qt.AspectRatioMode.KeepAspectRatio)
        if painter is None:
            painter = QPainter(self.target)
        painter.fillRect(self.rect, QColor('white'))
        cell_height = round(scaled_art.height() / self.rows)
        vertical_padding = self.rect.height() - self.rows * cell_height
        row_padding = vertical_padding / self.rows
        cell_width = round(scaled_art.width() / self.cols)
        horizontal_padding = self.rect.width() - self.cols * cell_width
        col_padding = horizontal_padding / self.cols
        padding = min(row_padding, col_padding)
        left_border = self.cols * (col_padding - padding) / 2
        top_border = self.rows * (row_padding - padding) / 2
        font = painter.font()
        font.setPixelSize(padding / 2.6)
        painter.setFont(font)
        old_pen = painter.pen()
        grey_pen = QPen(QColor('lightgrey'))
        width = max(cell_width / 35, 2)
        grey_pen.setWidth(round(width))
        y = top_border
        cell_index = 0
        for i in range(self.rows):
            x = left_border
            for j in range(self.cols):
                si, sj, label = self.cells[cell_index]
                clue = self.clues.get(label.lower(), label)
                sx = sj * cell_width
                sy = si * cell_height
                painter.setPen(grey_pen)
                painter.drawRect(x + padding / 2, y, cell_width, cell_height)
                painter.setPen(old_pen)
                if self.is_shuffled:
                    original_size = new_size = font.pixelSize()
                    while True:
                        # noinspection PyTypeChecker
                        rect = painter.boundingRect(0, 0, cell_width, padding,
                                                    Qt.AlignmentFlag.AlignLeft,
                                                    clue)
                        if (rect.width() <= cell_width + padding
                                and rect.height() <= padding):
                            break
                        new_size *= 0.9
                        font.setPixelSize(new_size)
                        painter.setFont(font)
                    if not self.row_clues:
                        painter.drawText(x, y + cell_height,
                                         cell_width + padding, padding,
                                         Qt.AlignmentFlag.AlignHCenter, clue)
                    else:
                        painter.drawPixmap(x + padding / 2, y, cell_width,
                                           cell_height, self.row_clues[si], 0,
                                           0, 0, 0)
                        painter.drawPixmap(x + padding / 2, y, cell_width,
                                           cell_height, self.column_clues[sj],
                                           0, 0, 0, 0)
                    font.setPixelSize(original_size)
                    painter.setFont(font)
                painter.drawPixmap(x + padding / 2, y, cell_width, cell_height,
                                   scaled_art, sx, sy, cell_width, cell_height)

                x += cell_width + padding
                cell_index += 1

            y += cell_height + padding