python.tkinter设计标记语言(渲染6-暂停与跳过渲染)

@TOC

前言

一个流式渲染呈现的标记语言,就需要有能够控制渲染呈现流程的标签。

TinML中(以TinText1.4版本为例),控制渲染呈现流程的标签主要有<stop>, <part>, <wait>,这三种标签分别对应以下流程控制:

  1. 暂停一段时间

  2. 划定一段内容,由读者决定是否显示并阅读

  3. 暂停渲染,等待读者确认继续阅读

为了使整个程序不会因为渲染暂停而被阻塞,TinText的渲染操作在子线程中进行。


暂停一段时间

这个很简单,由<stop>标签确定。

<stop>3
|-暂停三秒

在TinText中,由线程等待事件实现:

#t为暂停的时间,单位为秒
self.render_flag.clear()
self.render_flag.wait(t)
self.render_flag.set()

self.render_flag的定义如下:

self.render_flag=threading.Event()#渲染线程标志

划定可选阅读内容

TinML允许划定可选的阅读内容,由读者选择是否进行渲染呈现并阅读。

比如:

<p>接下来将介绍TinText的各个组成部分

<pt>dev
<p>开发介绍。。。
</pt>dev

<pt>apps
<p>TinText由TinReader、TinWriter、TinMaker等组成

<pt>reader
<p>TinReader是TinText的阅读器
</pt>reader

<pt>writer
<p>TinWriter是TinText的编辑器
</pt>writer

<pt>maker
<p>TinMaker是TinText的加密与集成TIN文件生成器
</pt>maker
</pt>apps

|-......

在新版TinML规范中,可选呈现内容标签允许嵌套,如果上级内容未被选择阅读,则下级所有内容,包括下级可选呈现内容,均会被跳过,所以尽量不要半嵌套

这就划定了两大可选内容,第二个可选内容下又分三个可选内容,这些内容都可以允许读者选择是否阅读,同来减少不必要的阅读信息。

在TinText的实现中,会在阅读框底部询问是否进行阅读某一个内容。内部实现由内容块名称记录表完成。

class PartTag:
    """
    TinText <part> <pt> </part> </pt>
    """
    def __init__(self):
        self.names={'':True}

    def named(self,name):
        if name in self.names:
            return True
        else:
            return False

    def edit(self,name,state:bool):
        self.names[name]=state

    def delete(self,name):
        del self.names[name]

    def check(self):
        return self.names[tuple(self.names.keys())[-1]]

    def now(self):
        return tuple(self.names.keys())[-1]

    def clear(self):
        #删除除了''以外的所有值
        self.names.clear()
        self.names['']=True

具体记录实现:

ttpaf=TinTextPartAskFrame(self,name)
result=ttpaf.initial()
self.parttag.edit(name,result)

TinTextPartAskFrame为TinText自身实现的询问对话框,result为对话结果

每一个开头标签都会在TinText的内容名称表末尾添加一个元素,TinText对于接下来内容是否渲染的判定依据,就是名称表最后一个元素的值。

if not self.parttag.check():
    #<part>未被允许阅读
    if unit[1] not in ('</part>','</pt>'):
        #不是<part>结束标签
        continue
    if unit[2] != self.parttag.now():
        #不是当前忽略层级(名称)
        continue

当碰到结束标签时(显然,必须是同一个名称,毕竟是否渲染就取决于当前名称内容),则在名称表中删除这个元素:

self.parttag.delete(name)

暂停渲染并等待

暂停渲染肯定不能退出渲染,然后再进去,这对一个流式呈现的内容是不合理,因为会丢失上文信息。好在,TinText子线程渲染能够实现线程的暂停。

另外,这个和是否继续阅读不同,这个不要求读者立刻做出决定,所以不适合锁死整个GUI,我们只是想让渲染线程停止。

先看一个TinML例子:

|-......
<p>这就是今天学的全部内容和总结,接下来会布置作业。

<wait>作业要求
<p>今天的作业是……

当TinText渲染器读到<wait>时,会触发以下操作:

ttwf=TinTextWaitFrame(self,content)
ttwf.initial()
self.render_flag.clear()
self.render_flag.wait()

TinTextWaitFrame用来显示“继续阅读”按钮

这样,我们就在这个线程里暂停了这个线程,那等读者按下继续阅读的按钮之后,又怎么恢复线程呢?

TinText的实现如下。

绑定恢复渲染的虚拟事件:

        self.bind('<<ResumeRender>>', lambda e:self.resume_thread_render())


    def resume_thread_render(self):
        #恢复渲染
        self.render_flag.set()

然后在TinTextWaitFrame获得读者确定后触发TinText的<<ResumeRender>>即可。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值