You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在Python的pyglet中向已有ScrollableTextLayout添加文本?

问题:如何在Pyglet的ScrollableTextLayout中动态追加日志文本?

我希望在游戏运行时创建操作日志,但查阅pyglet文档和示例后,仍不清楚如何向已显示初始文本的ScrollableTextLayout添加新文本。

现有代码可正常显示初始文本,滚动功能也能正常工作,但在游戏中通过actionLog = actionLog + "Player moved to " + str(x) + "," + str(y) + "\n"追加文本时,新内容不显示。尝试重新创建progressDocument和progressLayout会覆盖原有内容,多次绘制后旧文本出现重影。

原代码片段:

import pyglet
# width of window
progressWidth = 500
# height of window
progressHeight = 800
# caption i.e title of the window
progressTitle = "Game Progress"
# creating a window
gameProgress = pyglet.window.Window(progressWidth, progressHeight, progressTitle)
# text
actionLog = "Welcome to ALIEN SURVIVAL" + "\n"
# batch object
progressBatch = pyglet.graphics.Batch()
# creating a formatted document
# unlike unformatted document it is formatted
progressDocument = pyglet.text.document.FormattedDocument(actionLog)
# setting style to the document
progressDocument.set_style(0, len(progressDocument.text), dict(font_name='Helvetica', font_size=14, color=(255, 255, 255, 255)))
# creating a incremental text layout
progressLayout = pyglet.text.layout.ScrollableTextLayout(progressDocument, progressWidth, progressHeight, multiline=True, batch=progressBatch)

# on draw event
@gameProgress.event
def on_draw():
    # clear the window
    gameProgress.clear()
    # draw the batch
    progressBatch.draw()

pyglet.app.run()

解决方案

核心问题是你修改的actionLog变量和progressDocument没有绑定关系,progressDocument初始化后只会读取初始文本内容,后续修改actionLog不会同步到文档中。正确的做法是直接操作progressDocument的text属性追加内容,同时为新文本设置样式,避免出现无样式的空白内容。

修改后的代码示例

import pyglet
from pyglet.window import key

# 窗口参数
progressWidth = 500
progressHeight = 800
progressTitle = "Game Progress"

# 创建窗口
gameProgress = pyglet.window.Window(progressWidth, progressHeight, progressTitle)

# 初始化文档和布局
progressBatch = pyglet.graphics.Batch()
initial_text = "Welcome to ALIEN SURVIVAL\n"
progressDocument = pyglet.text.document.FormattedDocument(initial_text)
# 定义全局样式
style = dict(font_name='Helvetica', font_size=14, color=(255, 255, 255, 255))
progressDocument.set_style(0, len(progressDocument.text), style)
progressLayout = pyglet.text.layout.ScrollableTextLayout(progressDocument, progressWidth, progressHeight, multiline=True, batch=progressBatch)

# 通用日志追加函数
def add_log_entry(text):
    # 记录追加前的文本长度,用于定位新内容的样式范围
    current_length = len(progressDocument.text)
    # 直接向文档追加文本
    progressDocument.text += f"{text}\n"
    # 为新追加的文本设置样式
    progressDocument.set_style(current_length, len(progressDocument.text), style)
    # 自动滚动到日志底部(可选,不需要可删除此行)
    progressLayout.view_y = 0

# 用键盘事件模拟游戏操作(按M键触发移动日志)
@gameProgress.event
def on_key_press(symbol, modifiers):
    if symbol == key.M:
        # 模拟玩家移动坐标
        x, y = 100, 200
        add_log_entry(f"Player moved to {x},{y}")

@gameProgress.event
def on_draw():
    gameProgress.clear()
    progressBatch.draw()

pyglet.app.run()

关键说明

  1. 直接操作progressDocument.text:这是动态更新文本的正确方式,修改该属性会自动通知关联的ScrollableTextLayout刷新显示,无需重新创建文档或布局。
  2. 为新文本设置样式:追加的新文本不会自动继承原有样式,必须通过set_style方法为新增片段设置样式,起始位置为追加前的文本长度,结束位置为追加后的总长度。
  3. 自动滚动到最新内容(可选):设置progressLayout.view_y = 0可让视图自动定位到最底部,显示最新日志;若需保留手动滚动功能,可删除此行。

内容的提问来源于stack exchange,提问作者GerfnitAuthor

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.29 00:45:40