Не могу сделать сохранение и открытие нарисованной картинки в Canvas (пытаюсь создать свой paint)

Stdnt

Новичок
Пользователь
Апр 11, 2020
3
0
1
Здравствуйте, мне нужно сделать свой простой графический редактор. Осталось сделать функции сохранения и открытия файлов, а еще связать эти функции с меню. Нужно сохранить рисунок с Canvas(формат не важен, jpeg или png и тд) и также открывать в Canvas картинки. Пытался найти решение сам, но ничего не нашел. ОС-Windows 10, Python 3.8
Python:
from tkinter import *
from tkinter.messagebox import *

canvas_width=700
canvas_height=500
brush_size=3
color='black'

def paint(event):
    global brush_size
    global color
    x1=event.x-brush_size
    x2=event.x+brush_size
    y1=event.y-brush_size
    y2=event.y+brush_size
    w.create_oval(x1,y1,x2,y2, fill=color, outline=color)


def Okey():
    global ent
    a=ent.get()
    a=str(a)
    color_change(a)

def Okey1():
    global ent0
    a=ent0.get()
    a=int(a)
    brush_size_change(a)

def Okey2():
    global ent3
    a=ent3.get()
    a=str(a)
    w.config(bg=a)

def brush_size_change(new_size):
    global brush_size
    brush_size=new_size

def color_change(new_color):
    global color
    color=new_color

def close_win():
    if askyesno('Exit','Вы хотите выйти?'):
        root.destroy()

def about():
    win=Toplevel(root)
    lab=Label(win,text='Это простейший графический редактор. Рисовалка!)\n Здесь ты можешь рисовать')
    lab.pack()

def helping():
    win0=Toplevel(root)
    lab0=Label(win0,text='Разноцветные квадратики выбирают цвет,\n а цифирки выбирают размер. \n Стереть все - убирает все')
    lab0.pack()

def Ok():
    global ent1
    global ent2
    a=ent1.get()
    b=ent2.get()
    a=int(a)
    b=int(b)
    w.config(width=a,height=b)

def size():
    global ent1
    global ent2
    win=Toplevel(root)
    ent1=Entry(win, width=20, bd=3)
    ent2=Entry(win, width=20, bd=3)
    but=Button(win,width=20,text='Ok', command=lambda:Ok())
    ent1.pack()
    ent2.pack()
    but.pack()

def color_Newest ():
    global ent
    win=Toplevel(root)
    ent=Entry(win, width=20, bd=3)
    but=Button(win,width=20,text='Okey',command=lambda:Okey())
    ent.pack()
    but.pack()

def sizeBrush():
    global ent0
    win=Toplevel(root)
    ent0=Entry(win, width=20, bd=3)
    but=Button(win,width=20,text='Okey',command=lambda:Okey1())
    ent0.pack()
    but.pack()

def colorCanvas():
    global ent3
    win=Toplevel(root)
    ent3=Entry(win,width=20,bd=3)
    but=Button(win,width=20,text='Okey',command=lambda:Okey2())
    ent3.pack()
    but.pack()


    
root=Tk()
root.title('Paint на Питоне')

m=Menu(root)
root.config(menu=m)
fm=Menu(m)
m.add_cascade(label='File',menu=fm)
fm.add_command(label='Open') #нужна команда открытия файла
fm.add_command(label='Save') #нужна команда сохранения файла
fm.add_command(label='List color',command=colorCanvas)
fm.add_command(label='List Size', command=size)
fm.add_command(label='Brush color',command=color_Newest)
fm.add_command(label='Brush size',command=sizeBrush)
fm.add_command(label='Exit',command=close_win)

hm=Menu(m)
m.add_cascade(label='Help',menu=hm)
hm.add_command(label='Help',command=helping)
hm.add_command(label='About',command=about)

w=Canvas(root, width=canvas_width, height=canvas_height, bg='white')

w.bind('<B1-Motion>',paint)

red_but=Button(bg='red', width=2, command=lambda:color_change('red'))
orange_but=Button(bg='orange',width=2,command=lambda: color_change('orange'))
yellow_but=Button(bg='yellow',width=2,command=lambda: color_change('yellow'))
green_but=Button(bg='green',width=2,command=lambda: color_change('green'))
blue_but=Button(bg='blue',width=2,command=lambda: color_change('blue'))
violet_but=Button(bg='violet',width=2,command=lambda: color_change('violet'))
black_but=Button(bg='black',width=2,command=lambda: color_change('black'))
white_but=Button(bg='white',width=2,command=lambda: color_change('white'))

clear_but=Button(text='Удалить все!', width=10, command=lambda: w.delete('all'))

