This commit is contained in:
Irony 2018-12-28 20:50:07 +08:00
parent 3dc4b85a39
commit 97909c3690
92 changed files with 550 additions and 1442 deletions

View file

@ -2,7 +2,7 @@
<module type="PYTHON_MODULE" version="4">
<component name="NewModuleRootManager">
<content url="file://$MODULE_DIR$" />
<orderEntry type="inheritedJdk" />
<orderEntry type="jdk" jdkName="Python 3.4" jdkType="Python SDK" />
<orderEntry type="sourceFolder" forTests="false" />
</component>
<component name="TestRunnerService">

View file

@ -1 +0,0 @@
# Animation

View file

@ -4,7 +4,7 @@
'''
Created on 2017年12月28日
@author: Irony."[讽刺]
@site: http://alyl.vip, http://orzorz.vip, https://coding.net/u/892768447, https://github.com/892768447
@site: https://pyqt5.com https://github.com/892768447
@email: 892768447@qq.com
@file: charts.bar.BarStack
@description: like http://echarts.baidu.com/demo.html#bar-stack

View file

@ -4,7 +4,7 @@
'''
Created on 2017年12月28日
@author: Irony."[讽刺]
@site: http://alyl.vip, http://orzorz.vip, https://coding.net/u/892768447, https://github.com/892768447
@site: https://pyqt5.com https://github.com/892768447
@email: 892768447@qq.com
@file: charts.line.LineStack
@description: like http://echarts.baidu.com/demo.html#line-stack

View file

@ -4,7 +4,7 @@
'''
Created on 2017年12月23日
@author: Irony."[讽刺]
@site: http://alyl.vip, http://orzorz.vip, https://coding.net/u/892768447, https://github.com/892768447
@site: https://pyqt5.com https://github.com/892768447
@email: 892768447@qq.com
@file: ToolTip
@description:

View file

@ -4,7 +4,7 @@
'''
Created on 2017年12月23日
@author: Irony."[讽刺]
@site: http://alyl.vip, http://orzorz.vip, https://coding.net/u/892768447, https://github.com/892768447
@site: https://pyqt5.com https://github.com/892768447
@email: 892768447@qq.com
@file: ToolTip2
@description:

View file

@ -4,7 +4,7 @@
"""
Created on 2018年1月27日
@author: Irony."[讽刺]
@site: http://alyl.vip, http://orzorz.vip, https://coding.net/u/892768447, https://github.com/892768447
@site: https://pyqt5.com https://github.com/892768447
@email: 892768447@qq.com
@file: CityLinkage
@description: 下拉联动

View file

@ -4,7 +4,7 @@
'''
Created on 2018年2月4日
@author: Irony."[讽刺]
@site: http://alyl.vip, http://orzorz.vip, https://coding.net/u/892768447, https://github.com/892768447
@site: https://pyqt5.com https://github.com/892768447
@email: 892768447@qq.com
@file: TencentMovieHotPlay_Flow
@description:

View file

@ -1,14 +1,14 @@
#!/usr/bin/env python
# -*- coding: utf-8 -*-
'''
"""
Created on 2017年12月23日
@author: Irony."[讽刺]
@site: http://alyl.vip, http://orzorz.vip, https://coding.net/u/892768447, https://github.com/892768447
@site: https://pyqt5.com https://github.com/892768447
@email: 892768447@qq.com
@file: 添加QWidget
@file: AddQWidget
@description:
'''
"""
import sys
from PyQt5.QtCore import Qt

View file

@ -0,0 +1,16 @@
# QGraphicsView
## 1、绘制世界地图
[运行 WorldMap.py](WorldMap.py)
1. 解析json数据生成 `QPolygonF`
2. 使用Ctrl+滑轮进行放大缩小
![WorldMap](ScreenShot/WorldMap.gif)
## 2、添加QWidget
[运行 AddQWidget.py](AddQWidget.py)
通过 `QGraphicsScene.addWidget` 添加自定义QWidget
![AddQWidget](ScreenShot/AddQWidget.png)

View file

Before

Width:  |  Height:  |  Size: 4.9 KiB

After

Width:  |  Height:  |  Size: 4.9 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 460 KiB

View file

@ -1,14 +1,14 @@
#!/usr/bin/env python
# -*- coding: utf-8 -*-
'''
"""
Created on 2017年12月17日
@author: Irony."[讽刺]
@site: http://alyl.vip, http://orzorz.vip, https://coding.net/u/892768447, https://github.com/892768447
@site: https://pyqt5.com https://github.com/892768447
@email: 892768447@qq.com
@file: WorldMap
@description:
'''
"""
import json
import math
@ -128,7 +128,7 @@ class GraphicsView(QGraphicsView):
def initMap(self):
features = json.load(
open("world.json", encoding="utf8")).get("features")
open("Data/world.json", encoding="utf8")).get("features")
for feature in features:
geometry = feature.get("geometry")
if not geometry:

View file

@ -4,7 +4,7 @@
'''
Created on 2018年2月4日
@author: Irony."[讽刺]
@site: http://alyl.vip, http://orzorz.vip, https://coding.net/u/892768447, https://github.com/892768447
@site: https://pyqt5.com https://github.com/892768447
@email: 892768447@qq.com
@file: TencentMovieHotPlay
@description:

View file

@ -4,7 +4,7 @@
'''
Created on 2017年12月23日
@author: Irony."[讽刺]
@site: http://alyl.vip, http://orzorz.vip, https://coding.net/u/892768447, https://github.com/892768447
@site: https://pyqt5.com https://github.com/892768447
@email: 892768447@qq.com
@file: ShowImage
@description:

View file

@ -4,7 +4,7 @@
'''
Created on 2018年2月4日
@author: Irony."[讽刺]
@site: http://alyl.vip, http://orzorz.vip, https://coding.net/u/892768447, https://github.com/892768447
@site: https://pyqt5.com https://github.com/892768447
@email: 892768447@qq.com
@file: TencentMovieHotPlay_ListWidget
@description:

View file

Before

Width:  |  Height:  |  Size: 47 KiB

After

Width:  |  Height:  |  Size: 47 KiB

View file

Before

Width:  |  Height:  |  Size: 40 KiB

After

Width:  |  Height:  |  Size: 40 KiB

View file

Before

Width:  |  Height:  |  Size: 45 KiB

After

Width:  |  Height:  |  Size: 45 KiB

View file

Before

Width:  |  Height:  |  Size: 41 KiB

After

Width:  |  Height:  |  Size: 41 KiB

View file

Before

Width:  |  Height:  |  Size: 57 KiB

After

Width:  |  Height:  |  Size: 57 KiB

View file

Before

Width:  |  Height:  |  Size: 47 KiB

After

Width:  |  Height:  |  Size: 47 KiB

View file

Before

Width:  |  Height:  |  Size: 64 KiB

After

Width:  |  Height:  |  Size: 64 KiB

View file

Before

Width:  |  Height:  |  Size: 89 KiB

After

Width:  |  Height:  |  Size: 89 KiB

View file

Before

Width:  |  Height:  |  Size: 53 KiB

After

Width:  |  Height:  |  Size: 53 KiB

View file

Before

Width:  |  Height:  |  Size: 107 KiB

After

Width:  |  Height:  |  Size: 107 KiB

View file

@ -0,0 +1 @@
# QPropertyAnimation

View file

@ -1,4 +1,4 @@
# Animation
# QPropertyAnimation
# 1、窗口淡入淡出
[运行 FadeInOut.py](FadeInOut.py)

View file

Before

Width:  |  Height:  |  Size: 630 KiB

After

Width:  |  Height:  |  Size: 630 KiB

View file

Before

Width:  |  Height:  |  Size: 78 KiB

After

Width:  |  Height:  |  Size: 78 KiB

View file

Before

Width:  |  Height:  |  Size: 1.6 MiB

After

Width:  |  Height:  |  Size: 1.6 MiB

View file

Before

Width:  |  Height:  |  Size: 1.7 MiB

After

Width:  |  Height:  |  Size: 1.7 MiB

View file

@ -4,7 +4,7 @@
'''
Created on 2017年12月10日
@author: Irony."[讽刺]
@site: http://alyl.vip, http://orzorz.vip, https://coding.net/u/892768447, https://github.com/892768447
@site: https://pyqt5.com https://github.com/892768447
@email: 892768447@qq.com
@file: GetCookie
@description:

View file

