From 4f26fc768aebc1483030f4f08bf6f4d37994d5e1 Mon Sep 17 00:00:00 2001 From: rainzee Date: Fri, 25 Oct 2024 00:13:04 +0800 Subject: [PATCH 1/5] refactor: impl the code outline draft --- siui/components/button.py | 68 +++++++++++++++++++++++++++++++++++++++ 1 file changed, 68 insertions(+) create mode 100644 siui/components/button.py diff --git a/siui/components/button.py b/siui/components/button.py new file mode 100644 index 0000000..061d6dd --- /dev/null +++ b/siui/components/button.py @@ -0,0 +1,68 @@ +# NOTE This is the refactor of button component. It's working in progress. It will +# replace button once it's done. Now it's draft, code may be ugly and verbose temporarily. + +from PyQt5.QtCore import QRect, QRectF, Qt +from PyQt5.QtGui import QColor, QPainter, QPainterPath, QPaintEvent +from PyQt5.QtWidgets import QApplication, QPushButton, QVBoxLayout, QWidget + + +class SiPushButton(QPushButton): + def __init__(self, parent: QWidget | None = None) -> None: + super().__init__(parent) + + @property + def bottomBorderHeight(self) -> int: + return round(self.rect().height() * 0.125) + + @staticmethod + def _drawBackgroundPath(rect: QRect) -> QPainterPath: + path = QPainterPath() + path.addRoundedRect(QRectF(0, 0, rect.width(), rect.height()), 40, 40) + return path + + def _drawBackgroundRect(self, painter: QPainter, rect: QRect) -> None: + painter.setBrush(QColor("#2D2932")) + painter.drawPath(self._drawBackgroundPath(rect)) + + def _drawButtonPath(self, rect: QRect) -> QPainterPath: + path = QPainterPath() + path.addRoundedRect(QRectF(0, 0, rect.width(), rect.height() - self.bottomBorderHeight), 40, 40) + return path + + def _drawBbuttonRect(self, painter: QPainter, rect: QRect) -> None: + painter.setBrush(QColor("#4C4554")) + painter.drawPath(self._drawButtonPath(rect)) + + def enterEvent(self, event) -> None: + super().enterEvent(event) + + def leaveEvent(self, event) -> None: + super().leaveEvent(event) + + def resizeEvent(self, event) -> None: + super().resizeEvent(event) + + def paintEvent(self, event: QPaintEvent) -> None: + painter = QPainter(self) + painter.setRenderHint(QPainter.RenderHint.Antialiasing) + painter.setPen(Qt.PenStyle.NoPen) + rect = self.rect() + self._drawBackgroundRect(painter, rect) + self._drawBbuttonRect(painter, rect) + + +class Window(QWidget): + def __init__(self) -> None: + super().__init__() + self.resize(600, 800) + self.btn = SiPushButton(self) + self.btn.setFixedSize(2400, 320) + self.main_layout = QVBoxLayout(self) + self.main_layout.addWidget(self.btn, alignment=Qt.AlignmentFlag.AlignCenter) + + +if __name__ == "__main__": + app = QApplication([]) + window = Window() + window.show() + app.exec() From 5b6da8051e128df5e97b23c7fc31f666115efa91 Mon Sep 17 00:00:00 2001 From: rainzee Date: Fri, 25 Oct 2024 00:28:04 +0800 Subject: [PATCH 2/5] chore: add `typing-extensions` dep --- pyproject.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pyproject.toml b/pyproject.toml index 520f78b..a61208d 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -9,7 +9,7 @@ description = "A powerful and artistic UI library based on PyQt5 / PySide6" readme = "README.md" license = { file = "LICENSE" } requires-python = ">=3.8" -dependencies = ["PyQt5>=5.15.10"] +dependencies = ["PyQt5>=5.15.10", "typing-extensions>=4.12.2"] [project.urls] Repository = "https://github.com/ChinaIceF/PyQt-SiliconUI" From 344b2cfd332a3f79ee0c10e365245d6bd3f4f92b Mon Sep 17 00:00:00 2001 From: rainzee Date: Fri, 25 Oct 2024 00:31:17 +0800 Subject: [PATCH 3/5] feat: impl `typing` module --- siui/typing.py | 10 ++++++++++ 1 file changed, 10 insertions(+) create mode 100644 siui/typing.py diff --git a/siui/typing.py b/siui/typing.py new file mode 100644 index 0000000..80f8325 --- /dev/null +++ b/siui/typing.py @@ -0,0 +1,10 @@ +""" +## This module defines global shared types + +Use Python's Type Hint syntax, reference: +- [`typing`](https://docs.python.org/3/library/typing.html) +- [`PEP 484`](https://www.python.org/dev/peps/pep-0484/) +- [`PEP 526`](https://www.python.org/dev/peps/pep-0526/) +""" + +from typing_extensions import TypeAlias From c758cc9182ba1be2dd12936b69af86c5d8956a13 Mon Sep 17 00:00:00 2001 From: rainzee Date: Fri, 25 Oct 2024 00:13:04 +0800 Subject: [PATCH 4/5] refactor: impl the code outline draft --- siui/components/button.py | 68 +++++++++++++++++++++++++++++++++++++++ 1 file changed, 68 insertions(+) create mode 100644 siui/components/button.py diff --git a/siui/components/button.py b/siui/components/button.py new file mode 100644 index 0000000..061d6dd --- /dev/null +++ b/siui/components/button.py @@ -0,0 +1,68 @@ +# NOTE This is the refactor of button component. It's working in progress. It will +# replace button once it's done. Now it's draft, code may be ugly and verbose temporarily. + +from PyQt5.QtCore import QRect, QRectF, Qt +from PyQt5.QtGui import QColor, QPainter, QPainterPath, QPaintEvent +from PyQt5.QtWidgets import QApplication, QPushButton, QVBoxLayout, QWidget + + +class SiPushButton(QPushButton): + def __init__(self, parent: QWidget | None = None) -> None: + super().__init__(parent) + + @property + def bottomBorderHeight(self) -> int: + return round(self.rect().height() * 0.125) + + @staticmethod + def _drawBackgroundPath(rect: QRect) -> QPainterPath: + path = QPainterPath() + path.addRoundedRect(QRectF(0, 0, rect.width(), rect.height()), 40, 40) + return path + + def _drawBackgroundRect(self, painter: QPainter, rect: QRect) -> None: + painter.setBrush(QColor("#2D2932")) + painter.drawPath(self._drawBackgroundPath(rect)) + + def _drawButtonPath(self, rect: QRect) -> QPainterPath: + path = QPainterPath() + path.addRoundedRect(QRectF(0, 0, rect.width(), rect.height() - self.bottomBorderHeight), 40, 40) + return path + + def _drawBbuttonRect(self, painter: QPainter, rect: QRect) -> None: + painter.setBrush(QColor("#4C4554")) + painter.drawPath(self._drawButtonPath(rect)) + + def enterEvent(self, event) -> None: + super().enterEvent(event) + + def leaveEvent(self, event) -> None: + super().leaveEvent(event) + + def resizeEvent(self, event) -> None: + super().resizeEvent(event) + + def paintEvent(self, event: QPaintEvent) -> None: + painter = QPainter(self) + painter.setRenderHint(QPainter.RenderHint.Antialiasing) + painter.setPen(Qt.PenStyle.NoPen) + rect = self.rect() + self._drawBackgroundRect(painter, rect) + self._drawBbuttonRect(painter, rect) + + +class Window(QWidget): + def __init__(self) -> None: + super().__init__() + self.resize(600, 800) + self.btn = SiPushButton(self) + self.btn.setFixedSize(2400, 320) + self.main_layout = QVBoxLayout(self) + self.main_layout.addWidget(self.btn, alignment=Qt.AlignmentFlag.AlignCenter) + + +if __name__ == "__main__": + app = QApplication([]) + window = Window() + window.show() + app.exec() From 64c89412fd2cb85d6908a6a417c41d63a1115088 Mon Sep 17 00:00:00 2001 From: rainzee Date: Fri, 25 Oct 2024 01:03:17 +0800 Subject: [PATCH 5/5] feat: adding polymorphic constructor --- siui/components/button.py | 20 +++++++++++++++++++- 1 file changed, 19 insertions(+), 1 deletion(-) diff --git a/siui/components/button.py b/siui/components/button.py index 061d6dd..a122df4 100644 --- a/siui/components/button.py +++ b/siui/components/button.py @@ -2,7 +2,7 @@ # replace button once it's done. Now it's draft, code may be ugly and verbose temporarily. from PyQt5.QtCore import QRect, QRectF, Qt -from PyQt5.QtGui import QColor, QPainter, QPainterPath, QPaintEvent +from PyQt5.QtGui import QColor, QIcon, QPainter, QPainterPath, QPaintEvent from PyQt5.QtWidgets import QApplication, QPushButton, QVBoxLayout, QWidget @@ -10,6 +10,24 @@ class SiPushButton(QPushButton): def __init__(self, parent: QWidget | None = None) -> None: super().__init__(parent) + @classmethod + def withText(cls, text: str, parent: QWidget | None = None) -> "SiPushButton": + cls = cls(parent) + cls.setText(text) + return cls + + @classmethod + def withIcon(cls, icon: QIcon, parent: QWidget | None = None) -> "SiPushButton": + cls = cls(parent) + cls.setIcon(icon) + return cls + + def withTextAndIcon(cls, text: str, icon: str, parent: QWidget | None = None) -> "SiPushButton": + cls = cls(parent) + cls.setText(text) + cls.setIcon(icon) + return cls + @property def bottomBorderHeight(self) -> int: return round(self.rect().height() * 0.125)