one_but=Button(text='1',width=2,command=lambda:brush_size_change(1))
two_but=Button(text='2',width=2,command=lambda:brush_size_change(2))
three_but=Button(text='3',width=2,command=lambda:brush_size_change(3))
four_but=Button(text='4',width=2,command=lambda:brush_size_change(4))
five_but=Button(text='5',width=2,command=lambda:brush_size_change(5))
six_but=Button(text='6',width=2,command=lambda:brush_size_change(6))
seven_but=Button(text='7',width=2,command=lambda:brush_size_change(7))
eight_but=Button(text='8',width=2,command=lambda:brush_size_change(8))
nine_but=Button(text='9',width=2,command=lambda:brush_size_change(9))
ten_but=Button(text='10',width=2,command=lambda:brush_size_change(10))


w.grid(row=2, column=0, columnspan=100, padx=5, pady=5,sticky=E+W+S+N)
w.columnconfigure(6, weight=1)

w.rowconfigure(2, weight=1)




red_but.grid(row=0, column=10)
orange_but.grid(row=0,column=11)
yellow_but.grid(row=0,column=12)
green_but.grid(row=0,column=13)
blue_but.grid(row=1,column=10)
violet_but.grid(row=1,column=11)
black_but.grid(row=1,column=12)
white_but.grid(row=1,column=13)

clear_but.grid(row=0,column=15)

one_but.grid(row=0,column=30)
two_but.grid(row=0,column=31)
three_but.grid(row=0,column=32)
four_but.grid(row=0,column=33)
five_but.grid(row=0,column=34)
six_but.grid(row=1,column=30)
seven_but.grid(row=1,column=31)
eight_but.grid(row=1,column=32)
nine_but.grid(row=1,column=33)
ten_but.grid(row=1,column=34)

root.mainloop()
 

stud_55

Модератор
Команда форума
Модератор
Апр 3, 2020
1 522
672
113
Немного переделал ваш paint. Вот пример:
Python:
import tkinter as tk
from tkinter import filedialog as fd, messagebox as mb, colorchooser
from PIL import Image, ImageTk, ImageGrab


canvas_width = 700
canvas_height = 500
brush_size = 3
color = 'black'

root = tk.Tk()
root.title('Paint на Питоне')
w = tk.Canvas(root, width=canvas_width, height=canvas_height, bg='white')


def paint(event):
    global brush_size
    global color
    x1 = event.x - brush_size
    x2 = event.x + brush_size
    y1 = event.y - brush_size
    y2 = event.y + brush_size
    w.create_oval(x1, y1, x2, y2, fill=color, outline=color)


def get_color():
    global color
    color = colorchooser.askcolor()[1]


def brush_size_change(new_size):
    global brush_size
    try:
        new_size = int(new_size)
    except ValueError:
        return
    else:
        if new_size >= 1 and new_size <= 200:
            brush_size = new_size
        elif new_size < 1:
            brush_size = 1
        elif new_size >= 200:
            brush_size = 200


def close_win():
    if mb.askyesno('Exit', 'Вы хотите выйти?'):
        root.destroy()


def about():
    win = tk.Toplevel(root)
    lab = tk.Label(win, text='Это простейший графический редактор. Рисовалка!)\n Здесь ты можешь рисовать')
    lab.pack()


def helping():
    win0 = tk.Toplevel(root)
    lab0 = tk.Label(win0, text='Кнопка "Цвет" устанавливает цвет кисти.\n Кнопка "Размер кисти" устанавливает размер кисти. \n Кнопка "Стереть все" - очищает экран.')
    lab0.pack()


def get_foto():
    global w
    lpx = w.winfo_rootx()
    lpy = w.winfo_rooty()
    rpx = lpx + w.winfo_width()
    rpy = lpy + w.winfo_height()
    filename = fd.asksaveasfilename()
    ImageGrab.grab([lpx, lpy, rpx, rpy]).save(filename)


def image_open():
    global w
    filename = fd.askopenfilename()
    img = Image.open(filename)
    img_tk = ImageTk.PhotoImage(img)
    w.image = img_tk
    w.create_image(0, 0, image=w.image, anchor="nw")


mainmenu = tk.Menu(root)
root.config(menu=mainmenu)
filemenu = tk.Menu(mainmenu, tearoff=0)
filemenu.add_command(label="Открыть...", command=image_open)
filemenu.add_command(label="Новый", command=lambda: w.delete('all'))
filemenu.add_command(label="Сохранить...", command=get_foto)
filemenu.add_command(label="Выход", command=close_win)
helpmenu = tk.Menu(mainmenu, tearoff=0)
helpmenu.add_command(label="Помощь", command=helping)
helpmenu.add_command(label="О программе", command=about)
mainmenu.add_cascade(label="Файл", menu=filemenu)
mainmenu.add_cascade(label="Справка", menu=helpmenu)

