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

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.

主站蜘蛛池模板: 康保县| 原平市| 天水市| 略阳县| 石楼县| 什邡市| 怀仁县| 分宜县| 秦安县| 太仆寺旗| 澄江县| 滁州市| 利辛县| 黑水县| 乐都县| 梅河口市| 阳江市| 大方县| 怀柔区| 化州市| 永德县| 甘泉县| 张掖市| 房山区| 湟中县| 长寿区| 京山县| 鄱阳县| 广水市| 芜湖市| 顺平县| 青神县| 桐城市| 出国| 宁化县| 达拉特旗| 格尔木市| 利川市| 奇台县| 瑞安市| 罗定市|