Ich versuche, ein Programm in Python zu schreiben, das Teile eines Bildes nimmt und sie in Kivy rendert, mit einem GridLayout.AttributeError in Kivy: GridLayout-Objekt hat kein Attribut _trigger_layout
Unter Verwendung einer XML-Datei mit meinen Kartendaten lese ich jede Kachel von ihrer globalen ID (oder "GID", siehe here für eine Erklärung, wie es funktioniert und den Prozess, den mein Programm verwendet), indem ich das Quell-Tileset umwandle Bild in eine Textur und eine Region dieser Textur mit der .get_region() -Methode. Ich erstelle dann ein Bild-Widget mit diesem Teil der Textur, um in das GridLayout zu gelangen. Aber ich bekomme diesen Fehler:
Traceback (most recent call last): File "test_parse_xml.py", line 92, in Ground = Layer(root[1].attrib['name'], int(root[1].attrib['width']), int(root[1].attrib['height'])) File "test_parse_xml.py", line 85, in init self.add_widget(Image(current_texture)) #returns an error. What am I doing wrong?
File "/Applications/Kivy.app/Contents/Resources/kivy/kivy/uix/layout.py", line 85, in add_widget size=self._trigger_layout, AttributeError: 'Layer' object has no attribute '_trigger_layout'
Irgendwelche Ideen, wie ich das beheben kann? Der Punkt von Interesse ist die Zeile, die
self.add_widget(Image(current_texture))
Hier ist mein komplettes Programm.
import xml.etree.ElementTree as ET
from kivy.uix.gridlayout import GridLayout
from kivy.graphics.texture import Texture
from kivy.core.image import Image
from kivy.core.window import Window
tree = ET.parse('test_tileset.tmx')
root = tree.getroot()
#import general elements from <map> tag
mapWidth = int(root.attrib['width'])
mapHeight = int(root.attrib['height'])
tileWidth = int(root.attrib['tilewidth'])
tileHeight = int(root.attrib['tileheight'])
class TileSet(object):
"""Stores data about tilesets to be accessed by tiles from that tileset"""
def __init__(self, imagePath, imageWidth, imageHeight, #creating instance attributes of the class,
tilesetFirstGid, tilesetTileWidth, tilesetTileHeight): #change values with each instance
self.imagePath = imagePath
self.imageWidth = imageWidth
self.imageHeight = imageHeight
self.tilesetFirstGid = tilesetFirstGid
self.tilesetTileWidth = tilesetTileWidth
self.tilesetTileHeight = tilesetTileHeight
self.tilesetLastGid = (imageHeight//tilesetTileHeight)*(imageWidth//tilesetTileWidth)
#make a list of all the tilesets
tilesetList = []
#import data for each tileset from each <tileset> tag
Test = TileSet(root[0][0].attrib['source'], int(root[0][0].attrib['width']),
int(root[0][0].attrib['height']), int(root[0].attrib['firstgid']),
int(root[0].attrib['tilewidth']), int(root[0].attrib['tileheight'])
)
tilesetList.append(Test)
def get_tileset(gid):
"""takes an integer, the gid. Returns an instance of the tileset that has that gid"""
for i in tilesetList:
if gid <= i.tilesetLastGid:
return i
class Layer(GridLayout):
"""creates a grid of tiles based on information from a layer."""
def __init__(self, name, width, height, **kwargs):
self.name = str(name)
self.width = width
self.height = height
#set the number of columns of the gridlayout
self.cols = width
#get the layer for ease of iteration below
#using XPath to find all 'data' nodes that are children of nodes
#with the name of the instance of the class
self.layer = root.find(".//*[@name='"+self.name+"']/data")
prevgid = 1
current_texture = Image(Test.imagePath).texture
current_texture = current_texture.get_region(0, 0, 32, 32)
for gid in self.layer:
gid = int(gid.attrib['gid'])
if gid > 0:
if gid != prevgid:
ts = get_tileset(gid)
current_texture = Image(ts.imagePath).texture
#getting a region of the texture based off the Global ID (GID)
current_texture = current_texture.get_region((ts.imageWidth//ts.tilesetTileWidth-1)*ts.tilesetTileWidth,
(ts.imageHeight//ts.tilesetTileHeight-1)*ts.tilesetTileHeight,
ts.tilesetTileWidth, ts.tilesetTileHeight)
prevgid = gid
self.add_widget(Image(current_texture)) #returns an error. What am I doing wrong?
#Is there a better way to add the texture to the GridLayout?
else:
self.add_widget() #something will go here once I figure out my main problem
Ground = Layer(root[1].attrib['name'], int(root[1].attrib['width']), int(root[1].attrib['height']))
if __name__ == '__main__':
Ground().run()
Dank nennen! Das hat den Fehler beseitigt, aber ich konnte das Image-Widget immer noch nicht zum Laufen bringen: Datei "kivy/_event.pyx", Zeile 438, in kivy._event.EventDispatcher.bind (kivy/_event.c: 6026) KeyError: 'size_hint') Also habe ich self.canvas.add (Rectangle (texture = current_texture)) und es zog ein weißes Feld in der unteren linken Ecke des Bildschirms ... Ich muss herausfinden, wie zu bekommen Dies ist die anzuzeigende Texturregion. – Bam8000
Normalerweise verwende ich 'kivy.uix.image.Image', wenn ich ein Bild auf den Bildschirm setzen muss (aber ich mache auch keine Spiele) –