Skip to content

Commit

Permalink
refactor: adopt new coding style in tooltip.py
Browse files Browse the repository at this point in the history
  • Loading branch information
ChinaIceF committed Oct 25, 2024
1 parent 576b87b commit efdf74e
Show file tree
Hide file tree
Showing 6 changed files with 153 additions and 94 deletions.
47 changes: 47 additions & 0 deletions docs/coding_standard.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
# 代码规范
创建于 2024.10.25

为了提高可读性和可维护性,新编写的 PyQt-SiliconUI 代码将遵守以下规范。

## 命名规范
### 命名法
* 变量名采用 snake_case。
* 方法名沿袭 PyQt 特点,采用 lowerCamelCase
* 类名采用 UpperCamelCase
* 旗标类、枚举类和常量采用全大写命名

### 命名构成
#### 变量名
* 采用正常英文语序命名,例如 `day_counter`, `month_counter`, `year_counter`
* 具有大量语义类似,而类型不同的变量,将强调的类型提前作为前缀,例如 `container_name`, `label_name`
* 变量名与方法名冲突时,变量名后加 `_` 后缀,如 `self.name()`, `self.name_`


## 控件 / 组件类
约定模版化的方法和其功能。

### _initWidget()
初始化组件中需要用到的控件,仅做声明,不包含样式表,几何信息等。

### _initStyle()
初始化样式表、字体、颜色等外观相关的属性到自身以及 `_initWidget()` 声明的控件中。

### _initLayout()
初始化布局。除了使用 `QLayout` 外,几何信息也在这里定义,包括位置和大小。

### _initAnimation()
初始化动画。包括 `QPropertyAnimation``SiAnimation`,在这里完成他们的初始化和信号绑定。
例如:
```python
def _initAnimation(self):
self.animation = SiExpAnimation(self)
self.animation.setFactor(1/8)
self.animation.setBias(0.2)
self.animation.setTarget(self.idle_color)
self.animation.setCurrent(self.idle_color)
self.animation.ticked.connect(self.animate)
```

### \_\_init\_\_()
* 初始化变量。
* 依次调用 `_initWidget()` `_initStyle()` `_initLayout()` `_initAnimation()`
Original file line number Diff line number Diff line change
Expand Up @@ -259,10 +259,10 @@ def __init__(self, *args, **kwargs):
container_push_buttons = SiDenseHContainer(self)
container_push_buttons.setFixedHeight(32)

# self.debug_new_button = SiPushButtonRefactor(self)
# self.debug_new_button.resize(128, 32)
# self.debug_new_button.setText("新按钮")
# self.debug_new_button.setHint("我是工具提示")
self.debug_new_button = SiPushButtonRefactor(self)
self.debug_new_button.resize(128, 32)
self.debug_new_button.setText("新按钮")
self.debug_new_button.setToolTip("我是工具提示")

self.demo_push_button_normal = SiPushButton(self)
self.demo_push_button_normal.resize(128, 32)
Expand All @@ -277,7 +277,7 @@ def __init__(self, *args, **kwargs):
self.demo_push_button_long_press.resize(128, 32)
self.demo_push_button_long_press.attachment().setText("长按按钮")

# container_push_buttons.addWidget(self.debug_new_button)
container_push_buttons.addWidget(self.debug_new_button)
container_push_buttons.addWidget(self.demo_push_button_normal)
container_push_buttons.addWidget(self.demo_push_button_transition)
container_push_buttons.addWidget(self.demo_push_button_long_press)
Expand Down
5 changes: 3 additions & 2 deletions examples/Gallery for siui/test_new_button.py
Original file line number Diff line number Diff line change
Expand Up @@ -121,9 +121,10 @@ def __init__(self) -> None:
self.setStyleSheet("background-color: #332E38")

self.btn = SiPushButton(self)
self.btn.setFixedSize(128, 64)
self.btn.setFixedSize(128, 32)
self.btn.setFont(SiFont.tokenized(GlobalFont.S_NORMAL))
self.btn.setText("你好")
self.btn.setText("我是按钮")
self.btn.clicked.connect(lambda: print("clicked!"))

