首页 > 其他分享 >tkinter text控件添加行号. 完美版本

tkinter text控件添加行号. 完美版本

时间:2023-02-15 11:46:25浏览次数:47  
标签:__ 控件 tkinter text self args tk ._

import tkinter as tk

fon1=("宋", "16")

#===========2023-02-06,10点17  今天目标读懂这份888.py 代码.


class TextLineNumbers(tk.Canvas):
    def __init__(self, *args, **kwargs):
        tk.Canvas.__init__(self, *args, **kwargs)
        self.textwidget = None

    def attach(self, text_widget):
        self.textwidget = text_widget

    def redraw(self, *args):

        '''redraw line numbers'''
        self.delete("all")
        # ====================self.textwidget.index("@0,0") @0,0表示最接近左上角的行信息.
        i = self.textwidget.index("@0,0")  # 找到0行0列的信息. ref: 参考文档:    https://tkdocs.com/shipman/text-index.html
        hang, lie = i.split('.')
        while True:
            dline = self.textwidget.dlineinfo(i)
            hang, lie = i.split('.')  # 计算上面i行的信息.    self.textwidget.get(i)
            debug222 = self.textwidget.get(i)  # 这里面显示滚动之后的左上角第一个字.#这时候我们读入的是1.4
            if dline is None: break  # Return tuple (x,y,width,height,baseline) giving the bounding box        and baseline position of the visible part of the line containing        the character at INDEX.
            if lie == '0':  # ===首列才画行号.
                y = dline[1]
                linenum = hang  # 行信息
                self.create_text(1, y, anchor="nw", text="{0:>2}".format(linenum), font=fon1)  # 创建行号. 2是x索引.
            # i = self.textwidget.index("%s+1line" % i) #然后计算下一行.
            i = self.textwidget.index(str(int(hang) + 1) + '.' + '0')  # 然后计算下一行.







class CustomText(tk.Text):
    def __init__(self, *args, **kwargs):
        tk.Text.__init__(self, *args, **kwargs)

        # create a proxy for the underlying widget
        self._orig = self._w + "_orig"
        self.tk.call("rename", self._w, self._orig)
        self.tk.createcommand(self._w, self._proxy)

    def _proxy(self, *args): #发送自定义信号change
        # let the actual widget perform the requested action
        result=1
        try:
            cmd = (self._orig,) + args
            result = self.tk.call(cmd)

            # generate an event if something was added or deleted,
            # or the cursor position changed
            if (args[0] in ("insert", "replace", "delete") or
                args[0:3] == ("mark", "set", "insert") or
                args[0:2] == ("xview", "moveto") or
                args[0:2] == ("xview", "scroll") or
                args[0:2] == ("yview", "moveto") or
                args[0:2] == ("yview", "scroll")
            ):
                self.event_generate("<<Change>>", when="tail")#触发change信号.
        except:
            pass
        # return what the actual widget returned
        return result

