Here's what I managed to do. It is rather limited and I had to get help from the internet in some places.
Can you review it, give me some tips on making the code better, cleaner, faster etc.?
editor.py
import tkinter
import tkinter.ttk
import tkinter.filedialog
import tkinter.messagebox
import os
try:
import config
import menu
import syntaxhl
import findtool
except ImportError as e:
import sys
sys.exit("Import error.\nRaw: {}".format(e))
class Editor(object):
def editor(self):
self.root = tkinter.Tk()
self.config = config.config()
self.syntaxcolor = config.syntaxHighligh()
self.root.wm_title(self.config.editor_title)
self.root.attributes("-alpha", self.config.transparency)
# Scrollbar
self.scrollbar = tkinter.Scrollbar(self.root)
self.scrollbar.pack(side = tkinter.RIGHT, fill = tkinter.Y)
# Editor.
self.editor_space = tkinter.Text(self.root)
self.editor_space.config(undo = self.config.undo, width = self.config.width,
height = self.config.height, fg = self.config.foreground,
bg = self.config.background, insertbackground = self.config.cursorColor,
yscrollcommand = self.scrollbar.set,
font = (self.config.font, self.config.font_size))
self.editor_space.pack(fill = tkinter.X)
self.scrollbar.config(command = self.editor_space.yview)
# Find tool
find = findtool.Find(self.editor_space)
# Menu.
# Note: The order of the instances is the order in witch the menus will appear.
self.mn = tkinter.Menu(self.root)
self.filemenu = menu.FileMenu(self.mn, self.openFile,
self.saveFile, self.destroy,
self.root)
self.toolmenu = menu.ToolsMenu(self.mn, self.clear,
self.syntaxHighlight,
find.find)
self.prefmenu = menu.Settings(self.mn, self.openConfigFile)
self.helpmenu = menu.HelpMenu(self.mn, self.about)
# Close event.
if self.config.askokcancel:
self.root.protocol("WM_DELETE_WINDOW", self.destroy)
self.root.config(menu = self.mn)
self.root.mainloop()
def openConfigFile(self):
try:
with open("config.py") as file:
for line in file.readlines():
self.editor_space.insert(tkinter.END, line)
except IOError as e:
tkinter.messagebox.showerror("Error", "Couldn't open file.")
except Exception as e:
tkinter.messagebox.showerror("Error", "Error.\n{}".format(repr(e)))
def destroy(self):
ako = tkinter.messagebox.askokcancel("Quit", "Are you sure you want to exit?")
if ako:
self.root.quit()
def clear(self):
self.editor_space.delete("1.0", tkinter.END)
def saveFile(self):
path = tkinter.filedialog.asksaveasfilename(defaultextension = self.config.defext)
filename = os.path.basename(path)
try:
with open(filename, "w") as wf:
wf.write(self.editor_space.get("0.0", tkinter.END))
tkinter.messagebox.showinfo(None, "File saved.")
except IOError as e:
tkinter.messagebox.showerror("Error", "Couldn't open file.")
except Exception as e:
tkinter.messagebox.showerror("Error", "Error.\n{}".format(repr(e)))
def openFile(self):
self.clear()
file = tkinter.filedialog.askopenfile()
try:
for line in file.readlines():
self.editor_space.insert(tkinter.END, line)
self.syntaxHighlight()
except IOError as e:
tkinter.messagebox.showerror("Error", "Couldn't open file.")
except Exception as e:
tkinter.messagebox.showerror("Error", "Error.\n{}".format(repr(e)))
def syntaxHighlight(self):
for keyw, color in getattr(self.syntaxcolor, "colors").items():
syntaxhl.highlight(self.editor_space, keyw, color)
def about(self):
pass
config.py
class config(object):
editor_title = "TEdit"
undo = 1 # 1 - Enable
# The default extension used when saving a file.
defext = ".txt"
# Size of the editor window.
width = 150
height = 50
askokcancel = False
matchColor = "blue"
# Theme
transparency = 1
background = "black"
foreground = "white"
font = "Arial"
font_size = 18
cursorColor = "green"
class syntaxHighligh(object):
colors = {"import" : "red",
"def" : "red",
"format" : "red",
"if" : "red",
"class" : "red",
"else" : "red",
"elif" : "red",
"=" : "red",
"try" : "red",
"except" : "red",
"finally" : "red",
"yield" : "red",
"return" : "red",
"not" : "red",
"pass" : "red",
"for": "red",
"pass": "red",
"in" : "red",
"print" : "red",
"lambda" : "red",
}
findtool.py
import tkinter
import tkinter.ttk
import config
class Find(object):
def __init__(self, es):
self.editor_space = es
self.config = config.config()
def find(self):
# Find window and stuff.
root = tkinter.Tk()
tkinter.Label(root, text = "Seach for: ").grid(row = 1, column = 0)
input_ = tkinter.ttk.Entry(root, width = 20)
input_.grid(row = 1, column = 1)
self.editor_space.tag_configure("search", background = self.config.matchColor)
# Search button.
tkinter.ttk.Button(root, text = "Search", command=lambda: self.search_editor_space(input_.get())).grid(row = 2, column = 1,
columnspan = 2)
# On close.
root.protocol("WM_DELETE_WINDOW", lambda: self.destroy_find_window(root))
def destroy_find_window(self, root):
self.editor_space.tag_remove("found", "1.0", tkinter.END)
root.destroy()
def search_editor_space(self, searchfor):
# Actual search.
# Got from(with small modifications): http://www.java2s.com/Code/Python/GUI-Tk/SearchstringinText.html
# Thanks.
self.editor_space.tag_config("found", foreground = self.config.matchColor)
countVar = tkinter.IntVar()
item = "1.0"
while True:
item = self.editor_space.search(searchfor, item, tkinter.END, count = countVar)
if not item:
break
lastindex = "{} + {}c".format(item, countVar.get())
self.editor_space.tag_add("found", item, lastindex)
item = lastindex
menu.py
import tkinter
import tkinter.ttk
class FileMenu(object):
def __init__(self, menubar, openFunc, saveFunc, closeFunc, root):
self.of = openFunc
self.sf = saveFunc
self.cf = closeFunc
self.menu = tkinter.Menu(menubar)
filemenu = tkinter.Menu(self.menu)
filemenu.add_command(label = "Open", command = self.of)
filemenu.add_command(label = "Save", command = self.sf)
filemenu.add_separator()
filemenu.add_command(label = "Exit", command = self.cf)
menubar.add_cascade(label = "File", menu = filemenu)
class HelpMenu(object):
def __init__(self, menubar, aboutFunc):
self.helpmenu = tkinter.Menu(menubar)
self.helpmenu.add_command(label = "About", command = aboutFunc)
menubar.add_cascade(label = "Help", menu = self.helpmenu)
class ToolsMenu(object):
def __init__(self, menubar, clearFunc, syntaxHighL, find):
self.cf = clearFunc
self.fd = find
self.sh = syntaxHighL
self.toolsmenu = tkinter.Menu(menubar)
self.toolsmenu.add_command(label = "Clear", command = self.cf)
self.toolsmenu.add_command(label = "Find", command = self.fd)
self.toolsmenu.add_command(label = "Syntax highlighting", command = self.sh)
menubar.add_cascade(label = "Tools", menu = self.toolsmenu)
class Settings(object):
def __init__(self, menubar, configFile):
self.prefmenu = tkinter.Menu(menubar)
self.prefmenu.add_command(label = "Settings", command = configFile)
menubar.add_cascade(label = "Preferences", menu = self.prefmenu)
syntaxhl.py
import tkinter
def highlight(editor_space, searchfor, color):
countVar = tkinter.StringVar()
pos = "1.0"
while True:
pos = editor_space.search(searchfor, pos, tkinter.END, count = countVar)
if not pos:
break
lastindex = "{} + {}c".format(pos, countVar.get())
editor_space.tag_add("keyword", pos, lastindex)
pos = lastindex
editor_space.tag_configure("keyword", foreground = color)
main.py
try:
import editor
except ImportError as e:
import sys
sys.exit("editor.py module missing.")
if __name__ == '__main__':
edit = editor.Editor()
edit.editor()
config
norsyntaxHighligh
should be classes. Both look to me like a dictionary, the second one doesn't even try to hide it. – L3viathan Jun 20 '15 at 21:57