diff --git a/.settings/org.eclipse.core.resources.prefs b/.settings/org.eclipse.core.resources.prefs index fe101e1..8116164 100644 --- a/.settings/org.eclipse.core.resources.prefs +++ b/.settings/org.eclipse.core.resources.prefs @@ -17,6 +17,7 @@ encoding//\u56FE\u7247\u52A0\u8F7D/xpmres.py=utf-8 encoding//\u5B57\u4F53\u6D4B\u8BD5/FontAwesome.py=utf-8 encoding//\u5B57\u4F53\u6D4B\u8BD5/TestFontRoboto.py=utf-8 encoding//\u68A6\u5E7B\u6811/DreamTree.py=utf-8 +encoding//\u6C14\u6CE1\u63D0\u793A/BubbleTips.py=utf-8 encoding//\u6D4F\u89C8\u5668\u83B7\u53D6Cookie/WebEngineView.py=utf-8 encoding//\u6D4F\u89C8\u5668\u83B7\u53D6Cookie/WebView.py=utf-8 encoding//\u754C\u9762\u7F8E\u5316/QFileSystemModel\u56FE\u6807/FileSystemModel.py=utf-8 diff --git a/README.md b/README.md index 89b7aef..08e3a37 100644 --- a/README.md +++ b/README.md @@ -17,6 +17,7 @@ - [1.12 全局热键](全局热键/) - [1.13 图片加载](图片加载/) - [1.14 窗口重启](窗口重启/) + - [1.15 气泡提示](气泡提示/) ### [2.QGraphicsView练习](QGraphicsView练习/) - [2.1 世界地图](QGraphicsView练习/世界地图) diff --git a/气泡提示/BubbleTips.py b/气泡提示/BubbleTips.py new file mode 100644 index 0000000..08c8a66 --- /dev/null +++ b/气泡提示/BubbleTips.py @@ -0,0 +1,132 @@ +#!/usr/bin/env python +# -*- coding: utf-8 -*- + +''' +Created on 2018年1月27日 +@author: Irony."[讽刺] +@site: http://alyl.vip, http://orzorz.vip, https://coding.net/u/892768447, https://github.com/892768447 +@email: 892768447@qq.com +@file: BubbleTips +@description: +''' +import sys + +from PyQt5.QtCore import QRectF, Qt, QPropertyAnimation, pyqtProperty, \ + QPoint, QParallelAnimationGroup +from PyQt5.QtGui import QPainter, QPainterPath, QColor, QPen +from PyQt5.QtWidgets import QLabel, QWidget, QVBoxLayout, QApplication + + +__Author__ = "By: Irony.\"[讽刺]\nQQ: 892768447\nEmail: 892768447@qq.com" +__Copyright__ = "Copyright (c) 2018 Irony.\"[讽刺]" +__Version__ = "Version 1.0" + + +class BubbleLabel(QWidget): + + BackgroundColor = QColor(195, 195, 195) + BorderColor = QColor(150, 150, 150) + + def __init__(self, *args, **kwargs): + text = kwargs.pop("text", "") + super(BubbleLabel, self).__init__(*args, **kwargs) + # 设置无边框置顶 + self.setWindowFlags( + Qt.Window | Qt.FramelessWindowHint | Qt.WindowStaysOnTopHint) + # 设置最小宽度和高度 + self.setMinimumWidth(200) + self.setMinimumHeight(48) + self.setAttribute(Qt.WA_TranslucentBackground, True) + layout = QVBoxLayout(self) + # 左上右下的边距(下方16是因为包括了三角形) + layout.setContentsMargins(8, 8, 8, 16) + self.label = QLabel(self) + layout.addWidget(self.label) + self.setText(text) + # 获取屏幕高宽 + self._desktop = QApplication.instance().desktop() + + def setText(self, text): + self.label.setText(text) + + def text(self): + return self.label.text() + + def show(self): + super(BubbleLabel, self).show() + # 窗口开始位置 + startPos = QPoint( + self._desktop.screenGeometry().width() - self.width() - 100, + self._desktop.availableGeometry().height() - self.height()) + endPos = QPoint( + self._desktop.screenGeometry().width() - self.width() - 100, + self._desktop.availableGeometry().height() - self.height() * 3 - 5) + print(startPos, endPos) + self.move(startPos) + # 初始化动画 + self.initAnimation(startPos, endPos) + + def initAnimation(self, startPos, endPos): + # 透明度动画 + opacityAnimation = QPropertyAnimation(self, b"opacity") + opacityAnimation.setStartValue(1.0) + opacityAnimation.setEndValue(0.0) + opacityAnimation.setDuration(4000) # 在4秒的时间内完成 + # 往上移动动画 + moveAnimation = QPropertyAnimation(self, b"pos") + moveAnimation.setStartValue(startPos) + moveAnimation.setEndValue(endPos) + moveAnimation.setDuration(5000) # 在5秒的时间内完成 + # 并行动画组(目的是让上面的两个动画同时进行) + self.animationGroup = QParallelAnimationGroup(self) + self.animationGroup.addAnimation(opacityAnimation) + self.animationGroup.addAnimation(moveAnimation) + self.animationGroup.finished.connect(self.close) # 动画结束时关闭窗口 + self.animationGroup.start() + + def paintEvent(self, event): + super(BubbleLabel, self).paintEvent(event) + painter = QPainter(self) + painter.setRenderHint(QPainter.Antialiasing) # 抗锯齿 + + rectPath = QPainterPath() # 圆角矩形 + triPath = QPainterPath() # 底部三角形 + + height = self.height() - 8 # 往上偏移8 + rectPath.addRoundedRect(QRectF(0, 0, self.width(), height), 5, 5) + x = self.width() / 5 * 4 + triPath.moveTo(x, height) # 移动到底部横线4/5处 + # 画三角形 + triPath.lineTo(x + 6, height + 8) + triPath.lineTo(x + 12, height) + + rectPath.addPath(triPath) # 添加三角形到之前的矩形上 + + # 边框画笔 + painter.setPen(QPen(self.BorderColor, 1, Qt.SolidLine, + Qt.RoundCap, Qt.RoundJoin)) + # 背景画刷 + painter.setBrush(self.BackgroundColor) + # 绘制形状 + painter.drawPath(rectPath) + # 三角形底边绘制一条线保证颜色与背景一样 + painter.setPen(QPen(self.BackgroundColor, 1, + Qt.SolidLine, Qt.RoundCap, Qt.RoundJoin)) + painter.drawLine(x, height, x + 12, height) + + def windowOpacity(self): + return super(BubbleLabel, self).windowOpacity() + + def setWindowOpacity(self, opacity): + super(BubbleLabel, self).setWindowOpacity(opacity) + + # 由于opacity属性不在QWidget中需要重新定义一个 + opacity = pyqtProperty(float, windowOpacity, setWindowOpacity) + + +if __name__ == "__main__": + app = QApplication(sys.argv) + w = BubbleLabel() + w.setText("hello") + w.show() + sys.exit(app.exec_()) diff --git a/气泡提示/README.md b/气泡提示/README.md new file mode 100644 index 0000000..684a6bb --- /dev/null +++ b/气泡提示/README.md @@ -0,0 +1,12 @@ +# 简单的右下角气泡提示 + +### 原理思路: + - 1.使用QWidget包含一个QLabel,其中QWidget通过paintEvent绘制气泡形状 + - 2.使用QPropertyAnimation属性动画来移动气泡和改变气泡的透明度 + - 3.使用QParallelAnimationGroup动画组来同时运行两个动画 + +见 [Issues#3](https://github.com/892768447/PyQt/issues/3) + +截图 + +![1](ScreenShot/1.gif) \ No newline at end of file diff --git a/气泡提示/ScreenShot/1.gif b/气泡提示/ScreenShot/1.gif new file mode 100644 index 0000000..fc53d4f Binary files /dev/null and b/气泡提示/ScreenShot/1.gif differ