python编程使用PyQt制作预览窗口游戏中的小地图
作者:在逆境中蜕变 发布时间:2023-12-29 09:54:24
写作思路
1、简述实现原理
2、部分代码解析
3、位置同步解析(①上下两屏位置同步②编辑屏位置保持不变)
效果图如下:
版本1:
这就是我们常见的预览窗口,上面预览窗口移动/缩放小方框都会导致下面的编辑界面位置发生变化,同理,下面的编辑界面的移动/缩放也会导致上面的小方框变化,并且上面预览图是编辑窗口的同比例缩放
版本2:
在版本1的基础上,加入了点的删除和增加,并对画布进行了扩展,同时保持编辑界面的画面位置不变
1、简述实现原理
首先最重要的,要知道我们这些是用QGraphicsView、QGraphicsScene、QGraphicsRectItem 这三个基类实现的
实现方法如下:
①QGraphicsScene.render渲染编辑窗口获得image,将image按照预览窗口的比例进行缩放并放入overView
②创建一个矩形框,框是按照编辑器窗口和image的比例进行绘制的
③拖动或者缩放预览窗口的时候,编辑窗口按照同样的比例移动缩放,拖动或者缩放预览窗口的时候同理
2、部分代码解析
①方框的完整代码
from PyQt5.QtCore import Qt, QRectF
from PyQt5.QtGui import QBrush, QPainterPath, QPainter, QColor, QPen
from PyQt5.QtWidgets import QGraphicsRectItem, QGraphicsItem
class GraphicsRectItem(QGraphicsRectItem):
def __init__(self, scene, *args):
super().__init__(*args)
self.scene = scene
self.setFlag(QGraphicsItem.ItemIsMovable, True)
self.setFlag(QGraphicsItem.ItemIsSelectable, True)
self.setFlag(QGraphicsItem.ItemSendsGeometryChanges, True)
self.setFlag(QGraphicsItem.ItemIsFocusable, True)
def shape(self):
path = QPainterPath()
path.addRect(self.rect())
return path
def paint(self, painter, option, widget=None):
# 框选出来的方形
painter.setBrush(QBrush(QColor(0, 0, 0, 0)))
painter.setPen(QPen(QColor(0, 0, 0), 0.1, Qt.SolidLine))
painter.drawRect(self.rect())
x = self.rect().x()
y = self.rect().y()
width = self.rect().width()
height = self.rect().height()
otherColor = QColor(150, 150, 150, 50)
painter.setBrush(QBrush(otherColor))
# 下面这部分代码是使得小方框以外的地方多一层蒙皮
painter.setPen(QPen(QColor(0, 0, 0, 0), 1.0, Qt.SolidLine))
painter.drawRect(QRectF(x-10000, y, 20000+width, -20000+height)) #上
painter.drawRect(QRectF(x-10000, y+height, 20000+width, 20000+height)) #下
painter.drawRect(QRectF(x, y, -20000, height)) #左
painter.drawRect(QRectF(x+width, y, 20000, height)) #右
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))
这就是前面提到的 “item” 《scene view item的使用》,QGraphicsRectItem 也是继承自QGraphicsItem的,这里的方框就是我们要加到OverView界面中的那个定位方框
②编辑界面
class GraphicsWindow(QGraphicsView):
def __init__(self, parent=None):
super(GraphicsWindow, self).__init__(parent)
......
self.scene = ViewPortGraphScene(self)
self.setScene(self.scene)
......
self.setSceneRect(-1 << 30, -1 << 30, 1 << 31, 1 << 31)
self.setHorizontalScrollBarPolicy(Qt.ScrollBarAlwaysOff)
self.setVerticalScrollBarPolicy(Qt.ScrollBarAlwaysOff)
def addPoint(self, x, y):
self.scene.addEllipse(x, y, 16, 16, QPen(QColor(Qt.red)), QBrush(QColor(Qt.red)))
def mousePressEvent(self, mouseEvent):
......
if mouseEvent.button() == Qt.LeftButton:
if isinstance(self.itemAt(mouseEvent.pos()), QGraphicsEllipseItem):
self.scene.removeItem(self.itemAt(mouseEvent.pos()))
self.parent.changeView()
......
super(GraphicsWindow, self).mousePressEvent(mouseEvent)
class ViewPortGraphScene(QGraphicsScene):
def __init__(self, parent=None):
super(ViewPortGraphScene, self).__init__(parent)
......
def drawBackground(self, painter, rect):
# 自己去画格子吧 hhh
熟悉的操作:
1、创建scene
2、把scene放到view
3、把item放到scene,其中这里的item是点也就是QGraphicsEllipseItem,也是继承自QGraphicsRectItem
使屏幕可以拖动: self.setSceneRect(-1 << 30, -1 << 30, 1 << 31, 1 << 31),因为scene很大,在view里面装不下,所以就可以拖动啦~
**添加点:**如上的addPoint方法
**删除点:**如上的mousePressEvent方法,其中self.itemAt(mouseEvent.pos())可以获取当前鼠标位置是什么东西
③预览窗口
class OverViewGraphicsWindow(QGraphicsView):
def __init__(self, parent=None):
super(OverViewGraphicsWindow, self).__init__(parent)
......
self.scene = OverViewGraphScene(self)
self.item = GraphicsRectItem(self.scene, 0, 0, 50, 25)
self.scene.addItem(self.item)
......
......
class OverViewGraphScene(QGraphicsScene):
def __init__(self, parent=None):
super(OverViewGraphScene, self).__init__(parent)
同样的套路:
1、创建scene
2、把scene放到view
3、把item放到scene,其中这里的item是点也就是QGraphicsRectItem,继承自QGraphicsRectItem
3、位置同步解析
①上下两屏位置同步、编辑屏位置保持不变
1、两个pyqtSignal 分别去响应上下两个屏幕的移动和缩放
2、scene的的左上角到当前屏幕中心的长宽来定位(主要用到scene.itemsBoundingRect()、view.mapToScene()、view.mapFromScene()这几个方法),屏幕中心的scene位置可以通过编辑窗口长宽的一半并通过view.mapToScene()来转化
来源:https://blog.csdn.net/weixin_40301728/article/details/109654031
猜你喜欢
- 一些杀毒软件经常会把某些asp文件当成病毒删除,如卡巴斯基杀毒软件就经常把网页中有Microsoft.XMLHTTP 的当作病毒,有时简直防
- 原文地址:30 Days of Mootools 1.2 Tutorials - Day 19 - TooltipsMootools 1.2
- 使用 NetBox 可以方便的将 asp 应用编译成为独立运行的执行程序,完全摆脱 iis 的束缚,在几乎所有的 Windows 版本上面直
- 我用textarea提交大量的阿数据 我开始字段类型选的是mediumtext,数据有丢失 后来我改成了longtext,数据依然丢失, 而
- Server对象主要是给编程人员提供一些方便的对象和属性。(1)ScriptTimeout属性:<%Server.ScriptTime
- 异步操作数据的方式有两种常见的方式:XMLHttpRequest 和 iframe. 孰优孰劣在此我们不争论,只是想举一个例子说明在获取网片
- 系列一:图片格式介绍Gif格式特点透明性Gif是一种布尔透明类型,既它可以是全透明,也可以是全不透明,但是它并没有半透明(alpha 透明)
- 内容摘要:这篇文章的主旨是弄清楚如何根据实际需求实现一个联动菜单以及联动菜单的原理,实例是实现一个日期选择下拉菜单。首先来分析一下日期下拉菜
- 由于某些原因需要把函数直接放到 img 标签上的 onload 属性执行,比如:For some reasons we have to ex
- 一:绑定方法:其特点是调用方本身自动作为第一个参数传入1.绑定到对象的方法:调用方是一个对象,该对象自动传入2.方法绑定到类:调用方是类,类
- ALTER TABLE将表更改为当前字符集。如果在执行ALTER TABLE操作期间遇到重复键错误,原因在于新的字符集将2个键映射到了相同值
- 先来看一张简单的文档树很明显树的顶层节点是NodeA节点,接下来可以通过指定的合适节点移动到树中的任何点,结合以下的代码你可以更好的了解这棵
- 简单的仿图片验证码,适合新手简单的仿图片验证码演示,很容易被破解,实用性不大,但拿出来给新手学习一下还是不错的:JScript.Asp代码示
- 本文实例讲述了python 实现的发送邮件模板。分享给大家供大家参考,具体如下:##发送普通txt文件(与发送html邮件不同的是邮件内容设
- 代码如下:Function getTreeRootId(pNodeId) getSQL = "select note_id,par
- 很多朋友对FrontPage2003中增加的网页布局功能很感兴趣,现在我们一起来深入了解这一实用功能。 用FrontPage200
- 目前代码应该没什么bug了,兼容IE6.0 & FF 1.5, 通过xHTML 的Transitional验证和 CSS 验证。为了
- 选项default-charaset-set=utf8;然后创建一个数据表 create table a_table(b varchar(2
- 一个小代码 类似资源管理器效果 支持鼠标拖拽 没写些细节东西 JavaScript语言:
- 前言图片是Word的一种特殊内容,这篇文章主要介绍了关于Python操作word文档,向里面插入图片和表格的相关内容,下面话不多说了,来一起