@ -4,7 +4,7 @@
'''
Created on 2017年12月10日
@author: Irony."[讽刺]
@site: http://alyl.vip, http://orzorz.vip, https://coding.net/u/892768447, https://github.com/892768447
@site: https://pyqt5.com https://github.com/892768447
@email: 892768447@qq.com
@file: GetCookie
@description:

View file

@ -9,7 +9,6 @@ https://pyqt5.com 社区是专门针对PyQt5学习和提升开设的博客网站
| 分类 | 目录 |
|:-------|:-------|
| ActiveX | [QAxWidget](QAxWidget)
| 动画 | [Animation](Animation)
| 日历 | [QCalendarWidget](QCalendarWidget)
| 复选框 | [QCheckBox](QCheckBox)
| 列视图 | [QColumnView](QColumnView)
@ -37,6 +36,7 @@ https://pyqt5.com 社区是专门针对PyQt5学习和提升开设的博客网站
| OpenGL | [QOpenGLWidget](QOpenGLWidget)
| 纯文本 | [QPlainTextEdit](QPlainTextEdit)
| 进度条 | [QProgressBar](QProgressBar)
| 动画 | [QPropertyAnimation](QPropertyAnimation)
| 代理样式 | [QProxyStyle](QProxyStyle)
| 按钮 | [QPushButton](QPushButton)
| 单选框 | [QRadioButton](QRadioButton)

View file

@ -1,44 +1,44 @@
#!/usr/bin/env python
# -*- coding: utf-8 -*-
'''
Created on 2018年05月01日
@author: Irony."[讽刺]
@site: http://alyl.vip, http://orzorz.vip, https://coding.net/u/892768447, https://github.com/892768447
@email: 892768447@qq.com
@file: qrctest1
@description:
'''
from PyQt5.QtGui import QPixmap
from PyQt5.QtWidgets import QLabel
import res_rc # @UnusedImport @UnresolvedImport
__Author__ = "By: Irony.\"[讽刺]\nQQ: 892768447\nEmail: 892768447@qq.com"
__Copyright__ = "Copyright (c) 2017 Irony.\"[讽刺]"
__Version__ = "Version 1.0"
class ImageView(QLabel):
def __init__(self, *args, **kwargs):
super(ImageView, self).__init__(*args, **kwargs)
self.resize(800, 600)
# 从资源文件res_rc.py中加载
# 转换命令pyrcc5 res.qrc -o res_rc.py
# 这种方式是从通过pyrcc5转换res.qrc为res_rc.py文件可以直接import加载
# 此时可以通过路径:/images/head.jpg来访问
self.setPixmap(QPixmap(":/images/head.jpg"))
if __name__ == "__main__":
import sys
from PyQt5.QtWidgets import QApplication
app = QApplication(sys.argv)
app.aboutToQuit.connect(res_rc.qCleanupResources) # 退出时要清理资源
w = ImageView()
w.show()
sys.exit(app.exec_())
#!/usr/bin/env python
# -*- coding: utf-8 -*-
'''
Created on 2018年05月01日
@author: Irony."[讽刺]
@site: https://pyqt5.com https://github.com/892768447
@email: 892768447@qq.com
@file: qrctest1
@description:
'''
from PyQt5.QtGui import QPixmap
from PyQt5.QtWidgets import QLabel
import res_rc # @UnusedImport @UnresolvedImport
__Author__ = "By: Irony.\"[讽刺]\nQQ: 892768447\nEmail: 892768447@qq.com"
__Copyright__ = "Copyright (c) 2017 Irony.\"[讽刺]"
__Version__ = "Version 1.0"
class ImageView(QLabel):
def __init__(self, *args, **kwargs):
super(ImageView, self).__init__(*args, **kwargs)
self.resize(800, 600)
# 从资源文件res_rc.py中加载
# 转换命令pyrcc5 res.qrc -o res_rc.py
# 这种方式是从通过pyrcc5转换res.qrc为res_rc.py文件可以直接import加载
# 此时可以通过路径:/images/head.jpg来访问
self.setPixmap(QPixmap(":/images/head.jpg"))
if __name__ == "__main__":
import sys
from PyQt5.QtWidgets import QApplication
app = QApplication(sys.argv)
app.aboutToQuit.connect(res_rc.qCleanupResources) # 退出时要清理资源
w = ImageView()
w.show()
sys.exit(app.exec_())

View file

@ -1,44 +1,44 @@
#!/usr/bin/env python
# -*- coding: utf-8 -*-
'''
Created on 2018年05月01日
@author: Irony."[讽刺]
@site: http://alyl.vip, http://orzorz.vip, https://coding.net/u/892768447, https://github.com/892768447
@email: 892768447@qq.com
@file: qrctest2
@description:
'''
from PyQt5.QtCore import QResource
from PyQt5.QtGui import QPixmap
from PyQt5.QtWidgets import QLabel
__Author__ = "By: Irony.\"[讽刺]\nQQ: 892768447\nEmail: 892768447@qq.com"
__Copyright__ = "Copyright (c) 2017 Irony.\"[讽刺]"
__Version__ = "Version 1.0"
class ImageView(QLabel):
def __init__(self, *args, **kwargs):
super(ImageView, self).__init__(*args, **kwargs)
self.resize(800, 600)
self.setPixmap(QPixmap(":/images/head.jpg"))
if __name__ == "__main__":
import sys
from PyQt5.QtWidgets import QApplication
app = QApplication(sys.argv)
# 从二进制资源文件res.data中加载
# 转换命令cd tools
# rcc.exe -binary ../res.qrc -o ../res.data
# 此时需要注册
QResource.registerResource("res.data")
app.aboutToQuit.connect(lambda: QResource.unregisterResource("res.data"))
w = ImageView()
w.show()
sys.exit(app.exec_())
#!/usr/bin/env python
# -*- coding: utf-8 -*-
'''
Created on 2018年05月01日
@author: Irony."[讽刺]
@site: https://pyqt5.com https://github.com/892768447
@email: 892768447@qq.com
@file: qrctest2
@description:
'''
from PyQt5.QtCore import QResource
from PyQt5.QtGui import QPixmap
from PyQt5.QtWidgets import QLabel
__Author__ = "By: Irony.\"[讽刺]\nQQ: 892768447\nEmail: 892768447@qq.com"
__Copyright__ = "Copyright (c) 2017 Irony.\"[讽刺]"
__Version__ = "Version 1.0"
class ImageView(QLabel):
def __init__(self, *args, **kwargs):
super(ImageView, self).__init__(*args, **kwargs)
self.resize(800, 600)
self.setPixmap(QPixmap(":/images/head.jpg"))
if __name__ == "__main__":
import sys
from PyQt5.QtWidgets import QApplication
app = QApplication(sys.argv)
# 从二进制资源文件res.data中加载
# 转换命令cd tools
# rcc.exe -binary ../res.qrc -o ../res.data
# 此时需要注册
QResource.registerResource("res.data")
app.aboutToQuit.connect(lambda: QResource.unregisterResource("res.data"))
w = ImageView()
w.show()
sys.exit(app.exec_())

View file

@ -1,113 +1,113 @@
#!/usr/bin/env python
# -*- coding: utf-8 -*-
'''
Created on 2018年1月29日
@author: Irony."[讽刺]
@site: http://alyl.vip, http://orzorz.vip, https://coding.net/u/892768447, https://github.com/892768447
@email: 892768447@qq.com
@file: OpencvWidget
@description:
'''
import sys
from PyQt5.QtCore import QTimer
from PyQt5.QtGui import QImage, QPixmap
from PyQt5.QtWidgets import QLabel, QMessageBox, QApplication
import cv2 # @UnresolvedImport
import dlib
import numpy
__Author__ = "By: Irony.\"[讽刺]\nQQ: 892768447\nEmail: 892768447@qq.com"
__Copyright__ = "Copyright (c) 2018 Irony.\"[讽刺]"
__Version__ = "Version 1.0"
DOWNSCALE = 4
class OpencvWidget(QLabel):
def __init__(self, *args, **kwargs):
super(OpencvWidget, self).__init__(*args, **kwargs)
self.fps = 24
self.resize(800, 600)
self.setText("请稍候,正在初始化数据和摄像头。。。")
def start(self):
try:
# 检测相关
self.detector = dlib.get_frontal_face_detector()
self.predictor = dlib.shape_predictor(
"data/shape_predictor_68_face_landmarks.dat")
cascade_fn = "data/lbpcascades/lbpcascade_frontalface.xml"
self.cascade = cv2.CascadeClassifier(cascade_fn)
if not self.cascade:
return QMessageBox.critical(self, "错误", cascade_fn + " 无法找到")
self.cap = cv2.VideoCapture(0)
if not self.cap or not self.cap.isOpened():
return QMessageBox.critical(self, "错误", "打开摄像头失败")
# 开启定时器定时捕获
self.timer = QTimer(self, timeout=self.onCapture)
self.timer.start(1000 / self.fps)
except Exception as e:
QMessageBox.critical(self, "错误", str(e))
def closeEvent(self, event):
if hasattr(self, "timer"):
self.timer.stop()
self.timer.deleteLater()
self.cap.release()
del self.predictor, self.detector, self.cascade, self.cap
super(OpencvWidget, self).closeEvent(event)
self.deleteLater()
def onCapture(self):
_, frame = self.cap.read()
minisize = (
int(frame.shape[1] / DOWNSCALE), int(frame.shape[0] / DOWNSCALE))
tmpframe = cv2.resize(frame, minisize)
tmpframe = cv2.cvtColor(tmpframe, cv2.COLOR_BGR2GRAY) # 做灰度处理
tmpframe = cv2.equalizeHist(tmpframe)
# minNeighbors表示每一个目标至少要被检测到5次
faces = self.cascade.detectMultiScale(tmpframe, minNeighbors=5)
del tmpframe
if len(faces) < 1: # 没有检测到脸
frame = cv2.cvtColor(frame, cv2.COLOR_BGR2RGB)
img = QImage(
frame.data, frame.shape[1], frame.shape[0], frame.shape[1] * 3, QImage.Format_RGB888)
del frame
return self.setPixmap(QPixmap.fromImage(img))
# 特征点检测描绘
for x, y, w, h in faces:
x, y, w, h = x * DOWNSCALE, y * DOWNSCALE, w * DOWNSCALE, h * DOWNSCALE
# 画脸矩形
cv2.rectangle(frame, (x, y), (x + w, y + h), (0, 255, 0))
# 截取的人脸部分
tmpframe = frame[y:y + h, x:x + w]
# 进行特征点描绘
rects = self.detector(tmpframe, 1)
if len(rects) > 0:
landmarks = numpy.matrix(
[[p.x, p.y] for p in self.predictor(tmpframe, rects[0]).parts()])
for _, point in enumerate(landmarks):
pos = (point[0, 0] + x, point[0, 1] + y)
# 在原来画面上画点
cv2.circle(frame, pos, 3, color=(0, 255, 0))
# 转成Qt能显示的
frame = cv2.cvtColor(frame, cv2.COLOR_BGR2RGB)
img = QImage(
frame.data, frame.shape[1], frame.shape[0], frame.shape[1] * 3, QImage.Format_RGB888)
del frame
self.setPixmap(QPixmap.fromImage(img))
if __name__ == "__main__":
app = QApplication(sys.argv)
w = OpencvWidget()
w.show()
# 5秒后启动
QTimer.singleShot(5000, w.start)
sys.exit(app.exec_())
#!/usr/bin/env python
# -*- coding: utf-8 -*-
'''
Created on 2018年1月29日
@author: Irony."[讽刺]
@site: https://pyqt5.com https://github.com/892768447
@email: 892768447@qq.com
@file: OpencvWidget
@description:
'''
import sys
from PyQt5.QtCore import QTimer
from PyQt5.QtGui import QImage, QPixmap
from PyQt5.QtWidgets import QLabel, QMessageBox, QApplication
import cv2 # @UnresolvedImport
import dlib
import numpy
__Author__ = "By: Irony.\"[讽刺]\nQQ: 892768447\nEmail: 892768447@qq.com"
__Copyright__ = "Copyright (c) 2018 Irony.\"[讽刺]"
__Version__ = "Version 1.0"
DOWNSCALE = 4
class OpencvWidget(QLabel):
def __init__(self, *args, **kwargs):
super(OpencvWidget, self).__init__(*args, **kwargs)
self.fps = 24
self.resize(800, 600)
self.setText("请稍候,正在初始化数据和摄像头。。。")
def start(self):
try:
# 检测相关
self.detector = dlib.get_frontal_face_detector()
self.predictor = dlib.shape_predictor(
"data/shape_predictor_68_face_landmarks.dat")
cascade_fn = "data/lbpcascades/lbpcascade_frontalface.xml"
self.cascade = cv2.CascadeClassifier(cascade_fn)
if not self.cascade:
return QMessageBox.critical(self, "错误", cascade_fn + " 无法找到")
self.cap = cv2.VideoCapture(0)
if not self.cap or not self.cap.isOpened():
return QMessageBox.critical(self, "错误", "打开摄像头失败")
# 开启定时器定时捕获
self.timer = QTimer(self, timeout=self.onCapture)
self.timer.start(1000 / self.fps)
except Exception as e:
QMessageBox.critical(self, "错误", str(e))
def closeEvent(self, event):
if hasattr(self, "timer"):
self.timer.stop()
self.timer.deleteLater()
self.cap.release()
del self.predictor, self.detector, self.cascade, self.cap
super(OpencvWidget, self).closeEvent(event)
self.deleteLater()
def onCapture(self):
_, frame = self.cap.read()
minisize = (
int(frame.shape[1] / DOWNSCALE), int(frame.shape[0] / DOWNSCALE))
tmpframe = cv2.resize(frame, minisize)
tmpframe = cv2.cvtColor(tmpframe, cv2.COLOR_BGR2GRAY) # 做灰度处理
tmpframe = cv2.equalizeHist(tmpframe)
# minNeighbors表示每一个目标至少要被检测到5次
faces = self.cascade.detectMultiScale(tmpframe, minNeighbors=5)
del tmpframe
if len(faces) < 1: # 没有检测到脸
frame = cv2.cvtColor(frame, cv2.COLOR_BGR2RGB)
img = QImage(
frame.data, frame.shape[1], frame.shape[0], frame.shape[1] * 3, QImage.Format_RGB888)
del frame
return self.setPixmap(QPixmap.fromImage(img))
# 特征点检测描绘
for x, y, w, h in faces:
x, y, w, h = x * DOWNSCALE, y * DOWNSCALE, w * DOWNSCALE, h * DOWNSCALE
# 画脸矩形
cv2.rectangle(frame, (x, y), (x + w, y + h), (0, 255, 0))
# 截取的人脸部分
tmpframe = frame[y:y + h, x:x + w]
# 进行特征点描绘
rects = self.detector(tmpframe, 1)
if len(rects) > 0:
landmarks = numpy.matrix(
[[p.x, p.y] for p in self.predictor(tmpframe, rects[0]).parts()])
for _, point in enumerate(landmarks):
pos = (point[0, 0] + x, point[0, 1] + y)
# 在原来画面上画点
cv2.circle(frame, pos, 3, color=(0, 255, 0))
# 转成Qt能显示的
frame = cv2.cvtColor(frame, cv2.COLOR_BGR2RGB)
img = QImage(
frame.data, frame.shape[1], frame.shape[0], frame.shape[1] * 3, QImage.Format_RGB888)
del frame
self.setPixmap(QPixmap.fromImage(img))
if __name__ == "__main__":
app = QApplication(sys.argv)
w = OpencvWidget()
w.show()
# 5秒后启动
QTimer.singleShot(5000, w.start)
sys.exit(app.exec_())

View file

@ -4,7 +4,7 @@
'''
Created on 2017年12月11日
@author: Irony."[讽刺]
@site: http://alyl.vip, http://orzorz.vip, https://coding.net/u/892768447, https://github.com/892768447
@site: https://pyqt5.com https://github.com/892768447
@email: 892768447@qq.com
@file: HotKey
@description:

