Reputation: 199
I have two .py files called "notepad.py" & "pycolour.py". First is in the parent folder, second is in "subdir" folder. First file:
#notepad.py
from Tkinter import *
from subdir import pycolour
class SimpleNotepad(object):
def __init__(self):
self.frame = Frame(root, bg='#707070', bd=1)
self.text_field = Text(self.frame, font='Verdana 10', bd=3, wrap='word')
self.text_field.focus_set()
self.btn = Button(root, text='try to colour', command=self.try_to_colour)
self.coloured = pycolour.PyColour(root)
self.frame.pack(expand=True, fill='both')
self.text_field.pack(expand=True, fill='both')
self.btn.pack()
def try_to_colour(self):
txt = self.text_field.get(1.0, 'end')
text = str(txt).split('\n')
for i in range(len(text)-1):
self.coloured.colourize(i+1, len(text[i]))
root = Tk()
app = SimpleNotepad()
root.mainloop()
Second file:
#pycolour.py
from Tkinter import *
import keyword
#colorizing the Python code
class PyColour(Text):
def __init__(self, parent):
Text.__init__(self, parent)
self.focus_set()
self.tag_conf()
self.bind('<Key>', self.key_pressed)
tags = {'com' : '#009999', #comment is darkgreen
'str' : '#F50000', #string is red
'kw' : '#F57A00', #keyword is orange
'obj' : '#7A00F5', #function or class name is purple
'int' : '#3333FF' #integers is darkblue
}
def tag_conf(self):
for tag, value in self.tags.items():
self.tag_configure(tag, foreground=value)
def tag_delete(self, start, end):
for tag in self.tags.items():
self.tag_remove(tag, start, end)
def key_pressed(self, key):
if key.char in ' :[(]),"\'':
self.edit_separator() #for undo/redo
cline = self.index(INSERT).split('.')[0]
lastcol = 0
char = self.get('%s.%d'%(cline, lastcol))
while char != '\n':
lastcol += 1
char = self.get('%s.%d'%(cline, lastcol))
self.colourize(cline,lastcol)
def colourize(self, cline, lastcol):
buffer = self.get('%s.%d'%(cline,0),'%s.%d'%(cline,lastcol))
tokenized = buffer.split(' ')
self.tag_remove('%s.%d'%(cline, 0), '%s.%d'%(cline, lastcol))
quotes = 0
start = 0
for i in range(len(buffer)):
if buffer[i] in ['"',"'"]:
if quotes:
self.tag_add('str', '%s.%d'%(cline, start), '%s.%d'%(cline, i+1))
quotes = 0
else:
start = i
quotes = 1
elif buffer[i] == '#':
self.tag_add('com', '%s.%d'%(cline, i), '%s.%d'%(cline, len(buffer)))
break
start, end = 0, 0
obj_flag = 0
for token in tokenized:
end = start + len(token)+1
if obj_flag:
self.tag_add('obj', '%s.%d'%(cline, start), '%s.%d'%(cline, end))
obj_flag = 0
if token.strip() in keyword.kwlist:
self.tag_add('kw', '%s.%d'%(cline, start), '%s.%d'%(cline, end))
if token.strip() in ['def','class']: obj_flag = 1
else:
for index in range(len(token)):
try: int(token[index])
except ValueError: pass
else: self.tag_add('int', '%s.%d'%(cline, start+index))
start += len(token)+1
if __name__ == '__main__':
root = Tk()
st = PyColour(root)
st.pack(fill='both', expand='yes')
root.mainloop()
"pycolour.py" colours the python syntax in it's own text widget. I want to colour python syntax in text widget called "text_field" from "notepad.py", so i wrote try_to_colour
function. the problem is that i do not understand why this function doesn't work properly.
Upvotes: 0
Views: 178
Reputation: 385900
PyColour is a class. In order to take advantage of what it does you must either create an instance of it (eg self.text_field = PyColour(...)
) or create your own class that subclasses the PyColour class (eg class MyPyColour(PyColour): ...; self.text_field = MyPyColour(...)
)
Upvotes: 1
Reputation: 328556
PyColour
is not a utility class but a Text
widget. It can only color itself. So what you need to do is replace
self.text_field = Text(self.frame, ....)
with
self.text_field = PyColor(self.frame)
# find a different way to set font, etc.
The problem is that PyColor
calls self.tag_add()
and similar methods in colourize()
. These work only on the PyColor
instance self
, not on your widget.
Upvotes: 0