tkinter实现屏幕窗口弹幕

构思

我在CSDN上看了一篇文章,叫做 “tkinter制作弹幕”。但这并不是真正意义上的弹幕,而仅仅是弹窗,同时如此多的窗口会可能让人感到不适。
因此,我想实现一个能够横向移动的窗口,实现真正的屏幕弹幕。

创建类

我们准备创建一个名为BalloonTk的类,不继承任何组件,而是在类里面创建可移动的窗口。

制定 init 函数

首选,弹幕肯定要有文字和颜色,那么 __init__() 中需要有 “text”,“fg”以及“bg”属性。
其次,为了体现弹幕特征,窗口应该是有一点透明的,所以属性中还得有 “alpha”属性,在这一个类中,我们默认窗口是不透明的。
所以BalloonTk的框架为:

from tkinter import Tk,Label#...
#...

class BalloonTk():#使用tk窗口来实现弹窗效果,目前是覆盖整个屏幕
    def __init__(self,text,fg='',bg='',alpha=1):
            self.fg=fg
            self.bg=bg
            self.text=text
            self.alpha=alpha

移动

这篇文章主要讲思路,所以我们只实现弹幕从右往左水平移动,跟正常的视频弹幕一样。
窗口的起始位置就是屏幕的宽度,但是我们不可能让每一弹幕都从同一个位置出来,因此我们在显示窗口的时候需要接受不同的起始高度。

#移动函数
def show(self,heigh):#移动模块
    alpha=self.alpha#一般是不建议像这样使用self的,这里是为了测试方便
    fg=self.fg
    bg=self.bg
    text=self.text
    a=Tk()
    a.overrideredirect(True)#取消标题栏
    a.bind('<Button-1>',self.destroy)#点击删除
    a.attributes('-alpha',alpha)
    a.attributes('-topmost',True)
    self.a=a
    word=Label(a,text=text,font=('宋体',13),fg=fg,bg=bg).pack(fill='both')
    for i in range(0,a.winfo_screenwidth(),2)[::-1]:
      	try:#如果被点击删除,则退出线程
    	    a.update()                
    	    a.geometry('+'+str(i)+'+'+str(heigh))
    	    slp(0.03)
    	except:
    	    return
    a.destroy()

为什么这里面的注释中有“点击退出”和“退出线程”,接下来会作解释

退出

如果还是像开头那一篇文章,需要用到很多弹幕,如果窗口迟迟不消失,也会让人反感。
那么除了等待窗口运动到屏幕后自动销毁,还有什么快捷的销毁方法呢?显然,当我们迫切地想让弹幕消失,一般都会使用鼠标点击,因此就有了窗口绑定鼠标单击的设计了。

class BalloonTk:
    #...
    def destroy(self,event):
        self.a.destroy()

启动

当我们迫不及待地要使用 BalloonTk(…).show(…) 时,会发现如果前面的弹幕没有运行完或被点击销毁,那么后面一个弹幕就不会出现。此时,多线程的设计也由此而出。

多线程

我们的类是一个窗口,使用多线程不会影响或修改其它主线程的东西,所以可以放心使用。现在建立一个 start 函数。

#from threading import Thread
def start(self,nobg=False):
    Thread(target=lambda:self.show(heigh,nobg)).start()

无背景

视频弹幕一般是没有底色的,所以可以将 __init__ 中的bg更改为透明色,这个改动会在 show 函数中体现。

def show(self,nobg=False):#默认不透明
    #...
    if nobg==True:
        a.attributes('-transparentcolor',bg)
    #...

让我们来看一下有背景色弹幕的效果(无背景色弹幕在复杂颜色背景下不清楚,而且也很难点击销毁)
在这里插入图片描述Tin知识库

完整代码

class BalloonTk():#使用tk窗口来实现弹窗效果,目前是覆盖整个屏幕
    
    def __init__(self,text,fg='',bg='',alpha=1):
        self.fg=fg
        self.bg=bg
        self.text=text
        self.alpha=alpha
    
    def destroy(self,event):#点击关闭
        self.a.destroy()
    
    def show(self,heigh,nobg=False):#移动模块
        alpha=self.alpha
        fg=self.fg
        bg=self.bg
        text=self.text
        a=Tk()
        a.bind('<Button-1>',self.destroy)#点击删除
        a.overrideredirect(True)
        a.attributes('-alpha',alpha)
        a.attributes('-topmost',True)
        self.a=a
        word=Label(a,text=text,font=('宋体',13),fg=fg,bg=bg).pack(fill='both')
        if nobg==True:
            a.attributes('-transparentcolor',bg)
        for i in range(0,a.winfo_screenwidth(),2)[::-1]:
            try:#如果被点击删除,则退出线程
                a.update()
                a.geometry('+'+str(i)+'+'+str(heigh))
                slp(0.03)
            except:
                return
        a.destroy()
    
    def start(self,heigh,nobg=False):#多线程启动弹幕
        Thread(target=lambda:self.show(heigh,nobg)).start()

TinReader可移动工具栏

在这里插入图片描述

写在最后

tkinter的功能实际上还算是比较丰富的,有一定的拓展性。
tkinter实现弹幕,可以继续改进,如:添加背景图片,多方向移动等。

☀tkinter创新☀

  • 4
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值