tkinter显示rtf文件

引言

rtf文件是最经典的富文本格式文件,可以显示丰富的文本内容,同时还可以附带多种图片、附件以及加载项。虽然rtf相比于HTML和docx等文件并不是很有竞争力,但是因为其编辑方便,显示样式足够丰富,常被用于显示用户条例、软件文档、特殊输出信息显示等方面。

所以,在tkinter应用中显示*.rtf文件,我认为很有必要。

但是,tkinter无论从顶层还是底层来看,都没有办法显示*.rtf富文本格式的功能。但是,参照隔壁的WinForms,我们或许可以嵌入一个RichTextBox

容我赞扬一番

Python的一个第三方库:pythonnet是真的香,其也被引用为clr,可以调用Windows SDK。

所以无论是图像处理、GUI控件和线程等,均可以使用Windows提供的API。

我们需要使用pythonnet,使用pip下载安装,而且clr.pyd体积很小。


创建类

先引用一波。

from tkinter import Tk,Frame
from webbrowser import open as webopen
import ctypes
user32=ctypes.windll.user32

import clr
clr.AddReference('System.Windows.Forms')
clr.AddReference('System.Drawing')
clr.AddReference('System')
from System.Windows.Forms import RichTextBox
from System.Drawing import Font
from System import String,Single

这个很简单了(在这个专栏里,我们已经创建超多自定义控件类了)。

class TkRichtext(Frame):
    '''显示*.rtf文件的tkinter富文本组件'''

    def __init__(self,master,width,height):
        Frame.__init__(self,master,width=width,height=height)
        font=Font(String('微软雅黑'),Single(13))
        self.rt=RichTextBox()
        self.rt.Font=font
        self.rthwnd=int(str(self.rt.Handle))
        user32.SetParent(self.rthwnd,self.winfo_id())
        user32.MoveWindow(self.rthwnd,0,0,width,height,True)

匹配Frame父组件大小

为了让它看起来更像是一个tkinter控件,我们需要为其自动适配大小。

class TkRichtext(Frame):
    '''显示*.rtf文件的tkinter富文本组件'''

    def __init__(self,master,width,height):
        #...
        self.bind('<Configure>',self.__resize)
    
    def __resize(self,event):
        self.rt.Width=self.winfo_width()
        self.rt.Height=self.winfo_height()

打开文件中的超链接

其实我们发现,原来富文本框的超链接点击仅仅是一个空事件,需要我们自己绑定对超链接点击的处理方法。这里,我们直接使用浏览器打开。

class TkRichtext(Frame):
    '''显示*.rtf文件的tkinter富文本组件'''

    def __init__(self,master,width,height):
        #...
        self.__bind_event()
    
    def __bind_event(self):
        self.rt.LinkClicked+=self.__openlink
    def __openlink(self,sender,e):#点击链接
        webopen(e.LinkText)

这里之所以使用__bind_event来统一管理事件绑定,就是因为我还没来得及深入查看该组件的所有方法和事件,所以预留这一种途径。

载入rtf文件

因为目前我还没有深入了解这个WinForms组件,因此我只能给出这一个本地化函数了。

def loadfile(self,path):
    #载入*.rtf文件
    self.rt.LoadFile(path)

完整代码

from tkinter import Tk,Frame
from webbrowser import open as webopen
import ctypes
user32=ctypes.windll.user32

import clr
clr.AddReference('System.Windows.Forms')
clr.AddReference('System.Drawing')
clr.AddReference('System')
from System.Windows.Forms import RichTextBox
from System.Drawing import Font
from System import String,Single


class TkRichtext(Frame):
    '''显示*.rtf文件的tkinter富文本组件'''

    def __init__(self,master,width,height):
        Frame.__init__(self,master,width=width,height=height)
        font=Font(String('微软雅黑'),Single(13))
        self.rt=RichTextBox()
        self.rt.Font=font
        self.rthwnd=int(str(self.rt.Handle))
        user32.SetParent(self.rthwnd,self.winfo_id())
        user32.MoveWindow(self.rthwnd,0,0,width,height,True)
        self.bind('<Configure>',self.__resize)
        self.__bind_event()

    def __bind_event(self):
        self.rt.LinkClicked+=self.__openlink
    def __openlink(self,sender,e):#点击链接
        webopen(e.LinkText)

    def __resize(self,event):
        self.rt.Width=self.winfo_width()
        self.rt.Height=self.winfo_height()

    def loadfile(self,path):
        #载入*.rtf文件
        self.rt.LoadFile(path)


def test():
    a=Tk()
    a.geometry('600x600+5+5')

    rt=TkRichtext(a,500,500)
    rt.pack(fill='both',expand='True')
    rt.loadfile(r"E:\Py软件\Tin文件\软件说明.rtf")
    #这是我自己的文件,大家以自己的测试文件的路径为准

    a.mainloop()

if __name__=='__main__':
    test()

效果

在这里插入图片描述

偷懒

当然,这个模块已经上传至PYPI了,你们可以通过pip安装tkrichtext库。


结语

事实上,我发现结合Windows SDK,tkinter会有非常多的新玩法,大家可以尽情尝试和探索!

☀tkinter创新☀

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值