使用批量渲染时如何从屏幕上移除对象(标签、图形)?

How to remove objects (labels, graphics) from the screen when using batched rendering?

我正在 Pyglet 中构建一个演示程序,它使用串行输出来读取和更新屏幕上的对象。

import pyglet
import output_parser as parse

port = input("Serial port ? (examples:COM3, /dev/ttyUSB0) ")
ser = parse.serial.Serial(port=port, baudrate=115200)

ser.write('exit\r'.encode('utf-8'))

# Test is ser working
ser.isOpen()

##########################################################
def update(self):
    #Some code here to obtain output and treat data
    #
    #
    if posTiles and negTiles:
        global finalcoords
        finalcoords = findCoords(poscoords, negcoords, wide)
        global canvas
        canvas[0].vertices = finalcoords
        if uid:
            global uid_label
            uid_label = pyglet.text.Label(text=str(uid),
                                          font_name='Times New Roman',
                                          font_size=24,
                                          x=finalcoords[0]+wide,
                                          y=finalcoords[5],
                                          color=(0,0,250,255),
                                          batch=batch, group=text)
    else:
        if canvas:
            try:
                canvas[0].vertices = zero
                uid_label.delete()
            except:
                pass
######################################################
try:
    config = pyglet.gl.Config(double_buffer=True)
    window = pyglet.window.Window(1280, 720, resizable=True, config=config)

    window.set_minimum_size(640, 480)

    batch = pyglet.graphics.Batch()
    plate = pyglet.graphics.OrderedGroup(0)
    connect = pyglet.graphics.OrderedGroup(1)
    text = pyglet.graphics.OrderedGroup(2)

    cells = {}
    canvas = {}
    cells[0] = Cell(x[0],y[0],l, global_id[0:4])

    canvas[0] = batch.add(4, pyglet.gl.GL_QUADS, connect, ('v2f', zero))

    @window.event
    def on_draw():
        window.clear()
        batch.draw()

    @window.event
    def on_deactivate():
        ser.close()

    #window.push_handlers(pyglet.window.event.WindowEventLogger())

    pyglet.clock.schedule_interval(update, 1/240)

    pyglet.app.run()

finally:
    window.close()
    ser.close()

update() 函数检查串行输出的变化并在 pyglet window 中绘制适当的形状。我还希望 update() 函数在串口没有实际输出时从屏幕上删除 uid_label。 This image 显示程序的工作原理 - 您可以看到 canvas 对象是白色矩形,“3004”是标签。

但是,当串口没有输出时(posTilesnegTiles没有值),标签对象仍然是:Image, 尽管我已经在上面调用了 uid_label.delete()

所以,我的问题是 - 如何让屏幕上的标签消失? uid_label.delete() 似乎不起作用,因为即使在 window.clear()batch.draw() 之后标签仍在内存中并显示在屏幕上。除非我理解不正确,否则不应在 window 上重新绘制从批处理中移除的对象。

我之前在尝试使 canvas[0] 对象出现和消失时遇到过同样的问题,但我通过将顶点设置为零找到了解决方法。但是,我不能用标签来做到这一点,理想情况下,我还想随着程序的进行添加和删除对象,而不必存储它们的顶点并在需要时将它们设置为零。

实际上,.delete() 确实有效。这是一个可以解决问题的最小示例(基于您的代码):

import pyglet

canvas = {}

try:
    config = pyglet.gl.Config(double_buffer=True)
    window = pyglet.window.Window(1280, 720, resizable=True, config=config)
    window.set_minimum_size(640, 480)

    batch = pyglet.graphics.Batch()

    canvas[1] = pyglet.text.Label("Moo", x=10, y=10, batch=batch)

    @window.event
    def on_draw():
        window.clear()
        batch.draw()

    @window.event
    def on_key_press(symbol, modifiers):
        # As soon as a key is pressed, we delete the batch objects (all of them)
        for index in list(canvas):
            canvas[index].delete()
            del(canvas[index])

    pyglet.app.run()

finally:
    window.close()

按任意键应该会使标签消失。
您在尝试此操作时可能遇到的一个问题是,您的代码中没有任何内容可以实际刷新图形区域。

这会给人一种什么都没发生的错觉。任何时候你使用 batch.add(...) 它都会 return 一个你在其中做 delete() 的顶点对象。精灵也是如此。