This is a complicated question based on the solution of cloning widgets from this answer.
Basis:
When cloning widgets using this method any functions that are reliant on the references of those widgets are not transfered to the new widgets. e.g.:
from tkinter import *
from so_clone import clone_widget
def test(event, widget):
print(widget.get())
def clone(event, widget, root):
t= Toplevel(root)
c = clone_widget(widget, t)
c.pack(side=TOP)
root = Tk()
f = Frame(root)
f.pack(side=TOP, fill=BOTH, expand=1)
e = Entry(f)
e.pack(side=TOP)
Button(f, text="print", command=lambda e=Event(), w=e:test(e, w)).pack(side=BOTTOM)
Button(root, text="clone", command=lambda e=Event(), c=f, r=root:clone(e, c, r)).pack(side=BOTTOM)
root.mainloop()
When cloning the widget using this method the cloned print button is still referencing the original Entry as it is a perfect duplication.
What I am looking to do is reassign the e
variable from the original Entry to the cloned Entry. To achieve this I have created 3 new classes for creating the cloned window and holding the paths.
class Tree:
def __init__(self):
self.widgets = {}
def add(self, w)
self.widgets[str(w)] = w
return w
def get(self, path):
for w, p in self.widgest.items():
if p == path:
return w
return None
class Popout(TopLevel):
def __init__(self, root, **kwargs):
self.root = root
self.tree = kwargs.pop('tree', tree) ## take the input tree or make a new one.
super(Popout, self).__init__(root) ##creates toplevel window
self.bind('<Configure>', self._add_widget) ##call when configured = when widget added
def _add_widget(self, event):
if event.widget:
self.tree.add(event.widget)
class Poppable(Canvas):
# ... Same as Popout just as a canvas that's in the root frame.
def _popout(self):
p = Popout(self.root, tree=self.tree)
c = clone_widgets(self, p) ## here is where i need to recalculate the tree i think
c.pack(side=TOP)
There are a few additional things that needs to happen for this to work correctly.
- First the paths must be calculated relative to the base cloned widget.
- When cloning the paths must be compared to the tree and the widgets be reassigned
- After cloning all variables associated with the original widgets should be updated to the new widgtets
This is as far as i have gotten with the solution.
The process would be:
- create Poppable Canvas
- Add Widgets to Poppable Canvas
- Widgets are added to Tree which calcualtes their relative path from the Poppable Canvas
- Assigne varaible
e
to Entry inside Poppable Canvas - pop canvas which creates a Popout passing along the tree.
- Popout evaluates the tree while cloning the widgets to also get their relative path from Popout and when matching reassigns the widget in the tree
- Somehow figure out that
e
has the Entry assigned and reassigne
to the new Entry.
Although this is my current working theory it is not definitive if other methods are possible. I am looking for a solution to the problem as a whole, this example is just the first solution I could reasonable conceive to work.