2

I am creating a code editor as my project, and I think it is nice to have vertical lines under tabs so its easier for the coder. I want to draw a vertical line below tabs (I think the image below will be better to understand what I want, Just a screenshot from vs code):

enter image description here

Here you can see that there is a vertical line under def and I think these are pretty useful for me so that I won't make any indentation errors while I am coding. Now I want exactly a feature like this in my code editor. To simplify things I will upload a sample code below.

from tkinter import *

root = Tk()


txt = Text(root) # What changes do I have to make to this text widget so the lines appear like it does in the image
txt.pack()

root.mainloop()
ss3387
  • 299
  • 3
  • 19

1 Answers1

3

The text widget doesn't directly support this. You can fake it by using ascii line drawing characters, but it would probably be a lot of work. It should be doable, though.

You can do this if you base your IDE on a canvas rather than a Text widget, but the text-editing ability of the canvas text item would be very cumbersome compared to the text widget.

All of that being said, with a little creativity you can get something close to what you want with tags. The idea is to add a tag to the character that you want to appear as a line. If you set the tag to have a different color than the text, it will look like a vertical line. The problem, however, is that you don't have much control over the width of the line. You might have some luck using the bgstipple option, which allows you to apply a bitmap to the region.

Here's an example to illustrate the idea.

import tkinter as tk
import tempfile

def add_markup(text, start=None, end="end"):
    text.mark_set("current", start or "1.0")
    text.tag_remove("markup", "current", end)
    while text.compare("current", "<", end):
        if text.get("current") == " ":
            text.tag_add("markup", "current", "current+1c")
            text.mark_set("current", "current+4c")
        else:
            text.mark_set("current", f"current +1l linestart")

root = tk.Tk()

text = tk.Text(root)
text.tag_configure("markup", background='#f0f0f0', bgstipple='@line.xbm', fgstipple='@line.xbm')
text.pack(fill="both", expand=True)

text.bind(
    "<Any-KeyRelease>",
    lambda event: add_markup(event.widget, "insert linestart", "insert lineend")
)

def load_this_file(text):
    with open(__file__, "r") as f:
        text.insert("1.0", f.read())

load_this_file(text)
add_markup(text)

root.mainloop()

This is what it looks like on my machine:

screenshot

Bryan Oakley
  • 370,779
  • 53
  • 539
  • 685
  • How what I don't really understand what you mean by basing my IDE on a canvas – ss3387 Oct 31 '22 at 19:36
  • 1
    @ss3387: the canvas can have text items on it, and these text items support editing. for example, every line or every block could be a new text item. – Bryan Oakley Oct 31 '22 at 19:38
  • You're right now I understand why you said it will be a lot of work, In my project I have many other stuff that I do to the text widget for example saving the text into a file which I think will be hard to get all the text if there are seperate widgets – ss3387 Oct 31 '22 at 19:39
  • Hmm maybe I can place a canvas with a line above the text widget – ss3387 Oct 31 '22 at 19:43
  • 1
    I like the idea of *line drawing characters*, cause IDE's should have a search option and it shouldn't take for ever. The `Text` built in search function is probably faster than everything one is willing to code and think about. – Thingamabobs Oct 31 '22 at 21:42
  • 1
    @Thingamabobs: I think that the main problem with line drawing characters is that you have to remember to remove them when saving the data to a file. Though, it should be pretty easy to search for those characters and replace them with spaces before saving. If you not only add the characters but also apply a tag to them, that should be pretty easy to do. However, you'll also have the problem that when you cut and paste data you'll end up copy and pasting these characters too. – Bryan Oakley Oct 31 '22 at 22:15
  • 1
    That last paragraph of copy and paste is convincingly an issue for an IDE. Maybe an `image` would suit this case? As far as I know images are ignored by [`tk_textCopy`](https://wiki.tcl-lang.org/page/tk_textCopy) and [is used in the Text widget](https://www.tcl.tk/man/tcl/TkCmd/text.html#M192). – Thingamabobs Oct 31 '22 at 22:31