w.bind('<B1-Motion>', paint)
color_button = tk.Button(text='Цвет', width=5, command=lambda: get_color())
clear_but = tk.Button(text='Удалить все!', width=10, command=lambda: w.delete('all'))
size = tk.Entry(text='5', width=5)
size_button = tk.Button(text='Размер кисти', width=12, command=lambda: brush_size_change(size.get()))
w.grid(row=2, column=0, columnspan=100, sticky=tk.E + tk.W + tk.S + tk.N)
color_button.grid(row=0, column=10)
clear_but.grid(row=0, column=15)
size_button.grid(row=0, column=20)
size.insert(tk.END, brush_size)
size.grid(row=0, column=22, ipady=4)

root.mainloop()
 
  • Мне нравится
Реакции: Student, Stdnt и Vlad_SD

Stdnt

Новичок
Пользователь
Апр 11, 2020
3
0
1
Немного переделал ваш paint. Вот пример:
Python:
import tkinter as tk
from tkinter import filedialog as fd, messagebox as mb, colorchooser
from PIL import Image, ImageTk, ImageGrab


canvas_width = 700
canvas_height = 500
brush_size = 3
color = 'black'

root = tk.Tk()
root.title('Paint на Питоне')
w = tk.Canvas(root, width=canvas_width, height=canvas_height, bg='white')


def paint(event):
    global brush_size
    global color
    x1 = event.x - brush_size
    x2 = event.x + brush_size
    y1 = event.y - brush_size
    y2 = event.y + brush_size
    w.create_oval(x1, y1, x2, y2, fill=color, outline=color)


def get_color():
    global color
    color = colorchooser.askcolor()[1]


def brush_size_change(new_size):
    global brush_size
    try:
        new_size = int(new_size)
    except ValueError:
        return
    else:
        if new_size >= 1 and new_size <= 200:
            brush_size = new_size
        elif new_size < 1:
            brush_size = 1
        elif new_size >= 200:
            brush_size = 200


def close_win():
    if mb.askyesno('Exit', 'Вы хотите выйти?'):
        root.destroy()


def about():
    win = tk.Toplevel(root)
    lab = tk.Label(win, text='Это простейший графический редактор. Рисовалка!)\n Здесь ты можешь рисовать')
    lab.pack()


def helping():
    win0 = tk.Toplevel(root)
    lab0 = tk.Label(win0, text='Кнопка "Цвет" устанавливает цвет кисти.\n Кнопка "Размер кисти" устанавливает размер кисти. \n Кнопка "Стереть все" - очищает экран.')
    lab0.pack()


def get_foto():
    global w
    lpx = w.winfo_rootx()
    lpy = w.winfo_rooty()
    rpx = lpx + w.winfo_width()
    rpy = lpy + w.winfo_height()
    filename = fd.asksaveasfilename()
    ImageGrab.grab([lpx, lpy, rpx, rpy]).save(filename)


def image_open():
    global w
    filename = fd.askopenfilename()
    img = Image.open(filename)
    img_tk = ImageTk.PhotoImage(img)
    w.image = img_tk
    w.create_image(0, 0, image=w.image, anchor="nw")


mainmenu = tk.Menu(root)
root.config(menu=mainmenu)
filemenu = tk.Menu(mainmenu, tearoff=0)
filemenu.add_command(label="Открыть...", command=image_open)
filemenu.add_command(label="Новый", command=lambda: w.delete('all'))
filemenu.add_command(label="Сохранить...", command=get_foto)
filemenu.add_command(label="Выход", command=close_win)
helpmenu = tk.Menu(mainmenu, tearoff=0)
helpmenu.add_command(label="Помощь", command=helping)
helpmenu.add_command(label="О программе", command=about)
mainmenu.add_cascade(label="Файл", menu=filemenu)
mainmenu.add_cascade(label="Справка", menu=helpmenu)

w.bind('<B1-Motion>', paint)
color_button = tk.Button(text='Цвет', width=5, command=lambda: get_color())
clear_but = tk.Button(text='Удалить все!', width=10, command=lambda: w.delete('all'))
size = tk.Entry(text='5', width=5)
size_button = tk.Button(text='Размер кисти', width=12, command=lambda: brush_size_change(size.get()))
w.grid(row=2, column=0, columnspan=100, sticky=tk.E + tk.W + tk.S + tk.N)
color_button.grid(row=0, column=10)
clear_but.grid(row=0, column=15)
size_button.grid(row=0, column=20)
size.insert(tk.END, brush_size)
size.grid(row=0, column=22, ipady=4)

root.mainloop()
Спасибо, большое. Все классно работает. Многое упростилось и стало удобнее. Еще раз спасибо
 

Student

throw exception
Команда форума
Администратор
Апр 2, 2020
195
103
43
Москва
@Stdnt не забудьте выбрать ответ @stud_55 как лучший, нажмите на иконку кубка слева от ответа.
 

Форум IT Специалистов