self.main_layout = QVBoxLayout(self)
self.main_layout.addWidget(self.btn, alignment=Qt.AlignmentFlag.AlignCenter)
Expand Down
81 changes: 45 additions & 36 deletions siui/components/button.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,22 +2,20 @@
# replace button once it's done. Now it's draft, code may be ugly and verbose temporarily.
from __future__ import annotations

import os

from PyQt5.QtCore import QRect, QRectF, Qt
from PyQt5.QtCore import QEvent, QRect, QRectF, Qt
from PyQt5.QtGui import QColor, QIcon, QPainter, QPainterPath, QPaintEvent
from PyQt5.QtWidgets import QApplication, QPushButton, QVBoxLayout, QWidget
from PyQt5.QtWidgets import QPushButton, QWidget

from siui.core import GlobalFont, SiColor, SiExpAnimation
from siui.core import GlobalFont, SiColor, SiExpAnimation, SiGlobal
from siui.gui import SiFont

os.environ["QT_SCALE_FACTOR"] = str(2)


class SiPushButton(QPushButton):
class SiPushButtonRefactor(QPushButton):
def __init__(self, parent: QWidget | None = None) -> None:
super().__init__(parent)

self._initStyle()

self.idle_color = SiColor.toArray("#00FFFFFF")
self.hover_color = SiColor.toArray("#10FFFFFF")
self.click_color = SiColor.toArray("#40FFFFFF")
Expand All @@ -43,12 +41,18 @@ def withIcon(cls, icon: QIcon, parent: QWidget | None = None) -> "SiPushButton":
cls.setIcon(icon)
return cls

@classmethod
def withTextAndIcon(cls, text: str, icon: str, parent: QWidget | None = None) -> "SiPushButton":
cls = cls(parent)
cls.setText(text)
cls.setIcon(icon)
return cls

def _initStyle(self):
self.setFont(SiFont.tokenized(GlobalFont.S_NORMAL))
self.setStyleSheet("color: #DFDFDF;")


@property
def bottomBorderHeight(self) -> int:
return round(3)
Expand Down Expand Up @@ -76,22 +80,53 @@ def _drawHighLightRect(self, painter: QPainter, rect: QRect) -> None:
painter.setBrush(QColor(SiColor.toCode(self.animation.current_)))
painter.drawPath(self._drawButtonPath(rect))

def _drawTextRect(self, painter: QPainter, rect: QRect) -> None:
painter.setPen(self.palette().text().color())
painter.setFont(self.font())
painter.drawText(rect, Qt.AlignCenter, self.text())

def _onButtonClicked(self) -> None:
self.animation.setCurrent(self.click_color)
self.animation.start()

def _showToolTip(self) -> None:
if self.toolTip() != "" and "TOOL_TIP" in SiGlobal.siui.windows:
SiGlobal.siui.windows["TOOL_TIP"].setNowInsideOf(self)
SiGlobal.siui.windows["TOOL_TIP"].show_()

def _hideToolTip(self) -> None:
if self.toolTip() != "" and "TOOL_TIP" in SiGlobal.siui.windows:
SiGlobal.siui.windows["TOOL_TIP"].setNowInsideOf(None)
SiGlobal.siui.windows["TOOL_TIP"].hide_()

def _updateToolTip(self) -> None:
if SiGlobal.siui.windows["TOOL_TIP"].nowInsideOf() == self:
SiGlobal.siui.windows["TOOL_TIP"].setText(self.toolTip())

def animate(self, _) -> None:
self.update()

def setToolTip(self, tooltip) -> None:
super().setToolTip(tooltip)
self._updateToolTip()

def event(self, event):
if event.type() == QEvent.ToolTip:
return True # 忽略工具提示事件
return super().event(event)

def enterEvent(self, event) -> None:
super().enterEvent(event)
self.animation.setTarget(self.hover_color)
self.animation.start()
self._showToolTip()
self._updateToolTip()

def leaveEvent(self, event) -> None:
super().leaveEvent(event)
self.animation.setTarget(self.idle_color)
self.animation.start()
self._hideToolTip()