View file

@ -1,163 +1,163 @@
#!/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, QEasingCurve
from PyQt5.QtGui import QPainter, QPainterPath, QColor, QPen
from PyQt5.QtWidgets import QLabel, QWidget, QVBoxLayout, QApplication,\
QLineEdit, QPushButton
__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.Tool | Qt.FramelessWindowHint | Qt.WindowStaysOnTopHint | Qt.X11BypassWindowManagerHint)
# 设置最小宽度和高度
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 stop(self):
self.hide()
self.animationGroup.stop()
self.close()
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.setEasingCurve(QEasingCurve.InQuad)
opacityAnimation.setDuration(4000) # 在4秒的时间内完成
# 往上移动动画
moveAnimation = QPropertyAnimation(self, b"pos")
moveAnimation.setStartValue(startPos)
moveAnimation.setEndValue(endPos)
moveAnimation.setEasingCurve(QEasingCurve.InQuad)
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)
class TestWidget(QWidget):
def __init__(self, *args, **kwargs):
super(TestWidget, self).__init__(*args, **kwargs)
layout = QVBoxLayout(self)
self.msgEdit = QLineEdit(self, returnPressed=self.onMsgShow)
self.msgButton = QPushButton("显示内容", self, clicked=self.onMsgShow)
layout.addWidget(self.msgEdit)
layout.addWidget(self.msgButton)
def onMsgShow(self):
msg = self.msgEdit.text().strip()
if not msg:
return
if hasattr(self, "_blabel"):
self._blabel.stop()
self._blabel.deleteLater()
del self._blabel
self._blabel = BubbleLabel()
self._blabel.setText(msg)
self._blabel.show()
if __name__ == "__main__":
app = QApplication(sys.argv)
w = TestWidget()
w.show()
sys.exit(app.exec_())
#!/usr/bin/env python
# -*- coding: utf-8 -*-
'''
Created on 2018年1月27日
@author: Irony."[讽刺]
@site: https://pyqt5.com https://github.com/892768447
@email: 892768447@qq.com
@file: BubbleTips
@description:
'''
import sys
from PyQt5.QtCore import QRectF, Qt, QPropertyAnimation, pyqtProperty, \
QPoint, QParallelAnimationGroup, QEasingCurve
from PyQt5.QtGui import QPainter, QPainterPath, QColor, QPen
from PyQt5.QtWidgets import QLabel, QWidget, QVBoxLayout, QApplication,\
QLineEdit, QPushButton
__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.Tool | Qt.FramelessWindowHint | Qt.WindowStaysOnTopHint | Qt.X11BypassWindowManagerHint)
# 设置最小宽度和高度
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 stop(self):
self.hide()
self.animationGroup.stop()
self.close()
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.setEasingCurve(QEasingCurve.InQuad)
opacityAnimation.setDuration(4000) # 在4秒的时间内完成
# 往上移动动画
moveAnimation = QPropertyAnimation(self, b"pos")
moveAnimation.setStartValue(startPos)
moveAnimation.setEndValue(endPos)
moveAnimation.setEasingCurve(QEasingCurve.InQuad)
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)
class TestWidget(QWidget):
def __init__(self, *args, **kwargs):
super(TestWidget, self).__init__(*args, **kwargs)
layout = QVBoxLayout(self)
self.msgEdit = QLineEdit(self, returnPressed=self.onMsgShow)
self.msgButton = QPushButton("显示内容", self, clicked=self.onMsgShow)
layout.addWidget(self.msgEdit)
layout.addWidget(self.msgButton)
def onMsgShow(self):
msg = self.msgEdit.text().strip()
if not msg:
return
if hasattr(self, "_blabel"):
self._blabel.stop()
self._blabel.deleteLater()
del self._blabel
self._blabel = BubbleLabel()
self._blabel.setText(msg)
self._blabel.show()
if __name__ == "__main__":
app = QApplication(sys.argv)
w = TestWidget()
w.show()
sys.exit(app.exec_())

