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

Kivy实现弹幕式时间滚动显示黑屏问题排查

问题分析与修复方案

核心问题及修复

  • 根组件缺失:DanmakuApp的build方法返回None,Kivy应用必须返回一个Widget作为界面根容器,否则窗口无任何可渲染内容,直接显示黑屏。需创建FloatLayout这类布局作为根组件,所有弹幕都要添加到该布局中。
  • 弹幕未加入布局:创建的Danmaku实例仅存于列表,未添加到根布局的子控件列表,无法被Kivy渲染显示。
  • 颜色值超出范围:Kivy中颜色参数要求是0-1之间的浮点数,代码中(200,255,255)是RGB整数,会被判定为超出范围,导致文字不可见(或完全透明),需转换为浮点数格式。
  • 窗口resize事件未绑定:on_resize方法已定义但未绑定到Window的on_resize事件,窗口大小变化时弹幕不会同步更新。

修改后的完整代码

from kivy.app import App
from kivy.uix.label import Label
from kivy.uix.floatlayout import FloatLayout
from kivy.core.window import Window
from kivy.clock import Clock
from datetime import datetime

class Danmaku(Label):
    def __init__(self, **kwargs):
        super(Danmaku, self).__init__(**kwargs)
        self.x = Window.width  # 从屏幕右侧起始
        self.y = Window.height // 2  # 垂直居中
        self.speed = 100
        self.text = datetime.now().strftime("%H:%M")
        # 转换为0-1区间的浮点数颜色,最后一位为透明度
        self.color = (200/255, 255/255, 255/255, 1)
        self.font_size = int(0.5 * Window.height)
        self.font_name = "Arial"
        self.size_hint = (None, None)
        self.size = self.texture_size

    def update_text(self):
        self.text = datetime.now().strftime("%H:%M")
        self.font_size = int(0.9 * Window.height)
        self.color = (200/255, 255/255, 255/255, 1)
        self.size = self.texture_size  # 更新尺寸匹配新文本

    def shift(self, dt):
        self.x -= dt * self.speed

class DanmakuApp(App):
    def build(self):
        self.root_layout = FloatLayout()  # 创建根布局容器
        self.danmaku_list = []
        self.add_new_danmaku()  # 添加第一个弹幕
        Clock.schedule_interval(self.update, 1.0 / 60.0)
        # 绑定窗口尺寸变化事件
        Window.bind(on_resize=self.on_resize)
        return self.root_layout  # 返回根布局供Kivy渲染

    def add_new_danmaku(self):
        danmaku = Danmaku()
        self.danmaku_list.append(danmaku)
        self.root_layout.add_widget(danmaku)  # 将弹幕加入布局

    def update(self, dt):
        # 标记需要移除的已移出屏幕的弹幕
        to_remove = []
        for danmaku in self.danmaku_list:
            danmaku.shift(dt)
            # 弹幕完全移出屏幕左侧时标记移除
            if danmaku.x < -danmaku.width:
                to_remove.append(danmaku)
        
        # 清理已移出的弹幕,释放资源
        for danmaku in to_remove:
            self.danmaku_list.remove(danmaku)
            self.root_layout.remove_widget(danmaku)
        
        # 当前弹幕移动到屏幕中间位置时,添加新弹幕
        if not self.danmaku_list or self.danmaku_list[-1].x < Window.width * 0.5:
            self.add_new_danmaku()

    def on_resize(self, window, width, height):
        for danmaku in self.danmaku_list:
            danmaku.update_text()
            danmaku.y = height // 2  # 重置弹幕垂直居中位置

if __name__ == '__main__':
    DanmakuApp().run()

额外优化说明

  • 添加弹幕清理逻辑:移除完全移出屏幕的弹幕,避免内存占用过高。
  • 调整新弹幕触发条件,防止短时间内弹幕堆积过多。
  • 修复窗口resize时弹幕的垂直位置重置,保证窗口尺寸变化后弹幕仍居中显示。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.01 16:01:38