Beginning our text editor

Before writing any code, be sure to make a new folder to hold the files for this chapter. Inside this folder, create a file called textarea.py. This file will hold the main part of our text editor—a subclass of the Text widget.

The Text widget is such as a textarea tag within HTML. It holds multiple lines of text and many formatting options. In the next chapter, we will see just how powerful this widget can be with the use of concepts like tags and indexing, which alter the text's appearance and give us control over certain regions of the text, allowing us to search all over the document within.

For now, we will just need a simple instance of the widget with a couple of configuration options set:

import tkinter as tk


class TextArea(tk.Text):
def __init__(self, master, **kwargs):
super().__init__(**kwargs)

self.master = master

self.config(wrap=tk.WORD)

Although initially short, this is all we need at the moment for our Text widget subclass.

After initializing the Text widget superclass, we assign the master widget as an attribute which will allow us to send information back to the main application window in the future.

We use the config method to tell our widget to wrap text on a whole word where possible. This will be configurable in a later iteration.

The next file to create in this folder will hold our main window, so I have called it texteditor.py:

import tkinter as tk
import tkinter.ttk as ttk

from textarea import TextArea


class MainWindow(tk.Tk):
def __init__(self):
super().__init__()

self.text_area = TextArea(self, bg="white", fg="black", undo=True)

self.scrollbar = ttk.Scrollbar(orient="vertical",
command=self.scroll_text)
self.text_area.configure(yscrollcommand=self.scrollbar.set)

self.scrollbar.pack(side=tk.LEFT, fill=tk.Y)
self.text_area.pack(side=tk.LEFT, fill=tk.BOTH, expand=1)

As usual, our main window will inherit from the Tk widget. We make an instance of our TextArea class, passing a default background and foreground color. The undo keyword argument is used to tell the widget that we want to keep a history of the user's actions to allow the familiar undo and redo commands to function.

After our TextArea, we create a Scrollbar widget. This will allow the user to quickly scroll around the TextArea widget by dragging the bar with their mouse.

We want this Scrollbar to be down the left-hand side of our window and handle scrolling up and down. We achieve this by passing the string "vertical" to the orient keyword. Much like a Button, the Scrollbar widget can take a command argument to call a piece of code when it is interacted with.

To tell the TextArea widget to receive scrolling information from our Scrollbar, we configure it with the yscrollcommand attribute assigned to the Scrollbar set property.

Both widgets are packed into the main window. We pack the Scrollbar in first to ensure it goes on the very left and tell it to fill the entire Y (vertical) space above and below it. We then pack the TextArea widget next to our Scrollbar, instructing it to take up all remaining space with the fill and expand arguments.

If you were to run this code as is (after making an instance of the MainWindow and calling mainloop on it), you would see that scrolling the text area will move the Scrollbar along with it, but you cannot click and drag the Scrollbar yet. In order to make that work, we need to assign its command function, which in our case is the scroll_text method:

def scroll_text(self, *args):
self.text_area.yview_moveto(args[1])

The arguments supplied to this method will be the string moveto and an integer containing the position at which to move. We are catching these with a starred args parameter, for a reason which will become clear later on.

For now, all we need to do is call the text_area yview_moveto method with the supplied position and our text_area will be scrollable via the Scrollbar.

Finish up with the usual creation of an instance of the main window to allow the application to run:

if __name__ == '__main__':
mw = MainWindow()
mw.mainloop()

We can now run this file and have a look at our text editor. Try typing a lot of text and scrolling the widget with your mouse. Now try grabbing and pulling the Scrollbar as well.

Once you've explored scrolling, try some common keyboard shortcuts which you would expect to work. You should find that some of them will work fine, but others either do nothing or will do something different.

For example, Ctrl + A usually selects all text within a document, but this won't happen by default. Ctrl + O is usually to open a new file, but this will insert a blank line instead.

If we want to change these bindings, we will need to begin using Tkinter's event system to bind custom events to key combinations. Before diving in, let's take a brief look at how this event system is going to work.

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

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