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

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.

主站蜘蛛池模板: 瓦房店市| 嘉义县| 黔江区| 定南县| 马鞍山市| 抚州市| 房山区| 正镶白旗| 敦化市| 江源县| 舟曲县| 商南县| 茌平县| 化德县| 改则县| 贵港市| 温泉县| 嘉善县| 马公市| 怀远县| 禄丰县| 双鸭山市| 禄丰县| 清苑县| 安阳县| 巴林左旗| 聂拉木县| 福清市| 佛山市| 迁西县| 新干县| 班玛县| 汉沽区| 海门市| 大渡口区| 博白县| 许昌市| 象州县| 宁南县| 贵定县| 南华县|