气泡提示 #3
This commit is contained in:
parent
a34bcbfa59
commit
b54fed16a5
5 changed files with 146 additions and 0 deletions
|
@ -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/FontAwesome.py=utf-8
|
||||||
encoding//\u5B57\u4F53\u6D4B\u8BD5/TestFontRoboto.py=utf-8
|
encoding//\u5B57\u4F53\u6D4B\u8BD5/TestFontRoboto.py=utf-8
|
||||||
encoding//\u68A6\u5E7B\u6811/DreamTree.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/WebEngineView.py=utf-8
|
||||||
encoding//\u6D4F\u89C8\u5668\u83B7\u53D6Cookie/WebView.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
|
encoding//\u754C\u9762\u7F8E\u5316/QFileSystemModel\u56FE\u6807/FileSystemModel.py=utf-8
|
||||||
|
|
|
@ -17,6 +17,7 @@
|
||||||
- [1.12 全局热键](全局热键/)
|
- [1.12 全局热键](全局热键/)
|
||||||
- [1.13 图片加载](图片加载/)
|
- [1.13 图片加载](图片加载/)
|
||||||
- [1.14 窗口重启](窗口重启/)
|
- [1.14 窗口重启](窗口重启/)
|
||||||
|
- [1.15 气泡提示](气泡提示/)
|
||||||
|
|
||||||
### [2.QGraphicsView练习](QGraphicsView练习/)
|
### [2.QGraphicsView练习](QGraphicsView练习/)
|
||||||
- [2.1 世界地图](QGraphicsView练习/世界地图)
|
- [2.1 世界地图](QGraphicsView练习/世界地图)
|
||||||
|
|
132
气泡提示/BubbleTips.py
Normal file
132
气泡提示/BubbleTips.py
Normal file
|
@ -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_())
|
12
气泡提示/README.md
Normal file
12
气泡提示/README.md
Normal file
|
@ -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)
|
BIN
气泡提示/ScreenShot/1.gif
Normal file
BIN
气泡提示/ScreenShot/1.gif
Normal file
Binary file not shown.
After Width: | Height: | Size: 1.9 MiB |
Loading…
Reference in a new issue