Я нашел это видео, которое дает отличное руководство по созданию приложения рисования в этом видео YouTube . Я пытаюсь добавить функциональность слоев в программу. До сих пор, когда пользователь нажимает кнопку «Добавить», программа должна добавить еще один холст в словарь, созданный в __init__()
, поднять его впереди всех холстов, фон которого будет таким же, как у контента предыдущего холста. (Я не закончил это полностью.)
Но я получаю эту ошибку:
Exception in Tkinter callback
Traceback (most recent call last):
File "C:\Users\femis_000\AppData\Local\Programs\Python\Python37-32\lib\tkinter\__init__.py", line 1705, in __call__
return self.func(*args)
File "C:\Users\femis_000\Documents\Ibukun\Work\Computer Science\ALevelProject\paintapp1.py", line 115, in <lambda>
buttonA = Button(root,width=10,text="add",command= lambda: self.add(self.canvases))
File "C:\Users\femis_000\Documents\Ibukun\Work\Computer Science\ALevelProject\paintapp1.py", line 97, in add
canvas[label].tkraise(canvas[f'{keys[-1]}'])#_tkinter.TclError: invalid boolean operator in tag search expression using tkraise()
File "C:\Users\femis_000\AppData\Local\Programs\Python\Python37-32\lib\tkinter\__init__.py", line 2602, in tag_raise
self.tk.call((self._w, 'raise') + args)
_tkinter.TclError: invalid boolean operator in tag search expression
Можно ли как-нибудь это исправить? Кроме того, если это действительно ужасное и неэффективное начало реализации слоев, мне бы очень понравилась обратная связь.
from tkinter import *
import tkinter.font as font
import cv2
from PIL import ImageGrab,Image,ImageTk
import numpy as np
class PaintApp:
#class variables
drawing_tool = "pencil"
mouse_button = "up"
x,y = None,None
x1_pt,y1_pt,x2_pt,y2_pt = None,None,None,None
#catch mouse down
def ButtonDown(self,event=None):
self.mouse_button = "down"
self.x1_pt = event.x
self.y1_pt = event.y
#catch mouse up
def ButtonUp(self,event=None):
self.mouse_button = "up"
self.x = None
self.y = None
self.x2_pt = event.x
self.y2_pt = event.y
if self.drawing_tool == "line":
self.line(event)
elif self.drawing_tool == "arc":
self.arc(event)
elif self.drawing_tool == "oval":
self.oval(event)
elif self.drawing_tool == "rectangle":
self.rectangle(event)
elif self.drawing_tool == "text":
self.text(event)
#catch mouse move
def motion(self,event=None):
if self.drawing_tool == "pencil":
self.pencil(event)
#draw pencil
def pencil(self,event=None):
if self.mouse_button == "down":
if self.x is not None and self.y is not None:
event.widget.create_line(self.x,self.y,event.x,event.y,smooth=TRUE)
self.x = event.x
self.y = event.y
#draw line
def line(self,event=None):
if None not in (self.x1_pt,self.y1_pt,self.x2_pt,self.y2_pt):
event.widget.create_line(self.x1_pt,self.y1_pt,
self.x2_pt,self.y2_pt,smooth=TRUE,fill="blue")
#draw arc
def arc(self,event=None):
if None not in (self.x1_pt,self.y1_pt,self.x2_pt,self.y2_pt):
coords = self.x1_pt,self.y1_pt,self.x2_pt,self.y2_pt
event.widget.create_arc(coords,start=0,extent=150,style=ARC)
#draw oval
def oval(self,event=None):
if None not in (self.x1_pt,self.y1_pt,self.x2_pt,self.y2_pt):
event.widget.create_oval(self.x1_pt,self.y1_pt,self.x2_pt,
self.y2_pt)
#draw rectangle
def rectangle(self,event=None):
if None not in (self.x1_pt,self.y1_pt,self.x2_pt,self.y2_pt):
event.widget.create_rectangle(self.x1_pt,self.y1_pt,self.x2_pt,
self.y2_pt)
#text
def text(self,event=None):
if None not in (self.x1_pt,self.y1_pt):
text_font = font.Font(family='Helvetica',size=20,weight='bold')
event.widget.create_text(self.x1_pt,self.y1_pt,fill="green",
font=text_font,text="YEAH")
def add(self,canvas):
keys = list(canvas.keys())
for i in keys:
x = canvas[i].winfo_rootx()+canvas[i].winfo_x()
y = canvas[i].winfo_rooty()+canvas[i].winfo_y()
bboxCanvas = (x,y,x+canvas[i].winfo_width(),y+canvas[i].winfo_height())
print(i)
ImageGrab.grab(bbox=bboxCanvas).save(f'Layer {i}.jpg')
label = rf'Layer {len(keys)}'
canvas[label]=Canvas(root,bg="white")
self.im = ImageTk.PhotoImage(file=rf'Layer {keys[-1]}.jpg')
canvas[label].tkraise(canvas[f'{keys[-1]}'])#_tkinter.TclError: invalid boolean operator in tag search expression using tkraise()
canvas[label].create_image((0,0),image=self.im,anchor='nw')
canvas[label].pack()
canvas[label].bind("<Motion>", self.motion)
canvas[label].bind("<ButtonPress-1>", self.ButtonDown)
canvas[label].bind("<ButtonRelease-1>", self.ButtonUp)
#initialise
def __init__(self,root):
self.canvases = {'Background':Canvas(root,bg="white")}
self.canvases['Background'].pack()
self.canvases['Background'].bind("<Motion>", self.motion)
self.canvases['Background'].bind("<ButtonPress-1>", self.ButtonDown)
self.canvases['Background'].bind("<ButtonRelease-1>", self.ButtonUp)
buttonA = Button(root,width=10,text="add",command= lambda: self.add(self.canvases))
buttonA.pack()
root = Tk()
paint_app = PaintApp(root)
root.mainloop()