View file

@ -1,57 +1,57 @@
#!/usr/bin/env python
# -*- coding: utf-8 -*-
'''
Created on 2018年1月28日
@author: Irony."[讽刺]
@site: http://alyl.vip, http://orzorz.vip, https://coding.net/u/892768447, https://github.com/892768447
@email: 892768447@qq.com
@file: IronyImporter
@description:
'''
import base64
import os
import sys
from types import ModuleType
import xxtea # @UnresolvedImport
__Author__ = "By: Irony.\"[讽刺]\nQQ: 892768447\nEmail: 892768447@qq.com"
__Copyright__ = "Copyright (c) 2018 Irony.\"[讽刺]"
__Version__ = "Version 1.0"
KEY = base64.b85decode("HF5^hbNbOVOKM=(SB`7h")
class IronyImporter:
@classmethod
def find_module(cls, name, path=None):
name = name + ".irony"
if not os.path.isfile(name):
return None
return cls
@classmethod
def load_module(cls, name):
if name in sys.modules:
return sys.modules[name]
mod = ModuleType(name)
mod.__loader__ = cls
mod.__name__ = name
mod.__file__ = name + ".irony"
try:
exec(xxtea.decrypt(open(mod.__file__, "rb").read(), KEY), mod.__dict__)
except Exception as e:
print(e)
return None
sys.modules[name] = mod
return mod
@classmethod
def module_repr(cls, module):
return "<module {!r} from ({!r})>".format(module.__name__, module.__file__)
sys.meta_path.insert(0, IronyImporter)
#!/usr/bin/env python
# -*- coding: utf-8 -*-
'''
Created on 2018年1月28日
@author: Irony."[讽刺]
@site: https://pyqt5.com https://github.com/892768447
@email: 892768447@qq.com
@file: IronyImporter
@description:
'''
import base64
import os
import sys
from types import ModuleType
import xxtea # @UnresolvedImport
__Author__ = "By: Irony.\"[讽刺]\nQQ: 892768447\nEmail: 892768447@qq.com"
__Copyright__ = "Copyright (c) 2018 Irony.\"[讽刺]"
__Version__ = "Version 1.0"
KEY = base64.b85decode("HF5^hbNbOVOKM=(SB`7h")
class IronyImporter:
@classmethod
def find_module(cls, name, path=None):
name = name + ".irony"
if not os.path.isfile(name):
return None
return cls
@classmethod
def load_module(cls, name):
if name in sys.modules:
return sys.modules[name]
mod = ModuleType(name)
mod.__loader__ = cls
mod.__name__ = name
mod.__file__ = name + ".irony"
try:
exec(xxtea.decrypt(open(mod.__file__, "rb").read(), KEY), mod.__dict__)
except Exception as e:
print(e)
return None
sys.modules[name] = mod
return mod
@classmethod
def module_repr(cls, module):
return "<module {!r} from ({!r})>".format(module.__name__, module.__file__)
sys.meta_path.insert(0, IronyImporter)

View file

@ -1,25 +1,25 @@
#!/usr/bin/env python
# -*- coding: utf-8 -*-
'''
Created on 2018年1月28日
@author: Irony."[讽刺]
@site: http://alyl.vip, http://orzorz.vip, https://coding.net/u/892768447, https://github.com/892768447
@email: 892768447@qq.com
@file: build
@description:
'''
__Author__ = "By: Irony.\"[讽刺]\nQQ: 892768447\nEmail: 892768447@qq.com"
__Copyright__ = "Copyright (c) 2018 Irony.\"[讽刺]"
__Version__ = "Version 1.0"
import base64
import xxtea # @UnresolvedImport
KEY = base64.b85decode("HF5^hbNbOVOKM=(SB`7h")
with open("src/test.py", "rb") as fi:
open("test.irony", "wb").write(xxtea.encrypt(fi.read(), KEY))
print("ok")
#!/usr/bin/env python
# -*- coding: utf-8 -*-
'''
Created on 2018年1月28日
@author: Irony."[讽刺]
@site: https://pyqt5.com https://github.com/892768447
@email: 892768447@qq.com
@file: build
@description:
'''
__Author__ = "By: Irony.\"[讽刺]\nQQ: 892768447\nEmail: 892768447@qq.com"
__Copyright__ = "Copyright (c) 2018 Irony.\"[讽刺]"
__Version__ = "Version 1.0"
import base64
import xxtea # @UnresolvedImport
KEY = base64.b85decode("HF5^hbNbOVOKM=(SB`7h")
with open("src/test.py", "rb") as fi:
open("test.irony", "wb").write(xxtea.encrypt(fi.read(), KEY))
print("ok")

View file

@ -1,25 +1,25 @@
#!/usr/bin/env python
# -*- coding: utf-8 -*-
'''
Created on 2018年1月28日
@author: Irony."[讽刺]
@site: http://alyl.vip, http://orzorz.vip, https://coding.net/u/892768447, https://github.com/892768447
@email: 892768447@qq.com
@file: main
@description:
'''
__Author__ = "By: Irony.\"[讽刺]\nQQ: 892768447\nEmail: 892768447@qq.com"
__Copyright__ = "Copyright (c) 2018 Irony.\"[讽刺]"
__Version__ = "Version 1.0"
# 首先要引入importer
import IronyImporter # @UnresolvedImport @UnusedImport
# 测试开始
import test
print(test)
print(dir(test))
print(test.test(1, 5)) # @UndefinedVariable
#!/usr/bin/env python
# -*- coding: utf-8 -*-
'''
Created on 2018年1月28日
@author: Irony."[讽刺]
@site: https://pyqt5.com https://github.com/892768447
@email: 892768447@qq.com
@file: main
@description:
'''
__Author__ = "By: Irony.\"[讽刺]\nQQ: 892768447\nEmail: 892768447@qq.com"
__Copyright__ = "Copyright (c) 2018 Irony.\"[讽刺]"
__Version__ = "Version 1.0"
# 首先要引入importer
import IronyImporter # @UnresolvedImport @UnusedImport
# 测试开始
import test
print(test)
print(dir(test))
print(test.test(1, 5)) # @UndefinedVariable

View file

@ -1,19 +1,19 @@
#!/usr/bin/env python
# -*- coding: utf-8 -*-
'''
Created on 2018年1月28日
@author: Irony."[讽刺]
@site: http://alyl.vip, http://orzorz.vip, https://coding.net/u/892768447, https://github.com/892768447
@email: 892768447@qq.com
@file: test
@description:
'''
__Author__ = "By: Irony.\"[讽刺]\nQQ: 892768447\nEmail: 892768447@qq.com"
__Copyright__ = "Copyright (c) 2018 Irony.\"[讽刺]"
__Version__ = "Version 1.0"
def test(a, b):
return a + b
#!/usr/bin/env python
# -*- coding: utf-8 -*-
'''
Created on 2018年1月28日
@author: Irony."[讽刺]
@site: https://pyqt5.com https://github.com/892768447
@email: 892768447@qq.com
@file: test
@description:
'''
__Author__ = "By: Irony.\"[讽刺]\nQQ: 892768447\nEmail: 892768447@qq.com"
__Copyright__ = "Copyright (c) 2018 Irony.\"[讽刺]"
__Version__ = "Version 1.0"
def test(a, b):
return a + b

View file

@ -1,12 +0,0 @@
# 图形视图QGraphicsView
## [1、 世界地图](世界地图/)
![截图](世界地图/ScreenShot/2.png)
## [2、 添加QWidget](添加QWidget.py)
![添加QWidget](ScreenShot/添加QWidget.png)
## [3、 显示图片及缩放](显示图片及缩放.py)
按下小键盘-为缩小, +为放大
![显示图片及缩放](ScreenShot/显示图片及缩放.gif)

Binary file not shown.

Before

Width:  |  Height:  |  Size: 381 KiB

View file

