This commit is contained in:
Irony 2017-12-17 14:13:13 +08:00
parent 9ccad8c431
commit 08e9c377d7
10 changed files with 482 additions and 111 deletions

8
.gitignore vendored
View file

@ -1,3 +1,7 @@
tmp /tmp/
tmp/* /tmp/*
*.pyc *.pyc
.setting
tmp
.project
.pydevproject

View file

@ -0,0 +1,17 @@
eclipse.preferences.version=1
encoding//QGraphicsView\u7EC3\u4E60/WorldMap.py=utf-8
encoding//tmp/GraphiscView.py=utf-8
encoding//tmp/PyQtChart\u5E73\u6ED1\u66F2\u7EBF/SplineSeries.py=utf-8
encoding//tmp/\u622A\u56FE\u753B\u77E9\u5F62/DrawRectangle.py=utf-8
encoding//\u5168\u5C40\u70ED\u952E/HotKey.py=utf-8
encoding//\u5B57\u4F53\u6D4B\u8BD5/FontAwesome.py=utf-8
encoding//\u5B57\u4F53\u6D4B\u8BD5/TestFontRoboto.py=utf-8
encoding//\u68A6\u5E7B\u6811/DreamTree.py=utf-8
encoding//\u6D4F\u89C8\u5668\u83B7\u53D6Cookie/WebEngineView.py=utf-8
encoding//\u6D4F\u89C8\u5668\u83B7\u53D6Cookie/WebView.py=utf-8
encoding//\u7A0B\u5E8F\u91CD\u542F/AutoRestart.py=utf-8
encoding//\u81EA\u52A8\u66F4\u65B0/mylibs/testlibs.py=utf-8
encoding//\u81EA\u52A8\u66F4\u65B0/test.py=utf-8
encoding//\u81EA\u5B9A\u4E49QWidget\u7684QSS\u6837\u5F0F/CustomPaintWidget.py=utf-8
encoding//\u81EA\u5B9A\u4E49QWidget\u7684QSS\u6837\u5F0F/CustomWidget.py=utf-8
encoding//\u81EA\u5B9A\u4E49QWidget\u7684QSS\u6837\u5F0F/test.py=utf-8

View file

@ -0,0 +1,6 @@
# QGraphicsView练习
# 截图
世界地图
<img src="ScreenShot/1.png" />
<img src="ScreenShot/2.png" />

Binary file not shown.

After

Width:  |  Height:  |  Size: 103 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 141 KiB

View file

@ -0,0 +1,166 @@
#!/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
@email: 892768447@qq.com
@file: WorldMap
@description:
'''
import json
import math
from PyQt5.QtCore import Qt, QPointF, QRectF
from PyQt5.QtGui import QColor, QPainter, QPolygonF, QPen, QBrush
from PyQt5.QtOpenGL import QGLFormat
from PyQt5.QtWidgets import QGraphicsView, QGraphicsScene, QGraphicsPolygonItem
__Author__ = "By: Irony.\"[讽刺]\nQQ: 892768447\nEmail: 892768447@qq.com"
__Copyright__ = "Copyright (c) 2017 Irony.\"[讽刺]"
__Version__ = "Version 1.0"
class GraphicsView(QGraphicsView):
# 背景区域颜色
backgroundColor = QColor(31, 31, 47)
# 边框颜色
borderColor = QColor(58, 58, 90)
def __init__(self, *args, **kwargs):
super(GraphicsView, self).__init__(*args, **kwargs)
self.resize(800, 600)
# 设置背景颜色
self.setBackgroundBrush(self.backgroundColor)
'''
#参考 http://doc.qt.io/qt-5/qgraphicsview.html#CacheModeFlag-enum
CacheNone 不使用缓存
CacheBackground 缓存背景
'''
self.setCacheMode(self.CacheBackground)
'''
#参考 http://doc.qt.io/qt-5/qgraphicsview.html#DragMode-enum
NoDrag 什么都没发生; 鼠标事件被忽略
ScrollHandDrag 光标变成指针拖动鼠标将滚动滚动条 该模式可以在交互式和非交互式模式下工作
RubberBandDrag 拖动鼠标将设置橡皮筋几何形状并选择橡皮筋所覆盖的所有项目 对于非交互式视图此模式被禁用
'''
self.setDragMode(self.ScrollHandDrag)
'''
#参考 http://doc.qt.io/qt-5/qgraphicsview.html#OptimizationFlag-enum
DontClipPainter 已过时
DontSavePainterState 渲染时QGraphicsView在渲染背景或前景时以及渲染每个项目时保护painter状态请参阅QPainter.save() 这允许你离开painter处于改变状态即你可以调用QPainter.setPen()或QPainter.setBrush()而不需要在绘制之后恢复状态 但是如果项目一致地恢复状态则应启用此标志以防止QGraphicsView执行相同的操作
DontAdjustForAntialiasing 禁用QGraphicsView的抗锯齿自动调整曝光区域 在QGraphicsItem.boundingRect()的边界上渲染反锯齿线的项目可能会导致渲染部分线外 为了防止渲染失真QGraphicsView在所有方向上将所有曝光区域扩展2个像素 如果启用此标志QGraphicsView将不再执行这些调整最大限度地减少需要重绘的区域从而提高性能 一个常见的副作用是使用抗锯齿功能进行绘制的项目可能会在移动时在画面上留下绘画痕迹
IndirectPainting 从Qt 4.6开始恢复调用QGraphicsView.drawItems()和QGraphicsScene.drawItems()的旧绘画算法 仅用于与旧代码的兼容性
'''
self.setOptimizationFlag(self.DontSavePainterState)
'''
#参考 http://doc.qt.io/qt-5/qpainter.html#RenderHint-enum
Antialiasing 抗锯齿
TextAntialiasing 文本抗锯齿
SmoothPixmapTransform 平滑像素变换算法
HighQualityAntialiasing 请改用Antialiasing
NonCosmeticDefaultPen 已过时
Qt4CompatiblePainting 从Qt4移植到Qt5可能有用
'''
self.setRenderHints(QPainter.Antialiasing | QPainter.TextAntialiasing |
QPainter.SmoothPixmapTransform)
if QGLFormat.hasOpenGL():
self.setRenderHint(QPainter.HighQualityAntialiasing)
'''
#当视图被调整大小时,视图如何定位场景。使用这个属性来决定当视口控件的大小改变时,如何在视口中定位场景。 缺省行为NoAnchor在调整大小的过程中不改变场景的位置; 视图的左上角将显示为在调整大小时被锚定。请注意,只有场景的一部分可见(即有滚动条时),此属性的效果才明显。 否则如果整个场景适合视图QGraphicsScene使用视图对齐将视景中的场景定位。
#参考 http://doc.qt.io/qt-5/qgraphicsview.html#ViewportAnchor-enum
NoAnchor 视图保持场景的位置不变
AnchorViewCenter 视图中心被用作锚点
AnchorUnderMouse 鼠标当前位置被用作锚点
'''
self.setResizeAnchor(self.AnchorUnderMouse)
'''
Rubber选择模式
#参考 http://doc.qt.io/qt-5/qt.html#ItemSelectionMode-enum
ContainsItemShape 输出列表仅包含形状完全包含在选择区域内的项目 不包括与区域轮廓相交的项目
IntersectsItemShape 默认输出列表包含其形状完全包含在选择区域内的项目以及与区域轮廓相交的项目
ContainsItemBoundingRect 输出列表仅包含边界矩形完全包含在选择区域内的项目 不包括与区域轮廓相交的项目
IntersectsItemBoundingRect 输出列表包含边界矩形完全包含在选择区域内的项目以及与区域轮廓相交的项目 这种方法通常用于确定需要重绘的区域
'''
self.setRubberBandSelectionMode(Qt.IntersectsItemShape)
'''
#在转换过程中如何定位视图。QGraphicsView使用这个属性决定当变换矩阵改变时如何在视口中定位场景并且视图的坐标系被变换。 默认行为AnchorViewCenter确保在视图中心的场景点在变换过程中保持不变例如在旋转时场景将围绕视图的中心旋转。请注意只有场景的一部分可见即有滚动条时此属性的效果才明显。 否则如果整个场景适合视图QGraphicsScene使用视图对齐将视景中的场景定位。
#参考 http://doc.qt.io/qt-5/qgraphicsview.html#ViewportAnchor-enum
NoAnchor 视图保持场景的位置不变
AnchorViewCenter 视图中心被用作锚点
AnchorUnderMouse 鼠标当前位置被用作锚点
'''
self.setTransformationAnchor(self.AnchorUnderMouse)
# if QGLFormat.hasOpenGL(): # 如果开启了OpenGL则使用OpenGL Widget
# self.setViewport(QGLWidget(QGLFormat(QGL.SampleBuffers)))
'''
#参考 http://doc.qt.io/qt-5/qgraphicsview.html#ViewportUpdateMode-enum
FullViewportUpdate 当场景的任何可见部分改变或重新显示时QGraphicsView将更新整个视口 当QGraphicsView花费更多的时间来计算绘制的内容比如重复更新很多小项目这种方法是最快的 这是不支持部分更新如QGLWidget的视口以及需要禁用滚动优化的视口的首选更新模式
MinimalViewportUpdate QGraphicsView将确定需要重绘的最小视口区域通过避免重绘未改变的区域来最小化绘图时间 这是QGraphicsView的默认模式 虽然这种方法提供了一般的最佳性能但如果场景中有很多小的可见变化QGraphicsView最终可能花费更多的时间来寻找最小化的方法
SmartViewportUpdate QGraphicsView将尝试通过分析需要重绘的区域来找到最佳的更新模式
BoundingRectViewportUpdate 视口中所有更改的边界矩形将被重绘 这种模式的优点是QGraphicsView只搜索一个区域的变化最大限度地减少了花在确定需要重绘的时间 缺点是还没有改变的地方也需要重新绘制
NoViewportUpdate 当场景改变时QGraphicsView将永远不会更新它的视口 预计用户将控制所有更新 此模式禁用QGraphicsView中的所有可能较慢项目可见性测试适用于要求固定帧速率或视口以其他方式在外部进行更新的场景
'''
self.setViewportUpdateMode(self.SmartViewportUpdate)
# 设置场景(根据地图的经纬度,并让原点显示在屏幕中间)
self._scene = QGraphicsScene(-180, -90, 360, 180, self)
self.setScene(self._scene)
# 初始化地图
self.initMap()
def wheelEvent(self, event):
# 滑轮事件
if event.modifiers() & Qt.ControlModifier:
self.scaleView(math.pow(2.0, -event.angleDelta().y() / 240.0))
return event.accept()
super(GraphicsView, self).wheelEvent(event)
def scaleView(self, scaleFactor):
factor = self.transform().scale(
scaleFactor, scaleFactor).mapRect(QRectF(0, 0, 1, 1)).width()
if factor < 0.07 or factor > 100:
return
self.scale(scaleFactor, scaleFactor)
def initMap(self):
features = json.load(
open("world.json", encoding="utf8")).get("features")
for feature in features:
geometry = feature.get("geometry")
if not geometry:
continue
_type = geometry.get("type")
coordinates = geometry.get("coordinates")
for coordinate in coordinates:
if _type == "Polygon":
polygon = QPolygonF(
[QPointF(latitude, -longitude) for latitude, longitude in coordinate])
item = QGraphicsPolygonItem(polygon)
item.setPen(QPen(self.borderColor, 0))
item.setBrush(QBrush(self.backgroundColor))
item.setPos(0, 0)
self._scene.addItem(item)
elif _type == "MultiPolygon":
for _coordinate in coordinate:
polygon = QPolygonF(
[QPointF(latitude, -longitude) for latitude, longitude in _coordinate])
item = QGraphicsPolygonItem(polygon)
item.setPen(QPen(self.borderColor, 0))
item.setBrush(QBrush(self.backgroundColor))
item.setPos(0, 0)
self._scene.addItem(item)
if __name__ == "__main__":
import sys
from PyQt5.QtWidgets import QApplication
app = QApplication(sys.argv)
print("OpenGL Status:", QGLFormat.hasOpenGL())
view = GraphicsView()
view.setWindowTitle("世界地图")
view.show()
sys.exit(app.exec_())

File diff suppressed because one or more lines are too long

View file

@ -1,104 +0,0 @@
#!/usr/bin/env python
# -*- coding: utf-8 -*-
'''
Created on 2017年12月10日
@author: Irony."[讽刺]
@site: http://alyl.vip, http://orzorz.vip, https://coding.net/u/892768447, https://github.com/892768447
@email: 892768447@qq.com
@file: DrawRectangle
@description:
'''
import sys
from PyQt5.QtCore import Qt, QRect, QRectF
from PyQt5.QtGui import QPainter, QColor, QPen, QPainterPath
from PyQt5.QtWidgets import QApplication, QDialog
__Author__ = "By: Irony.\"[讽刺]\nQQ: 892768447\nEmail: 892768447@qq.com"
__Copyright__ = "Copyright (c) 2017 Irony.\"[讽刺]"
__Version__ = "Version 1.0"
class DrawRectangle(QDialog):
def __init__(self, *args, **kwargs):
super(DrawRectangle, self).__init__(*args, **kwargs)
self.pressed = False
self.moved = False
self.rectArea = QRect() # 矩形框
self.rectPen = QPen(QColor(22, 168, 250))
self.rectPen.setWidth(1)
self.setMouseTracking(True)
self.setWindowFlags(Qt.FramelessWindowHint)
self.setAttribute(Qt.WA_TranslucentBackground, True)
self.showMaximized()
# 通过绑定自定义右键菜单来监听右键点击,实现重新画区域或者退出,或者弹出菜单
self.setContextMenuPolicy(Qt.CustomContextMenu)
self.customContextMenuRequested.connect(self.onRightClicked)
def onRightClicked(self, _):
if not self.rectArea.isNull():
self.rectArea.setWidth(0)
self.rectArea.setHeight(0) # clear
return self.update()
self.close()
def mousePressEvent(self, event):
if event.buttons() == Qt.LeftButton:
self.pressed = True
# if not self.rectArea.isNull():
# self.moved = self.rectArea.contains(
# event.pos()) # 设置画好的窗口可整体移动
# return
self.rectArea.setTopLeft(event.pos()) # 设置左上角位置
def mouseReleaseEvent(self, event):
self.pressed = False
self.moved = False
super(DrawRectangle, self).mouseReleaseEvent(event)
def mouseMoveEvent(self, event):
pos = event.pos()
# if self.moved and not self.rectArea.isNull(): # 表示移动整体画好的矩形框
# # 重新设置矩形框的位置
# self.rectArea.setX(pos.x())
# self.rectArea.setY(pos.y())
# return self.update()
if not self.pressed:
if not self.rectArea.isNull():
if self.rectArea.contains(pos):
# 设置鼠标形状为十字箭头
return self.setCursor(Qt.SizeAllCursor)
# 设置鼠标为普通形状
return self.setCursor(Qt.ArrowCursor)
self.rectArea.setBottomRight(pos) # 设置右下角位置
self.update()
def paintEvent(self, event):
painter = QPainter(self)
if self.rectArea.isNull():
# 窗口背景全部半透明颜色
return painter.fillRect(self.rect(), QColor(0, 0, 0, 50))
# 画外围背景,去掉中间绘制的矩形框
path = QPainterPath()
path.setFillRule(Qt.OddEvenFill)
path.addRect(QRectF(self.rect()))
path.addRect(QRectF(self.rectArea))
painter.fillPath(path, QColor(0, 0, 0, 50))
# 画矩形
painter.save()
painter.setPen(self.rectPen)
painter.drawRect(self.rectArea) # 画矩形框
# 背景用白色透明遮住,防止鼠标穿透到桌面
painter.fillRect(self.rectArea, QColor(255, 255, 255, 1))
painter.restore()
if __name__ == "__main__":
app = QApplication(sys.argv)
w = DrawRectangle()
w.show()
sys.exit(app.exec_())

View file

@ -1,5 +0,0 @@
# 仿截图软件画矩形框,暂时只实现了矩形框的绘制,框的移动和大小调整还未实现<br />
右键退出矩形框或退出程序
# 截图
<img src="ScreenShot/1.gif" />

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.3 MiB