Python Tkinter如何通过转储所有画布对象来保存画布对象



我想保存canvas all"对象";而不是要保存的画布的图形。并加载保存以修改对象(可能更改位置、颜色(我知道用pickle保存小部件对象是不可能的。所以我想保存对象的整个配置,并在加载时重新创建对象。有人知道如何实现pickle_save/pickle_load这两个加载/保存自身的功能吗?c.

from tkinter.ttk import *
from tkinter import *
import tkinter.filedialog
import pickle

class Test_Gui(Frame):
   def __init__(self, root, run_class=None):
      Frame.__init__(self, root)
      self.run_class = run_class
      self.root = root
      root.geometry("+400+50")
      root.title("This is ping status")
      self.width = 600
      self.height = 400
      # create canvas at begin will be saved or replace by loading 
      self.c = Canvas(self, width=self.width, height=self.height,
                      bd=0, bg="green", highlightthickness=5, relief=RIDGE, borderwidth=2,
                      scrollregion=(0, 0, self.width, self.height))
      self.c.pack()
      self.canvas_bind()
      self.setting_menu()
      self.pack()
   def setting_menu(self):
      self.rootmenu = Menu(self.root, tearoff=False)
      self.root.config(menu=self.rootmenu)
      openmenu = Menu(self.rootmenu, tearoff=False)
      self.rootmenu.add_cascade(label='Open', menu=openmenu, underline=0)
      def pickle_save():
         # Some method to save widget object/config
         # save self.c to file
         pass
      def pickle_load():
         # Some method to loading save
         # destory self.c or origin and load file  tot self.c
         pass

      openmenu.add_command(label='Save', command=pickle_save)
      openmenu.add_command(label='Load', command=pickle_load)
      openmenu.add_command(label='Exit', command=self.root.destroy)
   def canvas_bind(self):
      def left_click(event):
         x, y = self.c.canvasx(event.x), self.c.canvasx(event.y)
         x1, y1 = (x - 3), (y - 3)
         x2, y2 = (x + 3), (y + 3)
         self.c.create_oval(x1, y1, x2, y2, fill="red")
      self.c.bind('<Button-1>', left_click)

if __name__ == '__main__':
   root = Tk()
   root.bind("<Escape>", lambda *x: root.destroy())
   root.geometry("300x200+50+50")
   top = Toplevel(root)
   Test_Gui(root=top)
   root.mainloop()

使用json将画布项目保存到文本文件:

import json
...
self.json_file = 'canvas-items.json'
def json_save():
    with open(self.json_file, 'w') as f:
        for item in self.c.find_all():
            print(json.dumps({
                'type': self.c.type(item),
                'coords': self.c.coords(item),
                'options': {key:val[-1] for key,val in self.c.itemconfig(item).items()}
            }), file=f)

然后您可以读取json文件并创建项目:

def json_load():
    # if you want to clear the canvas first, uncomment below line
    #self.c.delete('all')
    funcs = {
        'arc': self.c.create_arc,
        #'bitmap' and 'image' are not supported
        #'bitmap': self.c.create_bitmap,
        #'image': self.c.create_image,
        'line': self.c.create_line,
        'oval': self.c.create_oval,
        'polygon': self.c.create_polygon,
        'rectangle': self.c.create_rectangle,
        'text': self.c.create_text,
         # 'window' is not supported
    }
    with open(self.json_file) as f:
        for line in f:
            item = json.loads(line)
            if item['type'] in funcs:
                funcs[item['type']](item['coords'], **item['options'])

openmenu.add_command(label='Save', command=json_save)
openmenu.add_command(label='Load', command=json_load)

最新更新