@ -1,170 +0,0 @@
#!/usr/bin/env python
# -*- coding: utf-8 -*-
"""
Created on 2018年7月26日
@author: Irony
@site: https://pyqt5.com, https://github.com/892768447
@email: 892768447@qq.com
@file: QGraphicsView练习.QGraphicsItem.Item移动
@description:
"""
from PyQt5.QtCore import Qt, QLineF, QRectF
from PyQt5.QtGui import QPainter, QColor, QPen
from PyQt5.QtWidgets import QGraphicsRectItem, QGraphicsView, QGraphicsScene,\
QStyle
__Author__ = """By: Irony
QQ: 892768447
Email: 892768447@qq.com"""
__Copyright__ = "Copyright (c) 2018 Irony"
__Version__ = "Version 1.0"
class MoveableItem(QGraphicsRectItem):
def __init__(self, *args, **kwargs):
super(MoveableItem, self).__init__(*args, **kwargs)
self.setPos(0, 0)
# 可移动,可选择,有焦点,发送大小位置改变事件
self.setFlags(self.ItemIsMovable | self.ItemIsSelectable |
self.ItemIsFocusable | self.ItemSendsGeometryChanges)
# 设置接收悬停事件
self.setAcceptHoverEvents(True)
self.setBrush(QColor(247, 160, 57)) # 设置背景颜色
# 是否在调整大小的状态
self.isResizing = False
self.mousePressPos = None
self.mousePressRect = None
def paint(self, painter, option, widget):
super(MoveableItem, self).paint(painter, option, widget)
# 当鼠标选中后在边缘绘制边框
if option.state & QStyle.State_Selected:
rect = self.boundingRect()
painter.setRenderHint(QPainter.Antialiasing, True) # 抗锯齿
x, y, w, h = rect.x(), rect.y(), rect.width(), rect.height()
if option.state & QStyle.State_HasFocus: # 有焦点
painter.setPen(QPen(Qt.red, 3)) # 设置红色画笔
# 在左上、左下、右上、右下、以及四条边上画小线段
painter.drawLines(
QLineF(x, y, x + 10, y), # 左上顶点向右
QLineF(x, y, x, y + 10), # 左上顶点向下
QLineF(x, y + h, x + 10, y + h), # 左下顶点向右
QLineF(x, y + h, x, y + h - 10), # 左下顶点向上
QLineF(x + w, y, x + w - 10, y), # 右上顶点向左
QLineF(x + w, y, x + w, y + 10), # 右上顶点向下
QLineF(x + w, y + h, x + w - 10, y + h), # 右下顶点向左
QLineF(x + w, y + h, x + w, y + h - 10) # 右下顶点向上
)
def hoverMoveEvent(self, event):
super(MoveableItem, self).hoverMoveEvent(event)
# 鼠标悬停事件,用于检测鼠标位置并改变鼠标形态
cursor = self.isInResizeArea(event.pos())
if self.isResizing or (cursor and self.isSelected()):
# 正在调整中或者鼠标在可调整区域范围内并且是选中
self.setCursor(cursor)
else:
self.setCursor(Qt.ArrowCursor)
def hoverLeaveEvent(self, event):
"""鼠标悬停离开事件恢复鼠标样式"""
super(MoveableItem, self).hoverLeaveEvent(event)
self.setCursor(Qt.ArrowCursor)
def mousePressEvent(self, event):
# 鼠标按下
super(MoveableItem, self).mousePressEvent(event)
if event.button() == Qt.LeftButton and self.isInResizeArea(event.pos()):
self.isResizing = True
self.mousePressPos = event.pos()
self.mousePressRect = self.boundingRect()
def mouseReleaseEvent(self, event):
# 鼠标释放开
super(MoveableItem, self).mouseReleaseEvent(event)
if event.button() == Qt.LeftButton and self.isResizing:
self.isResizing = False
self.mousePressPos = None
self.mousePressRect = None
self.update()
def mouseMoveEvent(self, event):
# 鼠标移动
if self.isResizing and self.mousePressPos:
rect = self.boundingRect()
pos = event.pos() - self.mousePressPos
w = pos.x()
h = pos.y()
x = -4 if w > 0 else 4
y = -4 if h > 0 else 4
print(x, y, -x, -y, pos)
self.setRect(rect.adjusted(x, y, -x, -y))
self.prepareGeometryChange()
else:
super(MoveableItem, self).mouseMoveEvent(event)
def isInResizeArea(self, pos):
# 检测判断鼠标所在位置是否为四个顶点的范围内
rect = self.boundingRect()
x, y, w, h = rect.x(), rect.y(), rect.width(), rect.height()
lx = pos.x() < x + 10
rx = pos.x() > x + w - 10
ty = pos.y() < y + 10
by = pos.y() > y + h - 10
# 左上角和右下角
if (lx and ty) or (rx and by):
return Qt.SizeFDiagCursor
# 右上角和左下角
if (rx and ty) or (lx and by):
return Qt.SizeBDiagCursor
# 上、下
if ty or by:
return Qt.SizeVerCursor
if lx or rx:
return Qt.SizeHorCursor
# 左、右
return 0
class ImageWidget(QGraphicsView):
def __init__(self, *args, **kwargs):
super(ImageWidget, self).__init__(*args, **kwargs)
self.resize(800, 600)
# 设置背景颜色
self.setBackgroundBrush(QColor(31, 31, 47))
# 去掉滚动条
# self.setHorizontalScrollBarPolicy(Qt.ScrollBarAlwaysOff)
# self.setVerticalScrollBarPolicy(Qt.ScrollBarAlwaysOff)
# 设置变换中心为鼠标所在位置
self.setTransformationAnchor(self.AnchorUnderMouse)
# 不保证painter的状态
self.setOptimizationFlags(self.DontSavePainterState)
self.setViewportUpdateMode(self.SmartViewportUpdate)
self.setRenderHints(QPainter.Antialiasing |
QPainter.SmoothPixmapTransform)
# 场景
self._scene = QGraphicsScene(0, 0, self.width(), self.height())
self.setScene(self._scene)
self._scene.addItem(MoveableItem(100, 100, 200, 200))
if __name__ == '__main__':
import sys
import cgitb
sys.excepthook = cgitb.Hook(1, None, 5, sys.stderr, 'text')
from PyQt5.QtWidgets import QApplication
app = QApplication(sys.argv)
w = ImageWidget()
w.show()
sys.exit(app.exec_())

View file

@ -1,63 +0,0 @@
#!/usr/bin/env python
# -*- coding: utf-8 -*-
"""
Created on 2018年7月26日
@author: Irony
@site: https://pyqt5.com, https://github.com/892768447
@email: 892768447@qq.com
@file: QGraphicsView练习.QGraphicsItem.Item移动
@description:
"""
from PyQt5.QtGui import QPainter, QColor
from PyQt5.QtWidgets import QGraphicsRectItem, QGraphicsView, QGraphicsScene
__Author__ = """By: Irony
QQ: 892768447
Email: 892768447@qq.com"""
__Copyright__ = "Copyright (c) 2018 Irony"
__Version__ = "Version 1.0"
class MoveableItem(QGraphicsRectItem):
def __init__(self, *args, **kwargs):
super(MoveableItem, self).__init__(*args, **kwargs)
self.setFlag(self.ItemIsMovable) # 设置为可以动
self.setBrush(QColor(247, 160, 57)) # 设置背景颜色
class ImageWidget(QGraphicsView):
def __init__(self, *args, **kwargs):
super(ImageWidget, self).__init__(*args, **kwargs)
self.resize(800, 600)
# 设置背景颜色
self.setBackgroundBrush(QColor(31, 31, 47))
# 去掉滚动条
# self.setHorizontalScrollBarPolicy(Qt.ScrollBarAlwaysOff)
# self.setVerticalScrollBarPolicy(Qt.ScrollBarAlwaysOff)
# 设置变换中心为鼠标所在位置
self.setTransformationAnchor(self.AnchorUnderMouse)
# 不保证painter的状态
self.setOptimizationFlags(self.DontSavePainterState)
self.setViewportUpdateMode(self.SmartViewportUpdate)
self.setRenderHints(QPainter.Antialiasing |
QPainter.SmoothPixmapTransform)
# 场景
self._scene = QGraphicsScene()
self.setScene(self._scene)
self.setSceneRect(0, 0, self.width(), self.height())
self._scene.addItem(MoveableItem(100, 100, 200, 200))
if __name__ == '__main__':
import sys
from PyQt5.QtWidgets import QApplication
app = QApplication(sys.argv)
w = ImageWidget()
w.show()
sys.exit(app.exec_())

View file

@ -1,294 +0,0 @@
#!/usr/bin/env python
# -*- coding: utf-8 -*-
# Created on 2018年7月26日
# author: Irony
# site: https://pyqt5.com, https://github.com/892768447
# email: 892768447@qq.com
# file: QGraphicsView练习.QGraphicsItem.ttt
# description:
__Author__ = """By: Irony
QQ: 892768447
Email: 892768447@qq.com"""
__Copyright__ = 'Copyright (c) 2018 Irony'
__Version__ = 1.0
import sys
from PyQt5.QtCore import Qt, QRectF, QPointF
from PyQt5.QtGui import QBrush, QPainterPath, QPainter, QColor, QPen, QPixmap
from PyQt5.QtWidgets import QGraphicsRectItem, QApplication, QGraphicsView, QGraphicsScene, QGraphicsItem
class GraphicsRectItem(QGraphicsRectItem):
handleTopLeft = 1
handleTopMiddle = 2
handleTopRight = 3
handleMiddleLeft = 4
handleMiddleRight = 5
handleBottomLeft = 6
handleBottomMiddle = 7
handleBottomRight = 8
handleSize = +8.0
handleSpace = -4.0
handleCursors = {
handleTopLeft: Qt.SizeFDiagCursor,
handleTopMiddle: Qt.SizeVerCursor,
handleTopRight: Qt.SizeBDiagCursor,
handleMiddleLeft: Qt.SizeHorCursor,
handleMiddleRight: Qt.SizeHorCursor,
handleBottomLeft: Qt.SizeBDiagCursor,
handleBottomMiddle: Qt.SizeVerCursor,
handleBottomRight: Qt.SizeFDiagCursor,
}
def __init__(self, *args):
"""
Initialize the shape.
"""
super().__init__(*args)
self.handles = {}
self.handleSelected = None
self.mousePressPos = None
self.mousePressRect = None
self.setAcceptHoverEvents(True)
self.setFlag(QGraphicsItem.ItemIsMovable, True)
self.setFlag(QGraphicsItem.ItemIsSelectable, True)
self.setFlag(QGraphicsItem.ItemSendsGeometryChanges, True)
self.setFlag(QGraphicsItem.ItemIsFocusable, True)
self.updateHandlesPos()
def handleAt(self, point):
"""
Returns the resize handle below the given point.
"""
for k, v, in self.handles.items():
if v.contains(point):
return k
return None
def hoverMoveEvent(self, moveEvent):
"""
Executed when the mouse moves over the shape (NOT PRESSED).
"""
if self.isSelected():
handle = self.handleAt(moveEvent.pos())
cursor = Qt.ArrowCursor if handle is None else self.handleCursors[handle]
self.setCursor(cursor)
super().hoverMoveEvent(moveEvent)
def hoverLeaveEvent(self, moveEvent):
"""
Executed when the mouse leaves the shape (NOT PRESSED).
"""
self.setCursor(Qt.ArrowCursor)
super().hoverLeaveEvent(moveEvent)
def mousePressEvent(self, mouseEvent):
"""
Executed when the mouse is pressed on the item.
"""
self.handleSelected = self.handleAt(mouseEvent.pos())
if self.handleSelected:
self.mousePressPos = mouseEvent.pos()
self.mousePressRect = self.boundingRect()
super().mousePressEvent(mouseEvent)
def mouseMoveEvent(self, mouseEvent):
"""
Executed when the mouse is being moved over the item while being pressed.
"""
if self.handleSelected is not None:
self.interactiveResize(mouseEvent.pos())
else:
super().mouseMoveEvent(mouseEvent)
def mouseReleaseEvent(self, mouseEvent):
"""
Executed when the mouse is released from the item.
"""
super().mouseReleaseEvent(mouseEvent)
self.handleSelected = None
self.mousePressPos = None
self.mousePressRect = None
self.update()
def boundingRect(self):
"""
Returns the bounding rect of the shape (including the resize handles).
"""
o = self.handleSize + self.handleSpace
return self.rect().adjusted(-o, -o, o, o)
def updateHandlesPos(self):
"""
Update current resize handles according to the shape size and position.
"""
s = self.handleSize
b = self.boundingRect()
self.handles[self.handleTopLeft] = QRectF(b.left(), b.top(), s, s)
self.handles[self.handleTopMiddle] = QRectF(b.center().x() - s / 2, b.top(), s, s)
self.handles[self.handleTopRight] = QRectF(b.right() - s, b.top(), s, s)
self.handles[self.handleMiddleLeft] = QRectF(b.left(), b.center().y() - s / 2, s, s)
self.handles[self.handleMiddleRight] = QRectF(b.right() - s, b.center().y() - s / 2, s, s)
self.handles[self.handleBottomLeft] = QRectF(b.left(), b.bottom() - s, s, s)
self.handles[self.handleBottomMiddle] = QRectF(b.center().x() - s / 2, b.bottom() - s, s, s)
self.handles[self.handleBottomRight] = QRectF(b.right() - s, b.bottom() - s, s, s)
def interactiveResize(self, mousePos):
"""
Perform shape interactive resize.
"""
offset = self.handleSize + self.handleSpace
boundingRect = self.boundingRect()
rect = self.rect()
diff = QPointF(0, 0)
self.prepareGeometryChange()
if self.handleSelected == self.handleTopLeft:
fromX = self.mousePressRect.left()
fromY = self.mousePressRect.top()
toX = fromX + mousePos.x() - self.mousePressPos.x()
toY = fromY + mousePos.y() - self.mousePressPos.y()
diff.setX(toX - fromX)
diff.setY(toY - fromY)
boundingRect.setLeft(toX)
boundingRect.setTop(toY)
rect.setLeft(boundingRect.left() + offset)
rect.setTop(boundingRect.top() + offset)
self.setRect(rect)
elif self.handleSelected == self.handleTopMiddle:
fromY = self.mousePressRect.top()
toY = fromY + mousePos.y() - self.mousePressPos.y()
diff.setY(toY - fromY)
boundingRect.setTop(toY)
rect.setTop(boundingRect.top() + offset)
self.setRect(rect)
elif self.handleSelected == self.handleTopRight:
fromX = self.mousePressRect.right()
fromY = self.mousePressRect.top()
toX = fromX + mousePos.x() - self.mousePressPos.x()
toY = fromY + mousePos.y() - self.mousePressPos.y()
diff.setX(toX - fromX)
diff.setY(toY - fromY)
boundingRect.setRight(toX)
boundingRect.setTop(toY)
rect.setRight(boundingRect.right() - offset)
rect.setTop(boundingRect.top() + offset)
self.setRect(rect)
elif self.handleSelected == self.handleMiddleLeft:
fromX = self.mousePressRect.left()
toX = fromX + mousePos.x() - self.mousePressPos.x()
diff.setX(toX - fromX)
boundingRect.setLeft(toX)
rect.setLeft(boundingRect.left() + offset)
self.setRect(rect)
elif self.handleSelected == self.handleMiddleRight:
print("MR")
fromX = self.mousePressRect.right()
toX = fromX + mousePos.x() - self.mousePressPos.x()
diff.setX(toX - fromX)
boundingRect.setRight(toX)
rect.setRight(boundingRect.right() - offset)
self.setRect(rect)
elif self.handleSelected == self.handleBottomLeft:
fromX = self.mousePressRect.left()
fromY = self.mousePressRect.bottom()
toX = fromX + mousePos.x() - self.mousePressPos.x()
toY = fromY + mousePos.y() - self.mousePressPos.y()
diff.setX(toX - fromX)
diff.setY(toY - fromY)
boundingRect.setLeft(toX)
boundingRect.setBottom(toY)
rect.setLeft(boundingRect.left() + offset)
rect.setBottom(boundingRect.bottom() - offset)
self.setRect(rect)
elif self.handleSelected == self.handleBottomMiddle:
fromY = self.mousePressRect.bottom()
toY = fromY + mousePos.y() - self.mousePressPos.y()
diff.setY(toY - fromY)
boundingRect.setBottom(toY)
rect.setBottom(boundingRect.bottom() - offset)
self.setRect(rect)
elif self.handleSelected == self.handleBottomRight:
fromX = self.mousePressRect.right()
fromY = self.mousePressRect.bottom()
toX = fromX + mousePos.x() - self.mousePressPos.x()
toY = fromY + mousePos.y() - self.mousePressPos.y()
diff.setX(toX - fromX)
diff.setY(toY - fromY)
boundingRect.setRight(toX)
boundingRect.setBottom(toY)
rect.setRight(boundingRect.right() - offset)
rect.setBottom(boundingRect.bottom() - offset)
self.setRect(rect)
self.updateHandlesPos()
def shape(self):
"""
Returns the shape of this item as a QPainterPath in local coordinates.
"""
path = QPainterPath()
path.addRect(self.rect())
if self.isSelected():
for shape in self.handles.values():
path.addEllipse(shape)
return path
def paint(self, painter, option, widget=None):
"""
Paint the node in the graphic view.
"""
painter.setBrush(QBrush(QColor(255, 0, 0, 100)))
painter.setPen(QPen(QColor(0, 0, 0), 1.0, Qt.SolidLine))
painter.drawRect(self.rect())
painter.setRenderHint(QPainter.Antialiasing)
painter.setBrush(QBrush(QColor(255, 0, 0, 255)))
painter.setPen(QPen(QColor(0, 0, 0, 255), 1.0, Qt.SolidLine, Qt.RoundCap, Qt.RoundJoin))
for handle, rect in self.handles.items():
if self.handleSelected is None or handle == self.handleSelected:
painter.drawEllipse(rect)
def main():
app = QApplication(sys.argv)
grview = QGraphicsView()
scene = QGraphicsScene()
scene.setSceneRect(0, 0, 680, 459)
scene.addPixmap(QPixmap('01.png'))
grview.setScene(scene)
item = GraphicsRectItem(0, 0, 300, 150)
scene.addItem(item)
grview.fitInView(scene.sceneRect(), Qt.KeepAspectRatio)
grview.show()
sys.exit(app.exec_())
if __name__ == '__main__':
main()

View file

@ -1,6 +0,0 @@
# 描绘世界地图
世界地图-使用Ctrl+滑轮进行放大缩小
![ScreenShot1](ScreenShot/1.png)
![ScreenShot2](ScreenShot/1.png)

Binary file not shown.

Before

Width:  |  Height:  |  Size: 103 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 141 KiB

View file

