Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- #!/usr/bin/env python3
- # Tested with
- # Python 3.8.0 on Windows 10 (mainly)
- # Python 3.7.3 on Raspbian 10.2
- #
- # Known bug on Raspbian with Python 3.7.3
- # (works under Windows 10 with Python 3.8.0):
- # Start the app, click Help/About and than exit the app.
- # After closing the info box the app thinks, there is unsaved text
- # in the editor.
- # I have the same effect also in some other situations on Raspbian 10.2
- # and not on Windows 10
- # IMHO: this seems to be a problem in the underlying TK implementation.
- from guizero import App, Box, Combo, MenuBar, Slider, Text, TextBox
- from pathlib import Path
- app_name = 'Simple Text Editor'
- app_version = '4'
- app_verdate = '09-DEC-2019'
- app_version_string = app_name + ' v' + app_version + ' (' + app_verdate + ')'
- app = App(title=app_name, bg='slategray', width=800, height=600)
- # remember the last folder in use, default: . - the current folder
- folder = '.'
- # True: no unsaved text in the editor
- text_saved = True
- # True: dark mode is enabled
- dark_mode = False
- # get the current folder ins use from the complete file path, stored in file_name_text_box.value
- def get_folder():
- global file_name_text_box
- name = file_name_text_box.value
- if name is None:
- return '.'
- elif len(name) == 0:
- return '.'
- else:
- return Path(name).parent
- # show some version information
- def about_editor():
- global app_version_string
- app.info('About', app_version_string + "\nA simple Python guizero based text editor")
- return
- # open a file, selected in a file selector box, in the editor and
- # store the file name in file_name_text_box.value
- def open_file():
- global text_saved
- global app
- global editor
- global file_name_text_box
- if not text_saved:
- resp = app.yesno('Warning', 'You have unsaved text in the editor - proceed?')
- if not resp:
- return
- f = get_folder()
- name = app.select_file('Open file', folder=f, filetypes=[["Text files", "*.txt"], ["Markdown files", "*.md"]], save=False)
- if name is None:
- text_saved = True
- return
- if len(name) == 0:
- text_saved = True
- return
- try:
- with open(name, "r") as f:
- editor.value = f.read()
- except Exception as e:
- app.error('Read Error', 'Error in reading file: ' + str(e))
- return
- file_name_text_box.value= name
- text_saved = True
- # save the text in the editor the the file name, stored in file_name_text_box.value
- def save_file():
- global text_saved
- global file_name_text_box
- name = file_name_text_box.value
- if name is None:
- save_as_file()
- return
- if len(name) == 0:
- save_as_file()
- return
- try:
- with open(name, "w") as f:
- f.write(editor.value)
- except Exception as e:
- app.error('Write Error', 'Error in reading file: ' + str(e))
- return
- text_saved = True
- # save the text in the editor into a file, selected in a file selector box and
- # store the name in file_name_text_box.value
- def save_as_file():
- global text_saved
- global app
- global file_name_text_box
- f = get_folder()
- name = app.select_file('Save file', folder=f, filetypes=[["Text files", "*.txt"], ["Markdown files", "*.md"]], save=True)
- if name is None:
- return
- if len(name) == 0:
- return
- try:
- with open(name, "w") as f:
- f.write(editor.value)
- except Exception as e:
- app.error('Write Error', 'Error in reading file: ' + str(e))
- return
- file_name_text_box.value = name
- text_saved = True
- # remove all text from the editor and set the file name to '' in file_name_text_box.value
- def new_file():
- global text_saved
- global app
- global file_name_text_box
- global editor
- global char_count_text_box
- if not text_saved:
- resp = app.yesno('Warning', 'You have unsaved text in the editor - proceed?')
- if not resp:
- return
- file_name_text_box.value = ''
- editor.value = ''
- char_count_text_box.value = '0'
- text_saved = True
- # close the editor app
- def exit_app():
- global text_saved
- global app
- if not text_saved:
- resp = app.yesno('Warning', 'You have unsaved text in the editor - proceed?')
- if not resp:
- return
- app.destroy()
- def change_font():
- global editor
- global font
- editor.font = font.value
- def change_text_color():
- global editor
- global text_color
- editor.text_color = text_color.value
- def change_text_size():
- global editor
- global size
- editor.text_size = size.value
- editor.resize(1, 1)
- editor.resize("fill", "fill")
- # get number of characters in the editor
- # observation: even if editor.value is '' the len(editor.value) is 1
- def get_number_of_text_chars():
- global editor
- chars = len(editor.value)
- if chars > 0:
- return chars -1
- else:
- return 0
- # wil be called by any change in the editor's text area
- def count_text_chars():
- global text_saved
- global char_count_text_box
- char_count_text_box.value = get_number_of_text_chars()
- text_saved = False
- def toggle_status_line():
- global status_box
- if status_box.visible:
- status_box.visible = False
- else:
- status_box.visible = True
- def toggle_char_count():
- global char_count_box
- if char_count_box.visible:
- char_count_box.visible = False
- else:
- char_count_box.visible = True
- def toggle_preferences_controls():
- global preferences_controls
- if preferences_controls.visible:
- preferences_controls.visible = False
- else:
- preferences_controls.visible = True
- def toggle_dark_mode():
- global dark_mode
- global editor
- global text_color
- if dark_mode:
- dark_mode = False
- editor.bg = 'white'
- editor.text_color = text_color.value
- text_color.visible = True
- else:
- dark_mode = True
- editor.bg = '#0f0f0f'
- editor.text_color = 'white'
- text_color.visible = False
- # same handling as if clicked o 'File/Exit'
- app.when_closed = exit_app
- # create the app's menu bar and the related menu items
- menubar = MenuBar(app,
- # menu bar
- toplevel=["File", "Options", "Help"],
- # menu items
- options=[
- # File
- [
- # items in File
- ["New", new_file],
- ["Open...", open_file],
- ["Save", save_file],
- ["Save as...", save_as_file],
- ["Exit", exit_app]
- ],
- # Options
- [
- # items in Options
- ["Toggle status line", toggle_status_line],
- ["Toggle char count", toggle_char_count],
- ["Toggle preferences", toggle_preferences_controls],
- ["Toggle dark mode", toggle_dark_mode]
- ],
- # Help
- [
- # items in Help
- ["About", about_editor]
- ]
- ])
- # create the status line, copntains: file name and character count
- status_box = Box(app, width='fill', border=True)
- file_name_label = Text(status_box, text='File: ', align="left")
- file_name_text_box = TextBox(status_box, text='', width='fill', align="left", enabled=False)
- file_name_text_box.bg = 'white'
- char_count_box = Box(status_box, width='fill', border=True)
- char_count_text_box = TextBox(char_count_box, text='', width='20', align="right", enabled=False)
- char_count_label = Text(char_count_box, text='Chars: ', align="right")
- char_count_text_box.value = '0'
- text_saved = True
- # create the preferences line
- preferences_controls = Box(app, align="top", width="fill", border=True)
- font = Combo(preferences_controls, options=["Courier", "Times New Roman", "Verdana"], align="left", selected='Courier', command=change_font)
- size = Slider(preferences_controls, align="left", command=change_text_size, start=10, end=18)
- size.value = 10
- text_color = Combo(preferences_controls, options=['black', 'blue', 'red', 'magenta'], align="left", selected='black', command=change_text_color)
- # create the editor
- editor = TextBox(app, multiline=True, height="fill", width="fill", text='', scrollbar=True)
- editor.bg = 'white'
- editor.font = font.value
- editor.text_size = size.value
- editor.text_color = text_color.value
- editor.update_command(count_text_chars)
- editor.focus()
- app.display()
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement