Saving the user's choices

To ensure the user is able to save their choices, we need a Save button:

self.save_button = ttk.Button(self, text="Save", command=self.save)

Now we can finish off our __init__ method by packing all of our widgets:

self.save_button.pack(side=tk.BOTTOM, fill=tk.X, expand=1, padx=40)
self.font_list.pack(side=tk.LEFT, fill=tk.Y, expand=1)
self.size_input.pack(side=tk.BOTTOM, fill=tk.X, expand=1)

Since our Save button calls a method called save, let's define this now.

def save(self):
font_family = self.font_list.get(self.font_list.curselection()[0])
font_size = self.size_input.get()
yaml_file_contents = f"family: {font_family} "
+ f"size: {font_size}"

with open('schemes/font.yaml', 'w') as file:
file.write(yaml_file_contents)

self.master.update_font()

When saving our user's choices, we first need to extract them from their respective widgets.

The curselection method of a Listbox returns a tuple of all selected indexes. Since we are only allowing for the selection of one item (the default behavior) we will always want the first entry in this tuple. We can then pass this to the get method to obtain the string at this index, which will be the chosen font family.

The font size can be obtained by simply calling the get method on our Spinbox.

Now that we have these two choices we can write them into a .yaml file to ensure they remain persistent. We use formatted strings to construct the contents of the .yaml file, open a file handle (which will be stored in schemes/font.yaml), and use the write method to put that string in the file.

With the storage taken care of we now need to pass over to the TextEditor widget to update the styling of our TextArea. We call a method named update_font, which we will write now:

class TextEditor(tk.Tk):
...
def
update_font(self):
self.load_font_file('schemes/font.yaml')
self.text_area.configure(font=(self.font_family, self.font_size))

The update_font method will pass over to another method that handles loading the .yaml file which we just created. It then configures the text_area widget, passing its attributes to the font argument.

Let's now look at the load_font_file method:

def load_font_file(self, file_path):
with open(file_path, 'r') as stream:
try:
config = yaml.load(stream)
except yaml.YAMLError as error:
print(error)
return

self.font_family = config['family']
self.font_size = config['size']

This method looks very similar to all of our other methods that load and parse a .yaml file. We simply extract the family and size variables from the provided .yaml file and assign them to our font_family and font_size attributes.

With this all finished, our FontChooser is now fully functioning. The last thing to do is to create the method that will be responsible for placing it into our Tools menu. We will also need to import the class before we can begin to use it:

from fontchooser import FontChooser

class TextEditor(tk.Tk):
...
def change_font(self):
FontChooser()

def tools_change_font(self, event=None):
"""
Ctrl+L
"""
self.change_font()

After writing these two methods, we can now try out our font selection window. First create a folder named schemes alongside your languages folder, then run your texteditor.py file and type some text (or open a file). Choose Change Font from the Tools menu, and try changing the font and size from this window:

Now that we can change the font family and size, we should allow the user to change the editor's colors. We can approach this in a similar way to how we handled the font by making a new window that writes some options to a .yaml file for persistence.

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

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