官术网_书友最值得收藏!

Adding a built-in functionality

Tkinter's Text widget comes with some handy built-in functionalities to handle common text-related functions. Let's leverage these functionalities to implement some common features in the text editor.

Let's start by implementing the cut, copy, and paste features. We now have the editor GUI ready. If you open the program and play with the Text widget, you will see that you can perform basic functions such as cut, copy, and paste in the text area by using Ctrl + X, Ctrl + C, and Ctrl + V, respectively. All of these functions exist without us having to add a single line of code for these functionalities.

The Text widget clearly comes with these built-in events. Now, we simply want to connect these events to their respective menu items.

The documentation of the Tcl/Tk universal widget methods tells us that we can trigger events without an external stimulus by using the following command:

widget.event_generate(sequence, **kw)

To trigger the Cut event, all we need is the following line in the code:

content_text.event_generate("<<Cut>>")

Let's call it by using a cut function and associate it with the Cut menu by using the callback command (2.04.py):

def cut():
content_text.event_generate("<<Cut>>")

Then, define a callback command from the existing Cut menu, as follows:

edit_menu.add_command(label='Cut', accelerator='Ctrl+X', compound='left', image=cut_icon, command=cut)

Similarly, trigger the copy and paste functions from their respective menu items.

Next, we will move on to the implementation of the undo and redo features. The Tcl/Tk text documentation tells us that the Text widget has an unlimited Undo and Redo mechanism provided we set the undo option to true or 1. To leverage this option, let's first set the Text widget's undo option to true or 1, as shown in the following code:

content_text = Text(root, wrap='word', undo=1)

Now, if you open the text editor and try out the undo feature by using Ctrl + Z, it should work well. Now, we only have to associate the events to functions and call back the functions from the Undo menu. This is similar to what we did for cutcopy, and paste. Refer to the code in 2.03.py.

However, redo has a little quirk that needs to be addressed. By default, redo is not bound to the Ctrl + Y keys. Instead, Ctrl + Y is bound to the paste functionality. This is not how we expect the binding to behave, but it exists due to some historical reasons related to Tcl/Tk.

Fortunately, it is easy to override this functionality by adding an event binding, as follows:

content_text.bind('<Control-y>', redo) # handling Ctrl + small-case y
content_text.bind('<Control-Y>', redo) # handling Ctrl + upper-case y

Since an event binding like the one in the preceding code sends an event argument, the undo function must be able to handle this incoming parameter. Therefore, we'll add the event=None optional parameter to the redo function, as follows (2.04.py):

def redo(event=None):
content_text.event_generate("<<Redo>>")
return 'break'

Events propagate from the operating system level and are accessible to the window that subscribes to the event or wants to make use of it. The return 'break' expression in the preceding function tells the system that it has performed the event and that it should not be propagated further.

This prevents the same event from firing the paste event even though it is the default behavior in Tkinter. Now, Ctrl + Y fires the redo event instead of firing the paste event.

In fact, once we have performed an event, we do not want it to propagate further. Thus, we will add return break to all event-driven functions.

主站蜘蛛池模板: 米林县| 玛纳斯县| 鹤山市| 定南县| 德州市| 大丰市| 山阴县| 石嘴山市| 湘乡市| 时尚| 彭山县| 团风县| 兴国县| 柳州市| 洪洞县| 连州市| 新河县| 南召县| 屏山县| 文安县| 民县| 濉溪县| 淮阳县| 五莲县| 宝兴县| 双柏县| 成安县| 高邑县| 深水埗区| 平潭县| 山阴县| 旅游| 叙永县| 建宁县| 泰兴市| 深州市| 灵宝市| 武宁县| 天气| 恩平市| 竹北市|