update
|
@ -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">
|
||||
|
|
|
@ -1 +0,0 @@
|
|||
# Animation
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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:
|
||||
|
|
|
@ -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:
|
||||
|
|
|
@ -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: 下拉联动
|
||||
|
|
|
@ -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:
|
||||
|
|
|
@ -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
|
|
@ -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)
|
Before Width: | Height: | Size: 4.9 KiB After Width: | Height: | Size: 4.9 KiB |
BIN
QGraphicsView/ScreenShot/WorldMap.gif
Normal file
After Width: | Height: | Size: 460 KiB |
|
@ -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:
|
|
@ -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:
|
||||
|
|
|
@ -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:
|
||||
|
|
|
@ -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:
|
||||
|
|
Before Width: | Height: | Size: 47 KiB After Width: | Height: | Size: 47 KiB |
Before Width: | Height: | Size: 40 KiB After Width: | Height: | Size: 40 KiB |
Before Width: | Height: | Size: 45 KiB After Width: | Height: | Size: 45 KiB |
Before Width: | Height: | Size: 41 KiB After Width: | Height: | Size: 41 KiB |
Before Width: | Height: | Size: 57 KiB After Width: | Height: | Size: 57 KiB |
Before Width: | Height: | Size: 47 KiB After Width: | Height: | Size: 47 KiB |
Before Width: | Height: | Size: 64 KiB After Width: | Height: | Size: 64 KiB |
Before Width: | Height: | Size: 89 KiB After Width: | Height: | Size: 89 KiB |
Before Width: | Height: | Size: 53 KiB After Width: | Height: | Size: 53 KiB |
Before Width: | Height: | Size: 107 KiB After Width: | Height: | Size: 107 KiB |
1
QPropertyAnimation/README.en.md
Normal file
|
@ -0,0 +1 @@
|
|||
# QPropertyAnimation
|
|
@ -1,4 +1,4 @@
|
|||
# Animation
|
||||
# QPropertyAnimation
|
||||
|
||||
# 1、窗口淡入淡出
|
||||
[运行 FadeInOut.py](FadeInOut.py)
|
Before Width: | Height: | Size: 630 KiB After Width: | Height: | Size: 630 KiB |
Before Width: | Height: | Size: 78 KiB After Width: | Height: | Size: 78 KiB |
Before Width: | Height: | Size: 1.6 MiB After Width: | Height: | Size: 1.6 MiB |
Before Width: | Height: | Size: 1.7 MiB After Width: | Height: | Size: 1.7 MiB |
|
@ -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:
|
||||
|
|
|
@ -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:
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -4,7 +4,7 @@
|
|||
'''
|
||||
Created on 2018年05月01日
|
||||
@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: qrctest1
|
||||
@description:
|
||||
|
|
|
@ -4,7 +4,7 @@
|
|||
'''
|
||||
Created on 2018年05月01日
|
||||
@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: qrctest2
|
||||
@description:
|
||||
|
|
|
@ -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: OpencvWidget
|
||||
@description:
|
||||
|
|
|
@ -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:
|
||||
|
|
|
@ -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: BubbleTips
|
||||
@description:
|
||||
|
|
|
@ -4,7 +4,7 @@
|
|||
'''
|
||||
Created on 2018年1月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: IronyImporter
|
||||
@description:
|
||||
|
|
|
@ -4,7 +4,7 @@
|
|||
'''
|
||||
Created on 2018年1月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: build
|
||||
@description:
|
||||
|
|
|
@ -4,7 +4,7 @@
|
|||
'''
|
||||
Created on 2018年1月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: main
|
||||
@description:
|
||||
|
|
|
@ -4,7 +4,7 @@
|
|||
'''
|
||||
Created on 2018年1月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: test
|
||||
@description:
|
||||
|
|
|
@ -1,12 +0,0 @@
|
|||
# 图形视图QGraphicsView
|
||||
|
||||
## [1、 世界地图](世界地图/)
|
||||
![截图](世界地图/ScreenShot/2.png)
|
||||
|
||||
## [2、 添加QWidget](添加QWidget.py)
|
||||
![添加QWidget](ScreenShot/添加QWidget.png)
|
||||
|
||||
## [3、 显示图片及缩放](显示图片及缩放.py)
|
||||
按下小键盘-为缩小, +为放大
|
||||
|
||||
![显示图片及缩放](ScreenShot/显示图片及缩放.gif)
|
Before Width: | Height: | Size: 381 KiB |
|
@ -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_())
|
|
@ -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_())
|
294
图形视图/test/调整.py
|
@ -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()
|
|
@ -1,6 +0,0 @@
|
|||
# 描绘世界地图
|
||||
|
||||
世界地图-使用Ctrl+滑轮进行放大缩小
|
||||
|
||||
![ScreenShot1](ScreenShot/1.png)
|
||||
![ScreenShot2](ScreenShot/1.png)
|
Before Width: | Height: | Size: 103 KiB |
Before Width: | Height: | Size: 141 KiB |
108
图形视图/显示图片及缩放.py
|
@ -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_())
|
|
@ -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_())
|
|
@ -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
|
|
@ -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_())
|
|
@ -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:
|
||||
|
|
|
@ -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: 日历
|
||||
|
|
|
@ -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:
|
||||
|
|
|
@ -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:
|
||||
|
|
|
@ -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:
|
||||
|
|
|
@ -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:
|
||||
|
|
|
@ -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:
|
||||
|
|
|
@ -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:
|
||||
|
|
|
@ -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:
|
||||
|
|
|
@ -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:
|
||||
|
|
|
@ -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:
|
||||
|
|
|
@ -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:
|
||||
|
|
|
@ -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:
|
||||
|
|
|
@ -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:
|
||||
|
|
|
@ -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:
|
||||
|
|
|
@ -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:
|
||||
|
|
|
@ -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:
|
||||
|
|
|
@ -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:
|
||||
|
|
|
@ -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:
|
||||
|
|
|
@ -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:
|
||||
|
|