Using tags

In essence, a tag is simply a way of adding a name to certain parts of a widget. These names are then used as identifiers, and can be used either to separate certain parts, or group them, depending on your implementation of the principle.

To tag an area of text, you need:

  • The starting index
  • The ending index
  • A tag name

The starting and ending indexes are as discussed in the previous section—they can be numbers joined by a full stop, or they can use any of the special strings as shortcuts, too.

The tag name is simply a user-defined string; the only rule is that it cannot contain spaces. It is therefore up to the developer to give their tags a meaningful name. The exception to this is the sel tag, which is reserved for selecting text, so should not be overwritten.

Once you have assigned tags to the necessary parts of the content, nothing new will happen by default—the tags themselves must be configured first (with the exception of sel once again).

Configuring a tag allows us to change certain styling properties of any areas which have that tag applied. Some of the options available are:

  • background: The background (highlight) color of that area
  • foreground: The foreground (text) color of that area
  • font: The font and font size applied to that area
  • justify: Whether the text is aligned to the left, right, or center
  • offset: Vertically raise or lower the tagged text based on the argument provided (positive integer to raise, negative to lower)
  • underline: Add a line underneath the tagged area

These configuration options are passed as keyword arguments to the tag_configure method of a Text widget.

Let's once again adjust our demo application to practice the use of tags.

Open up the demo file and add the following functions underneath the others:

def tag_alternating(event=None):
for i in range(0, 27, 2):
index = '1.' + str(i)
end = index + '+1c'
text.tag_add('even', index, end)

text.tag_configure('even', foreground='orange')

return "break"

Our first function will tag each alternating character with a tag named even.

We use the range function to generate all of the even numbers between 0 and 27, passing a 2 to the step argument so that we count up by two each time. We then add this number to a 1 and a full stop in order to create the full index.

To ensure we only tag one character, our ending index is created by adding the special string +1c to the end of the beginning index.

Now that we have the starting and ending index, we assign the tag to that area with the tag_add method, passing all three of the required arguments to it.

Once we have tagged all relevant areas, we need to make the tag we have defined actually do something. We achieve this by using the tag_configure method to set the foreground argument to orange for everything that has been tagged with our even tag. This means that each even character on the first line (for the first 26 characters) will become orange after this function has been run.

We end up returning the break string to prevent any default behavior from our chosen keyboard shortcut.

This example uses hard-coded indexes, which works for a small example such as this, but is not desirable for a proper application. There is a method called tag_ranges which will get the start and end indexes of all regions with a specific tag. Since the selection is defined with a tag, we can use this method to get the selected area.

Let's add two more methods which utilize this method to have a look at a couple more of the possible styling changes that can be applied by tags:

def raise_selected(event=None):
text.tag_configure('raise', offset=5)
selection = text.tag_ranges("sel")
text.tag_add('raise', selection[0], selection[1])

return "break"


def underline_selected(event=None):
text.tag_configure('underline', underline=1)
selection = text.tag_ranges("sel")
text.tag_add('underline', selection[0], selection[1])

return "break"

These functions begin again by configuring a tag name to have a particular styling change.

The raise_selected function assigns a positive integer to the offset option, which will raise the tagged area higher than the rest of the text on that line. Our underline_selected method sets the underline option to 1, which will underline the tagged text.

We use the tag_ranges method to get the start and end index of text which has the sel tag, meaning the selected text. A tag is then added to text between these ranges in order to change their properties, and the usual break string is returned.

To play with these functions, all we need to do is bind them to a keyboard shortcut:

text.bind('<Control-t>', tag_alternating)
text.bind('<Control-r>', raise_selected)
text.bind('<Control-u>', underline_selected)

Run this version of the demo application, add some dummy text, and press Ctrl + t. You should see each letter at an even index has now become orange.

Now select a small part of the text and press Ctrl and r. You should see the text rise above the rest of the text on that same line. Then give Ctrl + u a try; even on the same text range, it will add the underlining on top of all previous style changes. This is because the same range of text can have multiple tags affecting its styling:

When multiple tags conflict, the tag that was configured last will have priority, regardless of what order they were added to the range in.

Now that we know how to apply a tag to an index range which will change its color, all we need to learn is how to discover the index ranges so that we can begin coloring certain words in our text editor. There's a very convenient method of Text widgets which will allow us to do just that.

..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset