wxPython和pycairo练习记录12

文章介绍了如何使用wxPython的Ticker控件创建滚动字幕效果,并讨论了在滚动文字衔接上遇到的问题。作者通过修改Ticker类,解决了文字空白期问题,实现了更平滑的滚动。此外,还探讨了使用双端队列优化显示性能的可能性,但考虑到特定场景下的效率和需求,最终选择了保留列表结构并优化处理方式。

wxPython 实现滚动字幕效果

过年在家刷视频号直播时发现弹幕互动游戏,挺有意思的,刚好诠释了“反射”(一种基于字符串的事件驱动)的用法。想要自己也做一个弹幕游戏,于是就有了这个基本的需求,先让弹幕滚动显示出来,直播时可以当作小挂件。

滚动文字功能

先查 API 文档和 demo 看有没相应的控件和例子,发现 wxPython 有滚动文字控件 wx.lib.ticker.Ticker (Ticker翻译:滚动条;收报机;心脏;跑马灯;断续器)。

类签名:
wx.lib.ticker.Ticker(parent, id=-1, text="", fgcolor = wx.BLACK, bgcolor = wx.WHITE, start=True, ppf=2, fps=20, direction="rtl", pos=wx.DefaultPosition, size=wx.DefaultSize, style=wx.NO_BORDER, name="Ticker")

参数:	
parent (wx.Window) – the parent
id (integer) – an identifier for the control: a value of -1 is taken to mean a default
text (string) – text in the ticker
fgcolor (wx.Colour) – text/foreground color
bgcolor (wx.Colour) – background color
start (boolean) – if True, the ticker starts immediately
ppf (int) – pixels per frame
fps (int) – frames per second
direction – direction of ticking, ‘rtl’ or ‘ltr’
pos (wx.Point) – the control position. A value of (-1, -1) indicates a default position, chosen by either the windowing system or wxPython, depending on platform
name – the control name

看看效果:
在这里插入图片描述

源码:

# -*- coding: utf-8 -*-
import wx
from wx.lib.ticker import Ticker


class MyFrame(wx.Frame):
    def __init__(self, *args, **kwargs):
        super(MyFrame, self).__init__(*args, **kwargs)
        self.Center()

        self.ticker = Ticker(parent=self, id=-1, text="你好,世界!Hello World!😍 ",
                             fgcolor="#ff0000", bgcolor="#fff000", start=True,
                             ppf=2, fps=20, direction="rtl",
                             pos=wx.DefaultPosition, size=self.GetClientSize(), style=wx.NO_BORDER,
                             name="Ticker")
        self.ticker.SetFont(wx.Font(18, family=wx.SWISS, style=wx.NORMAL, weight=wx.BOLD, faceName=u"宋体"))
        self.ticker.Start()

        self.ticker.Bind(wx.EVT_RIGHT_UP, self.OnClose)
        self.ticker.Bind(wx.EVT_LEFT_DOWN, self.OnLeftDown)
        self.ticker.Bind(wx.EVT_LEFT_UP, self.OnLeftUp)
        self.ticker.Bind(wx.EVT_MOTION, self.OnMouseMove)

    def OnClose(self, event):
        self.Close()

    def OnLeftDown(self, evt):
        # CaptureMouse 把所有鼠标输入指向 self.ticker 控件窗口
        self.ticker.CaptureMouse()
        # ClientToScreen 把鼠标位置相对于程序窗口的坐标转换为相对于屏幕的坐标
        x, y = self.ClientToScreen(evt.GetPosition())
        originx, originy = self.GetPosition()
        dx = x - originx
        dy = y - originy
        self.delta = ((dx, dy))

    def OnLeftUp(self, evt):
        if self.ticker.HasCapture():
            self.ticker.ReleaseMouse()

    def OnMouseMove(self, evt):
        if evt.Dragging() and evt.LeftIsDown():
            x, y = self.ClientToScreen(evt.GetPosition())
            fp = (x - self.delta[0], y - self.delta[1])
            # Move 将窗口移动到指定坐标
            self.Move(fp)


class App(wx.App):
    def OnInit(self):
        frame = MyFrame(parent=None, size=(1075, 53), style=wx.NO_BORDER)
        frame.Show()
        return True

    def OnExit(self):
        return 0


if __name__ == "__main__":
    app = App()
    app.MainLoop()

滚动文字衔接问题

滚动循环,文字需要全部滚出才会重新滚入,有空白期。
在这里插入图片描述

原 Ticker 类中,滚动文字是用属性 self._text 来存储的,它是一个字符串。如果在字符串尾部附加其他新的字符串,并不能解决显示衔接问题,而且不便对指定字符串进行修改。那么直接继承 Ticker ,把 _text 改成 list,并修改相应方法。

本来是想像做动画一样,将 _text 复制一份,轮流滚动。但是因为后期还要动态添加字符串,并且不应该把所有文字都显示出来。

所以最后想到的解决办法是:另设一个列表 _show_text 用于存储要显示的字符串,_index 表示最后从 _text 添加到 _show_text 的字符串的_text 索引。 当 _show_text 头部节点滚出显示区时,从列表中去除,当尾节点尾部与显示区尾部相距超过设定间距时,则把 _text[_index+1] 附加到 _show_text。
在这里插入图片描述

效果,录像 GIF 帧率是 30 FPS:
在这里插入图片描述

源码:

# -*- coding: utf-8 -*-
# Author: SmileBasic
import wx
import wx.lib.ticker


class Ticker(wx.lib.ticker.Ticker):
    def __init__(self, *args, **kwargs)
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值