@ -1,108 +0,0 @@
#!/usr/bin/env python
# -*- coding: utf-8 -*-
"""
Created on 2018年3月23日
@author: Irony
@site: https://pyqt5.com, https://github.com/892768447
@email: 892768447@qq.com
@file: ImageView
@description: 图片查看
"""
from PyQt5.QtCore import QStandardPaths, Qt
from PyQt5.QtGui import QColor, QPainter, QPixmap
from PyQt5.QtOpenGL import QGLFormat
from PyQt5.QtWidgets import QGraphicsView, QGraphicsScene, QFileDialog, \
QGraphicsItem
__Author__ = 'By: Irony\nQQ: 892768447\nEmail: 892768447@qq.com'
__Copyright__ = 'Copyright (c) 2018 Irony'
__Version__ = 1.0
class GraphicsView(QGraphicsView):
# 背景区域颜色
backgroundColor = QColor(28, 31, 34)
def __init__(self, *args, **kwargs):
super(GraphicsView, self).__init__(*args, **kwargs)
self.resize(800, 600)
# 设置背景颜色
self.setBackgroundBrush(self.backgroundColor)
# 缓存背景
self.setCacheMode(self.CacheBackground)
# 设置拖拽样式
# self.setDragMode(self.ScrollHandDrag)
self.setRenderHints(
QPainter.Antialiasing | QPainter.TextAntialiasing | QPainter.SmoothPixmapTransform)
# opengl
if QGLFormat.hasOpenGL():
self.setRenderHint(QPainter.HighQualityAntialiasing)
# 尝试通过分析需要重绘的区域来找到最佳的更新模式
self.setViewportUpdateMode(self.SmartViewportUpdate)
self._scene = QGraphicsScene(-400, -300, 800, 600, self)
self.setScene(self._scene)
# 图片item
self._itemImage = None
def keyReleaseEvent(self, event):
"""按键处理事件"""
self._scaleImage(event)
super(GraphicsView, self).keyReleaseEvent(event)
def closeEvent(self, event):
"""窗口关闭时清空场景中的所有item"""
self._scene.clear()
self._itemImage = None
super(GraphicsView, self).closeEvent(event)
def _scaleImage(self, event):
"""缩放图片操作"""
if not self._itemImage:
return
scale = self._itemImage.scale()
if event.key() == Qt.Key_Plus:
# 放大
if scale >= 0.91:
return
self._itemImage.setScale(scale + 0.1)
elif event.key() == Qt.Key_Minus:
# 缩小
if scale <= 0.11:
return
self._itemImage.setScale(scale - 0.1)
def loadImage(self):
path, _ = QFileDialog.getOpenFileName(
self, '请选择图片', QStandardPaths.writableLocation(QStandardPaths.DesktopLocation), '图片文件(*.jpg *.png)')
if not path:
return
if self._itemImage:
# 删除以前的item
self._scene.removeItem(self._itemImage)
del self._itemImage
self._itemImage = self._scene.addPixmap(QPixmap(path))
self._itemImage.setFlag(QGraphicsItem.ItemIsMovable)
self._itemImage.setScale(0.1) # 默认加载比例
size = self._itemImage.pixmap().size()
# 调整图片在中间
self._itemImage.setPos(
-size.width() * self._itemImage.scale() / 2,
-size.height() * self._itemImage.scale() / 2
)
if __name__ == '__main__':
import sys
import os
print(os.getpid())
from PyQt5.QtWidgets import QApplication, QPushButton
app = QApplication(sys.argv)
w = GraphicsView()
w.show()
ww = QPushButton('选择文件', clicked=w.loadImage)
ww.show()
sys.exit(app.exec_())

View file

@ -1,78 +0,0 @@
#!/usr/bin/env python
# -*- coding: utf-8 -*-
"""
Created on 2018年3月24日
@author: Irony
@site: https://pyqt5.com, https://github.com/892768447
@email: 892768447@qq.com
@file: SimpleImagePs
@description: 图片查看
"""
from PyQt5.QtCore import Qt
from PyQt5.QtGui import QCursor
from PyQt5.QtWidgets import QMainWindow, QToolBar
from SimpleImageView import SimpleImageView # @UnresolvedImport
__Author__ = """By: Irony
QQ: 892768447
Email: 892768447@qq.com"""
__Copyright__ = 'Copyright (c) 2018 Irony'
__Version__ = 1.0
class MainWindow(QMainWindow):
def __init__(self, *args, **kwargs):
super(MainWindow, self).__init__(*args, **kwargs)
# 获取可用主屏桌面大小
screenRect = QApplication.instance().desktop().availableGeometry()
# 设置为桌面的2/3大
self.resize(
int(screenRect.width() * 2 / 3), int(screenRect.height() * 2 / 3))
# 初始化中心控件
self._imageView = SimpleImageView(self)
self.setCentralWidget(self._imageView)
# 初始化菜单栏
self._initMenuBar()
# 初始化工具条
self._initToolBar()
def _initMenuBar(self):
"""菜单栏"""
menuBar = self.menuBar()
menu = menuBar.addMenu('文件')
menu.addAction('打开', self._imageView.loadImage)
menu.addAction('关闭')
menu.addAction('退出')
def _initToolBar(self):
"""工具条"""
toolBar = QToolBar('工具栏', self)
self.addToolBar(Qt.LeftToolBarArea, toolBar)
toolBar.addAction('灰度', self._imageView._greyScale)
toolBar.addAction('亮度')
toolBar.addAction('暖色调')
toolBar.addAction('冷色调')
toolBar.addAction('饱和度')
toolBar.addAction('模糊')
toolBar.addAction('锐化', self._ruihua)
def _ruihua(self):
# 得到按钮的大概位置
print(self.mapFromGlobal(QCursor.pos()))
if __name__ == '__main__':
import sys
import os
print('pid:', os.getpid())
from PyQt5.QtWidgets import QApplication
app = QApplication(sys.argv)
app.setApplicationDisplayName('简单图片处理')
app.setApplicationName('简单图片处理')
app.setApplicationVersion('1.0')
w = MainWindow()
w.show()
sys.exit(app.exec_())

View file

@ -1,19 +0,0 @@
#!/usr/bin/env python
# -*- coding: utf-8 -*-
from PyQt5.QtCore import QObject
# Created on 2018年3月26日
# author: Irony
# site: https://pyqt5.com, https://github.com/892768447
# email: 892768447@qq.com
# file: QGraphicsView练习.简单图像处理.SimpleImageThread
# description:
__Author__ = """By: Irony
QQ: 892768447
Email: 892768447@qq.com"""
__Copyright__ = 'Copyright (c) 2018 Irony'
__Version__ = 1.0
class ToGrey(QObject):
pass

View file

@ -1,158 +0,0 @@
#!/usr/bin/env python
# -*- coding: utf-8 -*-
"""
Created on 2018年3月24日
@author: Irony
@site: https://pyqt5.com, https://github.com/892768447
@email: 892768447@qq.com
@file: SimpleImageView
@description: 图片视图
"""
import struct
from time import time
from PIL import Image
from PIL.Image import fromarray
from PIL.ImageQt import fromqpixmap
from PyQt5.QtCore import QStandardPaths, Qt
from PyQt5.QtGui import QColor, QPainter, QPixmap, QImage, qRgb, qRed, qGreen,\
qBlue, QCursor
from PyQt5.QtWidgets import QGraphicsView, QGraphicsScene, QFileDialog, \
QGraphicsItem
import numpy
try:
from PyQt5.QtOpenGL import QGLFormat # , QGL, QGLWidget
hasOpenGL = True
except Exception as e:
print(e)
hasOpenGL = False
__Author__ = """By: Irony
QQ: 892768447
Email: 892768447@qq.com"""
__Copyright__ = 'Copyright (c) 2018 Irony'
__Version__ = 1.0
class SimpleImageView(QGraphicsView):
# 背景区域颜色
backgroundColor = QColor(28, 31, 34)
def __init__(self, *args, **kwargs):
super(SimpleImageView, self).__init__(*args, **kwargs)
# 设置背景颜色
self.setBackgroundBrush(self.backgroundColor)
# 缓存背景
self.setCacheMode(self.CacheBackground)
# 设置拖拽样式
# self.setDragMode(self.ScrollHandDrag)
self.setRenderHints(
QPainter.Antialiasing | QPainter.TextAntialiasing | QPainter.SmoothPixmapTransform)
# opengl
if hasOpenGL and QGLFormat.hasOpenGL():
# self.setViewport(QGLWidget(QGLFormat(QGL.SampleBuffers), self))
self.setRenderHint(QPainter.HighQualityAntialiasing)
self.setViewportUpdateMode(self.FullViewportUpdate)
else:
# 尝试通过分析需要重绘的区域来找到最佳的更新模式
self.setViewportUpdateMode(self.SmartViewportUpdate)
self._scene = QGraphicsScene(self)
self.setScene(self._scene)
# 图片item
self._itemImage = None
self._itemImageNew = None
def keyReleaseEvent(self, event):
"""按键处理事件"""
self._scaleImage(event)
super(SimpleImageView, self).keyReleaseEvent(event)
def closeEvent(self, event):
"""窗口关闭时清空场景中的所有item"""
self._scene.clear()
self._itemImage = None
self._itemImageNew = None
super(SimpleImageView, self).closeEvent(event)
def _scaleImage(self, event):
"""缩放图片操作"""
item = self._scene.focusItem()
if not item:
item = self._scene.items()
if not item:
return
item = item[0]
# 获取item的缩放度
scale = item.scale()
if event.key() == Qt.Key_Plus:
# 放大
if scale >= 0.91:
return
item.setScale(scale + 0.1)
elif event.key() == Qt.Key_Minus:
# 缩小
if scale <= 0.11:
return
item.setScale(scale - 0.1)
def loadImage(self):
path, _ = QFileDialog.getOpenFileName(
self, '请选择图片', QStandardPaths.writableLocation(QStandardPaths.DesktopLocation), '图片文件(*.jpg *.png)')
if not path:
return
if self._itemImageNew:
self._scene.removeItem(self._itemImageNew)
del self._itemImageNew
self._itemImageNew = None
if self._itemImage:
# 删除以前的item
self._scene.removeItem(self._itemImage)
del self._itemImage
self._itemImage = None
self._itemImage = self._scene.addPixmap(QPixmap(path))
self._itemImage.setFlag(QGraphicsItem.ItemIsMovable)
self._itemImage.setFlag(QGraphicsItem.ItemIsFocusable)
self._itemImage.setScale(0.1) # 默认加载比例
self._scene.setFocusItem(self._itemImage)
print(self._itemImage.zValue())
size = self._itemImage.pixmap().size()
# 调整图片在中间
self._itemImage.setPos(
-size.width() * self._itemImage.scale() / 2,
-size.height() * self._itemImage.scale() / 2
)
def _greyScale(self):
if not self._itemImage:
return
if self._itemImageNew:
self._scene.removeItem(self._itemImageNew)
del self._itemImageNew
self._itemImageNew = None
t = time()
# QPixmap 转 PIL Image 转 numpy array
image = numpy.array(fromqpixmap(self._itemImage.pixmap()).convert('L'))
image = fromarray(image).toqpixmap()
self._itemImageNew = self._scene.addPixmap(image)
self._itemImageNew.setFlag(QGraphicsItem.ItemIsFocusable)
self._itemImageNew.setFlag(QGraphicsItem.ItemIsMovable)
self._itemImageNew.setScale(self._itemImage.scale()) # 默认加载比例
self._scene.setFocusItem(self._itemImageNew)
print(self._itemImageNew.zValue())
print(time() - t)
if __name__ == '__main__':
import sys
from PyQt5.QtWidgets import QApplication
app = QApplication(sys.argv)
w = SimpleImageView()
w.resize(800, 600)
w.show()
sys.exit(app.exec_())

