diff options
Diffstat (limited to 'examples/widgets/widgets/charactermap/characterwidget.py')
-rw-r--r-- | examples/widgets/widgets/charactermap/characterwidget.py | 133 |
1 files changed, 133 insertions, 0 deletions
diff --git a/examples/widgets/widgets/charactermap/characterwidget.py b/examples/widgets/widgets/charactermap/characterwidget.py new file mode 100644 index 000000000..0f01f9684 --- /dev/null +++ b/examples/widgets/widgets/charactermap/characterwidget.py @@ -0,0 +1,133 @@ +# Copyright (C) 2022 The Qt Company Ltd. +# SPDX-License-Identifier: LicenseRef-Qt-Commercial OR BSD-3-Clause + +from textwrap import dedent + +from PySide6.QtCore import QSize, Qt, Slot, Signal +from PySide6.QtGui import (QBrush, QFont, QFontDatabase, QFontMetrics, + QPainter, QPen) +from PySide6.QtWidgets import QToolTip, QWidget + +COLUMNS = 16 + + +class CharacterWidget(QWidget): + + character_selected = Signal(str) + + def __init__(self, parent=None): + super().__init__(parent) + + self._display_font = QFont() + self._last_key = -1 + self._square_size = int(0) + + self.calculate_square_size() + self.setMouseTracking(True) + + @Slot(QFont) + def update_font(self, font): + self._display_font.setFamily(font.family()) + self.calculate_square_size() + self.adjustSize() + self.update() + + @Slot(str) + def update_size(self, fontSize): + self._display_font.setPointSize(int(fontSize)) + self.calculate_square_size() + self.adjustSize() + self.update() + + @Slot(str) + def update_style(self, fontStyle): + old_strategy = self._display_font.styleStrategy() + self._display_font = QFontDatabase.font(self._display_font.family(), + fontStyle, + self._display_font.pointSize()) + self._display_font.setStyleStrategy(old_strategy) + self.calculate_square_size() + self.adjustSize() + self.update() + + @Slot(bool) + def update_font_merging(self, enable): + if enable: + self._display_font.setStyleStrategy(QFont.PreferDefault) + else: + self._display_font.setStyleStrategy(QFont.NoFontMerging) + self.adjustSize() + self.update() + + def calculate_square_size(self): + h = QFontMetrics(self._display_font, self).height() + self._square_size = max(16, 4 + h) + + def sizeHint(self): + return QSize(COLUMNS * self._square_size, + (65536 / COLUMNS) * self._square_size) + + def _unicode_from_pos(self, point): + row = int(point.y() / self._square_size) + return row * COLUMNS + int(point.x() / self._square_size) + + def mouseMoveEvent(self, event): + widget_position = self.mapFromGlobal(event.globalPosition().toPoint()) + key = self._unicode_from_pos(widget_position) + c = chr(key) + family = self._display_font.family() + text = dedent(f''' + <p>Character: <span style="font-size: 24pt; font-family: {family}"> + {c}</span><p>Value: 0x{key:x} + ''') + QToolTip.showText(event.globalPosition().toPoint(), text, self) + + def mousePressEvent(self, event): + if event.button() == Qt.LeftButton: + self._last_key = self._unicode_from_pos(event.position().toPoint()) + if self._last_key != -1: + c = chr(self._last_key) + self.character_selected.emit(f"{c}") + self.update() + else: + super().mousePressEvent(event) + + def paintEvent(self, event): + with QPainter(self) as painter: + self.render(event, painter) + + def render(self, event, painter): + painter = QPainter(self) + painter.fillRect(event.rect(), QBrush(Qt.white)) + painter.setFont(self._display_font) + redraw_rect = event.rect() + begin_row = int(redraw_rect.top() / self._square_size) + end_row = int(redraw_rect.bottom() / self._square_size) + begin_column = int(redraw_rect.left() / self._square_size) + end_column = int(redraw_rect.right() / self._square_size) + painter.setPen(QPen(Qt.gray)) + for row in range(begin_row, end_row + 1): + for column in range(begin_column, end_column + 1): + x = int(column * self._square_size) + y = int(row * self._square_size) + painter.drawRect(x, y, self._square_size, self._square_size) + + font_metrics = QFontMetrics(self._display_font) + painter.setPen(QPen(Qt.black)) + for row in range(begin_row, end_row + 1): + for column in range(begin_column, end_column + 1): + key = int(row * COLUMNS + column) + painter.setClipRect(column * self._square_size, + row * self._square_size, + self._square_size, self._square_size) + + if key == self._last_key: + painter.fillRect(column * self._square_size + 1, + row * self._square_size + 1, + self._square_size, self._square_size, QBrush(Qt.red)) + + text = chr(key) + painter.drawText(column * self._square_size + (self._square_size / 2) + - font_metrics.horizontalAdvance(text) / 2, + row * self._square_size + 4 + font_metrics.ascent(), + text) |