Python 如何访问可移动QGraphics站点的位置偏移?
我最近开始使用PythonQt,我正在尝试制作一个点击拖动的映射编辑器,它可以读取和写入.json文件。到目前为止,我的进展是让QGraphicsView能够准确地动态显示整个房间的矩形布局。但是现在我不知道如何访问每个矩形的x和y偏移,因为它们都可以通过setFlag(QGraphicsItem.ItemIsMovable)属性单独移动 以下是我的代码的简短版本:Python 如何访问可移动QGraphics站点的位置偏移?,python,offset,qgraphicsitem,pyside6,movable,Python,Offset,Qgraphicsitem,Pyside6,Movable,我最近开始使用PythonQt,我正在尝试制作一个点击拖动的映射编辑器,它可以读取和写入.json文件。到目前为止,我的进展是让QGraphicsView能够准确地动态显示整个房间的矩形布局。但是现在我不知道如何访问每个矩形的x和y偏移,因为它们都可以通过setFlag(QGraphicsItem.ItemIsMovable)属性单独移动 以下是我的代码的简短版本: import json import sys from PySide6.QtCore import * from PySide6.
import json
import sys
from PySide6.QtCore import *
from PySide6.QtGui import *
from PySide6.QtWidgets import *
TILEWIDTH = 25
TILEHEIGHT = 15
OUTLINE = 3
class Room:
def __init__(self, name, width, height, offset_x, offset_z):
self.name = name
self.width = width
self.height = height
self.offset_x = offset_x
self.offset_z = offset_z
class Main(QMainWindow):
def __init__(self):
super().__init__()
self.initUI()
def initUI(self):
#Setting up viewport
self.scene = QGraphicsScene(self)
self.view = QGraphicsView(self.scene, self)
self.view.scale(1, -1)
self.view.setStyleSheet("background:transparent; border: 0px")
self.setCentralWidget(self.view)
self.setGeometry(360, 190, 1200, 700)
self.showMaximized()
#Reading json and converting entries to rooms
self.room_list = []
with open("Data\Content\PB_DT_RoomMaster.json", "r") as file_reader:
self.content = json.load(file_reader)
for i in self.content:
self.room_list.append(self.convert_json_to_room(i))
self.draw_map()
def convert_json_to_room(self, json):
name = json["Key"]
width = json["Value"]["AreaWidthSize"] * TILEWIDTH
height = json["Value"]["AreaHeightSize"] * TILEHEIGHT
offset_x = round(json["Value"]["OffsetX"]/12.6) * TILEWIDTH
offset_z = round(json["Value"]["OffsetZ"]/7.2) * TILEHEIGHT
room = Room(name, width, height, offset_x, offset_z)
return room
def draw_map(self):
for i in self.room_list:
fill = QColor("#000000")
outline = QPen("#ffffff")
outline.setWidth(OUTLINE)
outline.setJoinStyle(Qt.MiterJoin)
#Drawing rooms
rect = self.scene.addRect(i.offset_x, i.offset_z, i.width, i.height, outline, fill)
rect.setFlag(QGraphicsItem.ItemIsMovable)
def main():
app = QApplication(sys.argv)
main = Main()
main.show()
sys.exit(app.exec_())
if __name__ == '__main__':
main()
这是json:
[
{
"Key": "m01SIP_000",
"Value": {
"LevelName": "m01SIP_000",
"EnemyPatternSuffix": "",
"AreaID": "EAreaID::m01SIP",
"SameRoom": "None",
"AdjacentRoomName": [
"m01SIP_001",
"m01SIP_024",
"m01SIP_023"
],
"OutOfMap": false,
"EventFlagNameForShowEventIfNotSeen": "None",
"EventFlagNameForMarkEventAsSeen": "None",
"WarpPositionX": 0.0,
"WarpPositionY": 0.0,
"WarpPositionZ": 0.0,
"RoomType": "ERoomType::Normal",
"RoomPath": "ERoomPath::Both",
"ConsiderLeft": true,
"ConsiderRight": true,
"ConsiderTop": true,
"ConsiderBottom": true,
"AreaWidthSize": 2,
"AreaHeightSize": 1,
"OffsetX": 25.2,
"OffsetZ": 0.0,
"DoorFlag": [
2,
32
],
"HiddenFlag": [],
"RoomCollisionFromSplineOnly": false,
"RoomCollisionFromGimmick": false,
"NoRoomOutBlinder": false,
"Collision2DProjectionDistance": -1.0,
"FlyMaterialDistance": 10.0,
"NoTraverse": [],
"MagCameraFovScale": 0.0,
"MagCameraVolumeScale": 1.5,
"DemagCameraFovScale": 0.77,
"DemagCameraVolumeScale": 0.0,
"BgmID": "BGM_m01SIP",
"BgmType": "ERoomBgmType::PlayNormal",
"Amb1": "AMB_01SIP_Ship_Roll01",
"AmbVol1": 70,
"Amb2": "",
"AmbVol2": 0,
"Amb3": "",
"AmbVol3": 0,
"Amb4": "",
"AmbVol4": 0,
"Decay_Near": 1260.0,
"Decay_Far": 2520.0,
"Decay_Far_Volume": 0.5,
"UseLava": false,
"FrameType": "EFramePlateType::FPT_Full",
"PerfLevel": 1
}
},
{
"Key": "m01SIP_001",
"Value": {
"LevelName": "m01SIP_001",
"EnemyPatternSuffix": "",
"AreaID": "EAreaID::m01SIP",
"SameRoom": "None",
"AdjacentRoomName": [
"m01SIP_000",
"m01SIP_023",
"m01SIP_002"
],
"OutOfMap": false,
"EventFlagNameForShowEventIfNotSeen": "None",
"EventFlagNameForMarkEventAsSeen": "None",
"WarpPositionX": 0.0,
"WarpPositionY": 0.0,
"WarpPositionZ": 0.0,
"RoomType": "ERoomType::Normal",
"RoomPath": "ERoomPath::Both",
"ConsiderLeft": true,
"ConsiderRight": true,
"ConsiderTop": true,
"ConsiderBottom": true,
"AreaWidthSize": 3,
"AreaHeightSize": 1,
"OffsetX": 50.4,
"OffsetZ": 0.0,
"DoorFlag": [
1,
24,
3,
8
],
"HiddenFlag": [],
"RoomCollisionFromSplineOnly": false,
"RoomCollisionFromGimmick": false,
"NoRoomOutBlinder": false,
"Collision2DProjectionDistance": -1.0,
"FlyMaterialDistance": 10.0,
"NoTraverse": [],
"MagCameraFovScale": 0.0,
"MagCameraVolumeScale": 1.5,
"DemagCameraFovScale": 0.77,
"DemagCameraVolumeScale": 0.0,
"BgmID": "BGM_m01SIP",
"BgmType": "ERoomBgmType::PlayNormal",
"Amb1": "AMB_01SIP_Ship_Roll01",
"AmbVol1": 70,
"Amb2": "AMB_01SIP_Wind02_LP",
"AmbVol2": 70,
"Amb3": "",
"AmbVol3": 0,
"Amb4": "",
"AmbVol4": 0,
"Decay_Near": 1260.0,
"Decay_Far": 2520.0,
"Decay_Far_Volume": 0.5,
"UseLava": false,
"FrameType": "EFramePlateType::FPT_Full",
"PerfLevel": 1
}
},
...
基本上,我需要在地图编辑器上移动json中每个房间后,更新其偏移量。最好的方法是什么?您没有将偏移设置为矩形的参数,因为稍后必须进行转换,因为它位于项目的局部坐标中,而使用场景坐标中的方法pos():
rect=self.scene.addRect(0,0,i.width,i.height,outline,fill)
矩形设置位置(i.offset_x,i.offset_z)
rect.setFlag(QGraphicsItem.ItemIsMovable)
然后,您可以在执行以下操作后获得该职位:
i.offset_x=rect.pos().x()
i、 偏移量z=rect.pos().y()
我不认为有必要将信息分开,因为您可以创建一个存储信息的项,以便以后检索
导入json
导入系统
从functools导入缓存的_属性
从PySide6.QtCore导入Qt
从PySide6.QtGui导入QColor、QPen
从PySide6.QtWidgets导入(
QApplication,
QGraphicsRectItem,
Qsscene,
QZ视图,
QMainWindow,
Qm,
)
波浪宽度=25
瓷砖高度=15
轮廓=3
KEY_元数据=1
教室项目(QGraphicsRectItem):
定义初始化(self,x,y,width,height,metadata=None,parent=None):
超级()
自我设定位置(x,y)
self.setFlag(QGraphicsItem.ItemIsMovable)
self.setData(关键字元数据、元数据)
填充=QColor(#000000)
轮廓=QPen(#ffffff”)
outline.setWidth(outline)
outline.setJoinStyle(Qt.MiterJoin)
self.setPen(大纲)
自我挫折(填充)
@类方法
来自_json(cls,d)的def:
x=d[“值”][“偏移量”]/12.6*波浪宽度
y=d[“值”][“偏移量”]/7.2*瓷砖高度
宽度=d[“值”][“区域宽度大小”]*平铺宽度
高度=d[“值”][“区域高度大小”]*瓷砖高度
返回cls(x、y、宽度、高度、d)
def to_json(self):
d=self.data(KEY_元数据)或dict()
d[“值”]=dict(
偏移量x=self.pos().x()*12.6/瓦宽,
OffsetZ=self.pos().y()*7.2/瓷砖高度,
AreaWidthSize=self.rect().width()/TILEWIDTH,
AreaHeightSize=self.rect().height()/TILEHEIGHT,
)
返回d
类主(QMainWindow):
定义初始化(自):
super()。\uuuu init\uuuuu()
self.initUI()
@缓存的不动产
def项目(自身):
返回列表()
def initUI(self):
#设置视口
self.scene=qgraphicscene(self)
self.view=QGraphicsView(self.scene,self)
自视图比例(1,-1)
self.view.setStyleSheet(“背景:透明;边框:0px”)
self.setCentralWidget(self.view)
self.setGeometry(3601901200700)
self.showmized()
def load_from_json(self,filename):
打开(文件名为“r”)作为f:
对于json.load(f)中的e:
item=RoomItem.from_json(e)
self.scene.addItem(项目)
self.items.append(项目)
def save_to_json(自我,文件名):
打开(文件名为“w”)作为f:
l=[]
对于self.items中的项目:
l、 追加(item.to_json())
json.dump(l,f)
def main():
app=QApplication(sys.argv)
main=main()
main.show()
main.load_from_json(“data.json”)
ret=app.exec
main.save_to_json(“data.json”)
系统退出(ret)
如果名称=“\uuuuu main\uuuuuuuu”:
main()
好吧,我明白了,但是既然我从一个循环中生成了所有的“rect”,我该如何访问一个特定的“rect”。如何访问用户选择和移动的特定矩形?@Lakifume您的问题不清楚,但现在我的大问题是:您想何时访问?好吧,假设我想在用户点击保存按钮的最后访问它们。我希望访问每个矩形的位置,并将其传递到json列表中的每个对应条目上。例如,如果第一个矩形被移动到某个地方,我希望得到新的位置,并在“m01SIP_000”条目中对其进行修补。@Lakifume查看我的更新非常感谢,这就成功了