def resizeEvent(self, event) -> None:
super().resizeEvent(event)
Expand All @@ -103,34 +138,8 @@ def paintEvent(self, event: QPaintEvent) -> None:

painter.setPen(Qt.PenStyle.NoPen)
rect = self.rect()
text_rect = QRect(0, 0, self.width(), self.height() - 4)
self._drawBackgroundRect(painter, rect)
self._drawButtonRect(painter, rect)
self._drawHighLightRect(painter, rect)

text_rect = QRect(0, 0, self.width(), self.height() - 4)
painter.setPen(QColor(239, 239, 239)) # 设置文本颜色
painter.setFont(self.font()) # 设置字体和大小
painter.drawText(text_rect, Qt.AlignCenter, self.text()) # 在按钮中心绘制文本
painter.end()


class Window(QWidget):
def __init__(self) -> None:
super().__init__()
self.resize(600, 800)
self.setStyleSheet("background-color: #332E38")

self.btn = SiPushButton(self)
self.btn.setFixedSize(128, 64)
self.btn.setFont(SiFont.tokenized(GlobalFont.S_NORMAL))
self.btn.setText("你好")

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()
self._drawTextRect(painter, text_rect)
96 changes: 46 additions & 50 deletions siui/components/tooltip/tooltip.py
Original file line number Diff line number Diff line change
@@ -1,68 +1,72 @@
"""
tooltip 模块
实现工具提示
"""

from PyQt5.QtCore import Qt, QTimer
from PyQt5.QtGui import QColor, QCursor
from PyQt5.QtWidgets import QGraphicsDropShadowEffect
from PyQt5.QtGui import QCursor

from siui.components.widgets.abstracts.widget import SiWidget
from siui.components.widgets.label import SiLabel
from siui.core import GlobalFont, Si, SiGlobal
from siui.core import GlobalFont, Si, SiGlobal, SiQuickEffect
from siui.gui import SiFont


class ToolTipWindow(SiWidget):
def __init__(self, *args, **kwargs):
super().__init__(*args, **kwargs)

self.completely_hid = False
""" 是否已经完全隐藏(透明度是不是0) """
self.now_inside_of = None
""" 在哪个控件内部(最近一次被谁触发过显示事件) """
self.margin = 8
""" 周围给阴影预留的间隔空间 """
self.shadow_size = 8
""" 阴影大小 """

self.setWindowFlags(Qt.FramelessWindowHint | Qt.WindowStaysOnTopHint | Qt.Tool | Qt.WindowTransparentForInput)
self.setAttribute(Qt.WA_TranslucentBackground)
SiQuickEffect.applyDropShadowOn(self, (0, 0, 0, 128), blur_radius=int(self.shadow_size*1.5))

self.completely_hid = False # 是否已经完全隐藏(透明度是不是0)
self.animationGroup().fromToken("opacity").finished.connect(self._completely_hid_signal_handler)

self.margin = 8 # 周围给阴影预留的间隔空间
self.shadow_size = 8 # 阴影

self.now_inside_of = None # 在哪个控件内部(最近一次被谁触发过显示事件)
self._initWidget()
self._initStyle()
self._initLayout()
self._initAnimation()

shadow = QGraphicsDropShadowEffect()
shadow.setColor(QColor(0, 0, 0, 128))
shadow.setOffset(0, 0)
shadow.setBlurRadius(int(self.shadow_size * 1.5))
self.setGraphicsEffect(shadow)

# 跟踪鼠标的计时器,总处于启动状态
self.tracker_timer = QTimer()
self.tracker_timer.setInterval(int(1000/60))
self.tracker_timer.timeout.connect(self._refresh_position)
self.tracker_timer.start()
self.setText("", flash=False) # 通过输入空文本初始化大小

# 背景颜色,可以用于呈现不同类型的信息
def _initWidget(self):
self.bg_label = SiLabel(self)
self.bg_label.move(self.margin, self.margin)
self.bg_label.setFixedStyleSheet("border-radius: 6px")
"""背景颜色,可以用于呈现不同类型的信息"""

