Khristos
Khristos

Reputation: 983

How to copy one tkinter object's options when creating another object of the same type?

I'm trying to draw a rectangle in Tkinter using the options from another rectangle. I cannot hard code the options/which options to get from the first rectangle since I do not know beforehand which options it will have.

I used options = canvas.itemconfig(first) to get a dictionary of the first rectangle's options, then drew the second rectangle using second = canvas.create_rectangle(150, 50, 300, 150, **options) but got the following error:

_tkinter.TclError: bitmap "stipple {} {} {} {}" not defined

I then filtered the options dictionary to remove the parameters with no values (e.g. stipple), but then got the following error message:

_tkinter.TclError: unknown color name "black red"

since outline has two values ("black" and "red") though I gave it only one value while drawing the first rectangle

I also gave the first rectangle two tags, 'rect' and 'orig', which has been changed to 'rect orig'

Here is how the options dictionary looked like before and after filtering the parameters with no values:

Original Dictionary:

{'stipple': ('stipple', '', '', '', ''), 'disabledoutlinestipple': ('disabledoutlinestipple', '', '', '', ''), 'offset': ('offset', '', '', '0,0', '0,0'), 'dash': ('dash', '', '', '', ''), 'disabledwidth': ('disabledwidth', '', '', '0.0', '0'), 'activeoutlinestipple': ('activeoutlinestipple', '', '', '', ''), 'dashoffset': ('dashoffset', '', '', '0', '0'), 'activewidth': ('activewidth', '', '', '0.0', '0.0'), 'fill': ('fill', '', '', '', 'blue'), 'disabledoutline': ('disabledoutline', '', '', '', ''), 'disabledfill': ('disabledfill', '', '', '', ''), 'disableddash': ('disableddash', '', '', '', ''), 'width': ('width', '', '', '1.0', '1.0'), 'state': ('state', '', '', '', ''), 'outlinestipple': ('outlinestipple', '', '', '', ''), 'disabledstipple': ('disabledstipple', '', '', '', ''), 'activedash': ('activedash', '', '', '', ''), 'tags': ('tags', '', '', '', 'rect orig'), 'activestipple': ('activestipple', '', '', '', ''), 'activeoutline': ('activeoutline', '', '', '', ''), 'outlineoffset': ('outlineoffset', '', '', '0,0', '0,0'), 'activefill': ('activefill', '', '', '', ''), 'outline': ('outline', '', '', 'black', 'red')}

Filtered Dictionary:

{'outline': ('black', 'red'), 'width': ('1.0', '1.0'), 'offset': ('0,0', '0,0'), 'disabledwidth': ('0.0', '0'), 'outlineoffset': ('0,0', '0,0'), 'dashoffset': ('0', '0'), 'activewidth': ('0.0', '0.0'), 'tags': ('rect orig',), 'fill': ('blue',)}

And here is the original code:

from Tkinter import *

root = Tk()
canvas = Canvas(root, width=600, height=400)
canvas.pack()

first = canvas.create_rectangle(50, 50, 200, 150, outline="red",
                                fill="blue", tags=("rect", "org"))

options = canvas.itemconfig(first)
print options

#second = canvas.create_rectangle(150, 50, 300, 150, **options)

root.mainloop()

Upvotes: 1

Views: 823

Answers (2)

crs
crs

Reputation: 71

For a slightly more general approach: to copy any canvas item:

coords = canvas.coords(item_id)
config = canvas.itemconfig(item_id)
new_config = {key: config[key][-1] for key in config.keys()}
item = new_canvas._create(item_type, coords, {})
new_canvas.itemconfigure(item, new_config)

enter code here

Upvotes: 0

Bryan Oakley
Bryan Oakley

Reputation: 386325

As you can see, itemconfig doesn't return just a dictionary of simple key/value pairs. For each option it will return a tuple made up of the following five items:

  1. option name
  2. option name for the option database
  3. option class for the option database
  4. the default value
  5. the current value

If you want to replicate all of the options, you need the last item returned for each option.

You can do that fairly easily with a dictionary comprehension:

config = canvas.itemconfig(canvas_tag_or_id)
new_config = {key: config[key][-1] for key in config.keys()}
canvas.create_rectangle(coords, **new_config)

For more information see

Upvotes: 3

Related Questions