I am the OP(internet slang for original poster), and I believe I have found an answer to my question. This just serves for those whom may run into a similar situation, not to mention that others can provide better solutions, for am sure they exist, but this is one none the less.
So, my initial solution was to store the values in a dictionary, and then append that to a file to read back, however there was no way of obtaining the final value, that is, I had to update the dictionary and append it to the file, however I could not obtain the final value.
After that, I looked into data persistence, where you assign a value to a variable, which refers to an object, however, if I assigned a value to variable 'foobar', and 'pickle' it, (erm... writing it to a file, but in bytes), and then assign another value to 'foobar', you end up storing both of those values, rather than storing one constant value for the same object.
What I did then, was to combine these two approaches, of updating a dictionary, and pickling objects. I pickled a dictionary to which I could update, and since it was referring to the same object, then only one value was binded to the dictionary. I don't know why this does not work for mutable sequences, but I suppose that whilst the variable stays the same, it points to multiple objects, though I may be wrong, so if someone could add some clarification that would be much appreciated.
So now everything works, and I can move items on the canvas/widgets to my hearts desire.
Remember, if you need to write to a file where you only want to store a single value for a given object, whose value in dependent on time, use and read up an pickle, here is the link:
https://docs.python.org/3.4/library/pickle.html
Here are exapmles of pickle in action:
This one in particular describes to how save a dict using pickle:
How can I use pickle to save a dict?
Good wiki reference:
https://wiki.python.org/moin/UsingPickle
Here is the latest source code, you may adapt it as you see fit, please note, the indentation may be wrong, because pasting this into here did some weird things with the indentation levels, but am sure you can handle that:
from tkinter import *
import pickle
import os
import __main__
class Drag_Shape:
filename = os.path.basename(__main__.__file__)
filename = filename[:filename.index('.')]+'_coords.py'
print(__main__.__file__)
if os.path.isfile(filename) == False:
foorbar = open(filename, 'w')
foorbar.close()
if os.path.getsize(filename) == 0: coords_dict = {}
else:
with open(filename, 'rb') as shape_cords:
coords_dict = pickle.load(shape_cords)
data = {'x': 0, 'y': 0}
def __init__(self, canvas, *coords, shape = 'rect', fill = 'white', outline = 'black', width = 1, activefill = '',
activeoutline = 'black', activewidth = 1, disabledfill = '', disabledoutline = 'black', disabledwidth = 1,
state = ''):
self.canvas = canvas
self.shape = shape.lower()
print(shape)
print(coords)
for i in self.coords_dict.keys():
if shape.lower() in i: shape = i.lower()
if coords != (): self.coords_dict.update({shape:coords})
else: coords = self.coords_dict[shape]
if shape in 'line':
tag = 'line'
ID = canvas.create_line(coords, tags = tag, fill = fill, width = width,
activefill = activefill, activewidth = activewidth, disabledfill = disabledfill,
disabledwidth = disabledwidth, state = '')
elif shape in 'rectangle':
tag = 'rect'
ID = canvas.create_rectangle(coords, tags = tag, fill = fill, outline = outline, width = width,
activefill = activefill, activeoutline = activeoutline, activewidth = activewidth, disabledfill = disabledfill,
disabledoutline = disabledoutline, disabledwidth = disabledwidth, state = '')
elif shape in 'oval':
tag = 'oval'
ID = canvas.create_oval(coords, tags = tag, fill = fill, outline = outline, width = width,
activefill = activefill, activeoutline = activeoutline, activewidth = activewidth, disabledfill = disabledfill,
disabledoutline = disabledoutline, disabledwidth = disabledwidth, state = '')
elif shape in 'arc':
tag = 'arc'
ID = canvas.create_arc(coords, tags = tag, fill = fill, outline = outline, width = width,
activefill = activefill, activeoutline = activeoutline, activewidth = activewidth, disabledfill = disabledfill,
disabledoutline = disabledoutline, disabledwidth = disabledwidth, state = '')
elif shape in 'polygon':
tag = 'poly'
ID = canvas.create_polygon(coords, tags = tag, fill = fill, outline = outline, width = width,
activefill = activefill, activeoutline = activeoutline, activewidth = activewidth, disabledfill = disabledfill,
disabledoutline = disabledoutline, disabledwidth = disabledwidth, state = '')
elif shape in 'window':
tag = 'win'
ID = canvas.create_window(coords, tags = tag, fill = fill)
elif shape in 'text':
tag = 'text'
ID = canvas.create_text(coords, tags = tag, fill = fill)
elif shape in 'image':
tag = 'img'
ID = canvas.create_image(coords, tags = tag, fill = fill)
elif shape in 'bitmap':
tag = 'bitmap'
ID = canvas.create_bitmap(coords, tags = tag, fill = fill)
self.ID = ID
self.tag = tag
with open(self.filename, 'wb') as shape_coords:
pickle.dump(self.coords_dict, shape_coords)
canvas.tag_bind(tag, '<Button-1>', self.click)
canvas.tag_bind(tag, '<Button1-Motion>', self.track)
canvas.tag_bind(tag, '<ButtonRelease-1>', self.release)
def click(self, event):
self.data.update({'x': event.x, 'y': event.y})
self.item = self.canvas.find_closest(self.data['x'], self.data['y'])
return self.item
def track(self, event):
x, y = event.x - self.data['x'], event.y - self.data['y']
self.canvas.move(self.item, x, y)
self.data.update({'x': event.x, 'y': event.y})
def release(self, event):
self.data.update({'x': event.x, 'y': event.y})
coords = list(self.canvas.coords(self.item))
self.coords_dict.update({self.shape : coords})
with open(self.filename, 'wb') as shape_coords:
pickle.dump(self.coords_dict, shape_coords)
return self.ID
Three important things:
You must specify the coords with a list, or possibly a tuple or other containers (though I have only tested on lists)
If you want to actually save the location of the shape on the canvas, delete the original coords that was used to create the shape, otherwise it will just reset back to it's original position, and so it should.
A file is automagically created when you use the class outside of the file that it belong too. If the file is called 'foorbar.py', than a file called 'foorbar.coords.py', is created in the same folder. If you touch this in anyway, well just don't, it will mess things up.
I know I said three, but am going to push this 'community wiki' sign and see what it does, sorry if this has an undesired effect.