# 文字标签的父对象,防止文字超出界限
self.text_container = SiLabel(self)
self.text_container.move(self.margin, self.margin)
"""文字标签的父对象,防止文字超出界限"""

# 文字标签,工具提示就在这里显示,
self.text_label = SiLabel(self.text_container)
"""文字标签,显示工具提示内容"""

self.highlight_mask = SiLabel(self)
"""高光遮罩,当信息刷新时会闪烁一下"""

def _initStyle(self):
self.bg_label.setFixedStyleSheet("border-radius: 6px")
self.text_label.setFixedStyleSheet("padding: 8px")
self.text_label.setSiliconWidgetFlag(Si.InstantResize)
self.text_label.setSiliconWidgetFlag(Si.AdjustSizeOnTextChanged)
self.text_label.setFont(SiFont.tokenized(GlobalFont.S_NORMAL))

# 高光遮罩,当信息刷新时会闪烁一下
self.highlight_mask = SiLabel(self)
self.highlight_mask.move(self.margin, self.margin)
self.highlight_mask.setFixedStyleSheet("border-radius: 6px")
self.highlight_mask.setColor("#00FFFFFF")

# 通过输入空文本初始化大小
self.setText("", flash=False)
def _initLayout(self):
self.bg_label.move(self.margin, self.margin)
self.text_container.move(self.margin, self.margin)
self.highlight_mask.move(self.margin, self.margin)

def _initAnimation(self):
self.tracker_timer = QTimer() # 跟踪鼠标的计时器
self.tracker_timer.setInterval(int(1000/60))
self.tracker_timer.timeout.connect(self._refresh_position)
self.tracker_timer.start()

# 当透明度动画结束时处理隐藏与否
self.animationGroup().fromToken("opacity").finished.connect(self._completely_hid_signal_handler)

def reloadStyleSheet(self):
self.bg_label.setColor(SiGlobal.siui.colors["TOOLTIP_BG"])
Expand Down Expand Up @@ -109,21 +113,13 @@ def setText(self, text, flash=True):
self.flash()

def _refresh_size(self):
"""
用于设置大小动画结束值并启动动画
:return:
"""
w, h = self.text_label.width(), self.text_label.height()

# 让自身大小变为文字标签的大小加上阴影间距
self.resizeTo(w + 2 * self.margin, h + 2 * self.margin)
""" 用于设置大小动画结束值并启动动画 """
w = self.text_label.width()
h = self.text_label.height()
self.resizeTo(w + 2 * self.margin, h + 2 * self.margin) # 设为文字标签的大小加上阴影间距

def flash(self):
"""
激活高光层动画,使高光层闪烁
:return:
"""
# 刷新高亮层动画当前值和结束值,实现闪烁效果
""" 激活高光层动画,使高光层闪烁 """
self.highlight_mask.setColor("#7FFFFFFF")
self.highlight_mask.setColorTo("#00FFFFFF")

Expand Down
8 changes: 7 additions & 1 deletion siui/components/widgets/abstracts/label.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@

from PyQt5.QtCore import QPoint, pyqtSignal
from PyQt5.QtCore import QPoint, pyqtSignal, QEvent
from PyQt5.QtWidgets import QLabel

from siui.core import Si, SiAnimationGroup, SiColor, SiExpAnimation, SiGlobal, SiQuickEffect
Expand Down Expand Up @@ -299,6 +299,7 @@ def setHint(self, text: str):
:param text: tooltip content. Rich text is supported
"""
self.hint = text
self.setToolTip(text)

# 把新的工具提示推送给工具提示窗口
if self.hint != "" and "TOOL_TIP" in SiGlobal.siui.windows:
Expand All @@ -323,3 +324,8 @@ def leaveEvent(self, event):
if self.hint != "" and "TOOL_TIP" in SiGlobal.siui.windows:
SiGlobal.siui.windows["TOOL_TIP"].setNowInsideOf(None)
SiGlobal.siui.windows["TOOL_TIP"].hide_()

def event(self, event):
if event.type() == QEvent.ToolTip:
return True # 忽略工具提示事件
return super().event(event)

0 comments on commit efdf74e

Please sign in to comment.