class Example(tk.Frame):
    def __init__(self, *args, **kwargs):
        tk.Frame.__init__(self, *args, **kwargs)
        self.text = CustomText(self,font=fon1)
        self.vsb = tk.Scrollbar(self, orient="vertical", command=self.text.yview)#竖直方向的滑动杆.
        self.text.configure(yscrollcommand=self.vsb.set)

        self.linenumbers = TextLineNumbers(self, width=30)#创建行号工具
        self.linenumbers.attach(self.text) # 绑定行号工具到text空间.

        self.vsb.pack(side="right", fill="y")
        self.linenumbers.pack(side="left", fill="y")
        self.text.pack(side="right", fill="both", expand=True)

        self.text.bind("<<Change>>", self._on_change)#绑定修改到重新绘制linenumber
        self.text.bind("<Configure>", self._on_change)

        self.text.insert("end", "onefivefivefivefivefivefivefivefivefivefivefivefivefivefivefivefivefivefivefivefivefivefivefivefivefivefivefivefivefivefivefivefivefivefivefivefivefivefivefivefivefivefivefivefivefivefivefivefivefivefivefivefivefivefivefivefivefivefivefivefivefivefivefivefivefivefivefivefivefivefivefivefivefivefivefivefivefivefivefivefivefivefivefivefivefivefivefivefivefivefivefive\ntwofivefivefivefivefivefivefivefivefivefivefivefivefivefivefivefivefivefivefivefivefivefivefivefivefivefivefivefivefivefivefivefivefivefivefivefivefivefivefivefivefivefivefivefivefivefivefive\nthree\n")
        self.text.insert("end", "onefivefivefivefivefivefivefivefivefivefivefivefivefivefivefivefivefivefivefivefivefivefivefivefivefivefivefivefivefivefivefivefivefivefivefivefivefivefivefivefivefivefivefivefivefivefivefivefivefivefivefivefivefivefivefivefivefivefivefivefivefivefivefivefivefivefivefivefivefivefivefivefivefivefivefivefivefivefivefivefivefivefivefivefivefivefivefivefivefivefivefive\ntwofivefivefivefivefivefivefivefivefivefivefivefivefivefivefivefivefivefivefivefivefivefivefivefivefivefivefivefivefivefivefivefivefivefivefivefivefivefivefivefivefivefivefivefivefivefivefive\nthree\n")
        self.text.insert("end", "onefivefivefivefivefivefivefivefivefivefivefivefivefivefivefivefivefivefivefivefivefivefivefivefivefivefivefivefivefivefivefivefivefivefivefivefivefivefivefivefivefivefivefivefivefivefivefivefivefivefivefivefivefivefivefivefivefivefivefivefivefivefivefivefivefivefivefivefivefivefivefivefivefivefivefivefivefivefivefivefivefivefivefivefivefivefivefivefivefivefivefive\ntwofivefivefivefivefivefivefivefivefivefivefivefivefivefivefivefivefivefivefivefivefivefivefivefivefivefivefivefivefivefivefivefivefivefivefivefivefivefivefivefivefivefivefivefivefivefivefive\nthree\n")
        self.text.insert("end", "onefivefivefivefivefivefivefivefivefivefivefivefivefivefivefivefivefivefivefivefivefivefivefivefivefivefivefivefivefivefivefivefivefivefivefivefivefivefivefivefivefivefivefivefivefivefivefivefivefivefivefivefivefivefivefivefivefivefivefivefivefivefivefivefivefivefivefivefivefivefivefivefivefivefivefivefivefivefivefivefivefivefivefivefivefivefivefivefivefivefivefive\ntwofivefivefivefivefivefivefivefivefivefivefivefivefivefivefivefivefivefivefivefivefivefivefivefivefivefivefivefivefivefivefivefivefivefivefivefivefivefivefivefivefivefivefivefivefivefivefive\nthree\n")
        self.text.insert("end", "onefivefivefivefivefivefivefivefivefivefivefivefivefivefivefivefivefivefivefivefivefivefivefivefivefivefivefivefivefivefivefivefivefivefivefivefivefivefivefivefivefivefivefivefivefivefivefivefivefivefivefivefivefivefivefivefivefivefivefivefivefivefivefivefivefivefivefivefivefivefivefivefivefivefivefivefivefivefivefivefivefivefivefivefivefivefivefivefivefivefivefive\ntwofivefivefivefivefivefivefivefivefivefivefivefivefivefivefivefivefivefivefivefivefivefivefivefivefivefivefivefivefivefivefivefivefivefivefivefivefivefivefivefivefivefivefivefivefivefivefive\nthree\n")
        self.text.insert("end", "onefivefivefivefivefivefivefivefivefivefivefivefivefivefivefivefivefivefivefivefivefivefivefivefivefivefivefivefivefivefivefivefivefivefivefivefivefivefivefivefivefivefivefivefivefivefivefivefivefivefivefivefivefivefivefivefivefivefivefivefivefivefivefivefivefivefivefivefivefivefivefivefivefivefivefivefivefivefivefivefivefivefivefivefivefivefivefivefivefivefivefive\ntwofivefivefivefivefivefivefivefivefivefivefivefivefivefivefivefivefivefivefivefivefivefivefivefivefivefivefivefivefivefivefivefivefivefivefivefivefivefivefivefivefivefivefivefivefivefivefive\nthree\n")
        self.text.insert("end", "fivefivefivefivefivefivefivefivefivefivefivefivefivefivefivefivefivefivefivefivefivefivefivefivefivefivefivefivefivefivefivefivefivefivefivefivefivefivefivefivefivefivefivefivefivefivefivefivefivefivefivefivefivefivefivefivefivefivefivefivefivefivefivefivefivefivefivefivefivefivefivefivefivefivefivefivefivefivefivefivefivefivefivefivefivefivefivefivefivefive\n")

    def _on_change(self, event):
        self.linenumbers.redraw()
# ... and, of course, add this at the end of the file to bootstrap it:

if __name__ == "__main__":
    root = tk.Tk()
    Example(root).pack(side="top", fill="both", expand=True)
    root.mainloop()
View Code

仓库在:

https://github.com/zhangbo2008/tkinter_text_with_linenumber_best_version

标签:__,控件,tkinter,text,self,args,tk,._
From: https://www.cnblogs.com/zhangbo2008/p/17122205.html

相关文章

  • 在代码中实现背景单击变换颜色和TextView变换文字颜色
    效果:点击前:[img]http://dl2.iteye.com/upload/attachment/0093/6747/421353dc-c6b1-3518-8f00-13d7ba03cc37.png[/img]点击中:[img]http://dl2.......
  • Django context must be a dict rather than UserProfile.
    contextmustbeadictratherthanUserProfile. #主页@login_requireddefindex(request):data={}data=request.userprint(type(data))print(da......
  • 界面控件DevExpress WinForm——轻松构建类Visual Studio UI(一)
    DevExpressWinForm拥有180+组件和UI库,能为WindowsForms平台创建具有影响力的业务解决方案。DevExpressWinForm能完美构建流畅、美观且易于使用的应用程序,无论是Office风......
  • python TKinter弹出式菜单的使用
    1、弹出菜单也叫上下文菜单,建立菜单并向菜单添加各种功能。2、右键监听鼠标。如右键点击,则根据位置判断弹出。3、调用Menupop方法。4、add_separator添加分隔符。实例#弹出......
  • python TKinter普通菜单的介绍
    TKinter中的菜单种类比较多,本篇就其中的普通菜单为大家带来讲解。1、第一个Menu类定义是parent。2、add_command添加菜单项,如果菜单是顶层菜单,从左到右添加,否则就是下拉菜单......
  • python中TKinter的绑定方法
    1、bind_all全局绑定,默认是全局快捷键,比如F1是帮助文档。2、bind_class接受三个参数,第一个是类名,第二个是事件,第三个是操作。3、bind单独绑定某个实例。4、unbind解绑需要一......
  • Listener-概述、Listener-ServletContextListener使用
    Listener-概述Listener:监听器概念:web的三大组件之一事件:一件事情事件源:事件发生的地方监听器:一个对象注册监听:将事件,事件源,监......
  • 从 Newtonsoft.Json 迁移到 System.Text.Json
    一.写在前面System.Text.Json是.NETCore3及以上版本内置的Json序列化组件,刚推出的时候经常看到踩各种坑的吐槽,现在经过几个版本的迭代优化,提升了易用性,修复了各种......
  • Android 自定义变化的文本控件ColorChangeView
    实例图说明图/***有颜色过渡变化的textview**@ProjectApp_View*@Packagecom.android.view.colortextview*@authorchenlin*@version1.0*@NoteTODO*//*......
  • HTML_01_TEXT
    1.TEXT<strong>bold</strong><!--bydefauly,thecontentshowedinbold--><b>bold</b><i>italics</i><em>italics</em><del>del</del><s>del</s><ins>ins......