View file

@ -4,7 +4,7 @@
'''
Created on 2018年1月17日
@author: Irony."[讽刺]
@site: http://alyl.vip, http://orzorz.vip, https://coding.net/u/892768447, https://github.com/892768447
@site: https://pyqt5.com https://github.com/892768447
@email: 892768447@qq.com
@file: RestartMainWindow
@description:

View file

@ -1,7 +1,7 @@
'''
Created on 2018年1月30日
@author: Irony."[讽刺]
@site: http://alyl.vip, http://orzorz.vip, https://coding.net/u/892768447, https://github.com/892768447
@site: https://pyqt5.com https://github.com/892768447
@email: 892768447@qq.com
@file: CalendarWidget
@description: 日历

View file

@ -4,7 +4,7 @@
'''
Created on 2018年1月26日
@author: Irony."[讽刺]
@site: http://alyl.vip, http://orzorz.vip, https://coding.net/u/892768447, https://github.com/892768447
@site: https://pyqt5.com https://github.com/892768447
@email: 892768447@qq.com
@file: FileSystemModel
@description:

View file

@ -4,7 +4,7 @@
'''
Created on 2018年1月20日
@author: Irony."[讽刺]
@site: http://alyl.vip, http://orzorz.vip, https://coding.net/u/892768447, https://github.com/892768447
@site: https://pyqt5.com https://github.com/892768447
@email: 892768447@qq.com
@file: CircleLabel
@description:

View file

@ -4,7 +4,7 @@
'''
Created on 2018年1月17日
@author: Irony."[讽刺]
@site: http://alyl.vip, http://orzorz.vip, https://coding.net/u/892768447, https://github.com/892768447
@site: https://pyqt5.com https://github.com/892768447
@email: 892768447@qq.com
@file: critical
@description:

View file

@ -4,7 +4,7 @@
'''
Created on 2018年1月17日
@author: Irony."[讽刺]
@site: http://alyl.vip, http://orzorz.vip, https://coding.net/u/892768447, https://github.com/892768447
@site: https://pyqt5.com https://github.com/892768447
@email: 892768447@qq.com
@file: information
@description:

View file

@ -4,7 +4,7 @@
'''
Created on 2018年1月17日
@author: Irony."[讽刺]
@site: http://alyl.vip, http://orzorz.vip, https://coding.net/u/892768447, https://github.com/892768447
@site: https://pyqt5.com https://github.com/892768447
@email: 892768447@qq.com
@file: question
@description:

View file

@ -4,7 +4,7 @@
'''
Created on 2018年1月17日
@author: Irony."[讽刺]
@site: http://alyl.vip, http://orzorz.vip, https://coding.net/u/892768447, https://github.com/892768447
@site: https://pyqt5.com https://github.com/892768447
@email: 892768447@qq.com
@file: warning
@description:

View file

@ -4,7 +4,7 @@
'''
Created on 2018年1月17日
@author: Irony."[讽刺]
@site: http://alyl.vip, http://orzorz.vip, https://coding.net/u/892768447, https://github.com/892768447
@site: https://pyqt5.com https://github.com/892768447
@email: 892768447@qq.com
@file: critical
@description:

View file

@ -4,7 +4,7 @@
'''
Created on 2018年1月17日
@author: Irony."[讽刺]
@site: http://alyl.vip, http://orzorz.vip, https://coding.net/u/892768447, https://github.com/892768447
@site: https://pyqt5.com https://github.com/892768447
@email: 892768447@qq.com
@file: information
@description:

View file

@ -4,7 +4,7 @@
'''
Created on 2018年1月17日
@author: Irony."[讽刺]
@site: http://alyl.vip, http://orzorz.vip, https://coding.net/u/892768447, https://github.com/892768447
@site: https://pyqt5.com https://github.com/892768447
@email: 892768447@qq.com
@file: question
@description:

View file

@ -4,7 +4,7 @@
'''
Created on 2018年1月17日
@author: Irony."[讽刺]
@site: http://alyl.vip, http://orzorz.vip, https://coding.net/u/892768447, https://github.com/892768447
@site: https://pyqt5.com https://github.com/892768447
@email: 892768447@qq.com
@file: warning
@description:

View file

@ -4,7 +4,7 @@
'''
Created on 2018年1月30日
@author: Irony."[讽刺]
@site: http://alyl.vip, http://orzorz.vip, https://coding.net/u/892768447, https://github.com/892768447
@site: https://pyqt5.com https://github.com/892768447
@email: 892768447@qq.com
@file: ProgressBar
@description:

View file

@ -4,7 +4,7 @@
'''
Created on 2018年1月29日
@author: Irony."[讽刺]
@site: http://alyl.vip, http://orzorz.vip, https://coding.net/u/892768447, https://github.com/892768447
@site: https://pyqt5.com https://github.com/892768447
@email: 892768447@qq.com
@file: ButtonHover
@description:

View file

@ -4,7 +4,7 @@
'''
Created on 2018年2月1日
@author: Irony."[讽刺]
@site: http://alyl.vip, http://orzorz.vip, https://coding.net/u/892768447, https://github.com/892768447
@site: https://pyqt5.com https://github.com/892768447
@email: 892768447@qq.com
@file: PushButtonFont
@description:

View file

@ -4,7 +4,7 @@
'''
Created on 2018年2月1日
@author: Irony."[讽刺]
@site: http://alyl.vip, http://orzorz.vip, https://coding.net/u/892768447, https://github.com/892768447
@site: https://pyqt5.com https://github.com/892768447
@email: 892768447@qq.com
@file: PushButtonLine
@description:

View file

@ -4,7 +4,7 @@
'''
Created on 2018年1月20日
@author: Irony."[讽刺]
@site: http://alyl.vip, http://orzorz.vip, https://coding.net/u/892768447, https://github.com/892768447
@site: https://pyqt5.com https://github.com/892768447
@email: 892768447@qq.com
@file: ScrollBar
@description:

View file

@ -4,7 +4,7 @@
'''
Created on 2017年12月10日
@author: Irony."[讽刺]
@site: http://alyl.vip, http://orzorz.vip, https://coding.net/u/892768447, https://github.com/892768447
@site: https://pyqt5.com https://github.com/892768447
@email: 892768447@qq.com
@file: CustomPaintWidget
@description:

View file

@ -4,7 +4,7 @@
'''
Created on 2017年12月10日
@author: Irony."[讽刺]
@site: http://alyl.vip, http://orzorz.vip, https://coding.net/u/892768447, https://github.com/892768447
@site: https://pyqt5.com https://github.com/892768447
@email: 892768447@qq.com
@file: CustomWidget
@description:

View file

@ -4,7 +4,7 @@
'''
Created on 2017年12月10日
@author: Irony."[讽刺]
@site: http://alyl.vip, http://orzorz.vip, https://coding.net/u/892768447, https://github.com/892768447
@site: https://pyqt5.com https://github.com/892768447
@email: 892768447@qq.com
@file: test
@description: