Home > Enterprise >  How to insert a tag in a Tkinter ScrolledText so that the user can type in their chosen style
How to insert a tag in a Tkinter ScrolledText so that the user can type in their chosen style

Time:05-29

I'm kinda new to Python and I'm running into a hitch that I just can't seem to find an answer for. I've got a program with multiple tkinter.Entry and tkinter.ScrolledText elements spread across multiple tabs in a tkinter.Notebook. I've configured tags for basic formatting (Bold, Italic, and Underline).

The tags work fine when inserting text, but I want to give the user the ability to place their cursor anywhere in the ScrolledText box (at the end or in the middle of existing text), choose the formatting they want to type in, and have what they type come out as that formatting. Here's what I've got so far:

import tkinter as tk
from tkinter.scrolledtext import ScrolledText
...
#an example of one of the Scrolled Text widgets
sermonText = ScrolledText(
    self.sermonFrame,
    fg = 'black',
    font = self.standardFont,
    spacing2 = 3,
    spacing3 = 10,
    wrap = tk.WORD,
    padx = 10,
    pady = 10)
sermonText.grid(
    column = 0,
    row = 6,
    columnspan = 6,
    sticky = 'nsew')
self.configureTags(sermonText)

#the function to configure tags for the ScrolledText widgets
def configureTags(self, component):
    component.tag_configure('plainText', font = ('Helvetica', '12'))
    component.tag_configure('boldText', font = ("Helvetica", "12", "bold"))
    component.tag_configure('italicText', font = ("Helvetica", "12", "italic"))
    component.tag_configure('boldItalicText', font = ('Helvetica', '12', 'bold italic'))
    component.tag_configure('underlineText', font = ('Helvetica', '12', 'underline'))
    component.tag_configure('boldUnderlineText', font = ('Helvetica', '12', 'bold underline'))
    component.tag_configure('underlineItalicText', font = ('Helvetica', '12', 'underline italic'))
    component.tag_configure('boldUnderlineItalicText', font = ('Helvetica', '12', 'bold underline italic'))

There are also formatting buttons the user can click. The bold button calls this function:

def setBold(self):
    currentComponent = self.root.focus_get()
    if currentComponent.tag_ranges(tk.SEL):
        cursorStart = currentComponent.index(tk.SEL_FIRST)
        cursorEnd = currentComponent.index(tk.SEL_LAST)
        print('first:', cursorStart, 'last', cursorEnd)
        currentComponent.tag_add('boldText', cursorStart, cursorEnd)
    else:
        cursor = currentComponent.index(tk.INSERT)
        currentComponent.tag_add('boldText', cursor)
        currentComponent.configure(font = ('Helvetica', '12', 'bold'))

This works when there is text that has been selected by dragging the mouse. Otherwise, if the bold button is clicked, it only changes the formatting at the end of what text is already in the box.

tl:dr - How do I alter that setBold function so that a user can click anywhere in a tkinter ScrolledText box, click the button that calls it, and start typing in bold.

i.e. Existing Text: "Let's all go to the bar." Place cursor before 'bar', click the bold button, and type 'foo '; resulting in: "Let's all go to the foo bar."

P.S. "Just learn Qt" is probably an acceptable answer!

CodePudding user response:

Sure enough, changing this program to use Qt instead of Tkinter made all my text formatting dreams come true. The long and short of is is that for each of the Tkinter ScrolledText widgets, I used Qt's QTextEdit widgets instead. That enabled me to connect these functions to each of the bold, italic, and underline buttons:

def setBold(self):
    component = self.win.focusWidget()
    if isinstance(component, QTextEdit):
        font = QFont(component.textCursor().charFormat().font())
        if font.weight() == QFont.Normal:
            font.setWeight(QFont.Bold)
            component.setCurrentFont(font)
        else:
            font.setWeight(QFont.Normal)
            component.setCurrentFont(font)

def setItalic(self):
    component = self.win.focusWidget()
    if isinstance(component, QTextEdit):
        font = QFont(component.textCursor().charFormat().font())
        if font.italic() == False:
            font.setItalic(True)
            component.setCurrentFont(font)
        else:
            font.setItalic(False)
            component.setCurrentFont(font)

def setUnderline(self):
    component = self.win.focusWidget()
    if isinstance(component, QTextEdit):
        font = QFont(component.textCursor().charFormat().font())
        if font.underline() == False:
            font.setUnderline(True)
            component.setCurrentFont(font)
        else:
            font.setUnderline(False)
            component.setCurrentFont(font)
  • Related