Some live coding to draw on the screen. I’ve already made this once, but I wanted to make it simple because I have intention to add this feature to my latest project called pygpoint, a mix among pygame and powerpoint to show slides that are images like in powerpoint. In the last version of this program I added a blackboard where you can draw, but in another window. Now I want to add the feature so that you can also draw on the slides and have the chance to save also the image with the drawings on.
So this is the code to implement this. Next time I will add it to pygpoint.
The code
import pygame as pg
# pip install pygame==2.0.0.dev10
"""
With this program you can draw on the
screen with pygame
pythonprogramming.altervista.org
"""
def init():
global screen
pg.init()
screen = pg.display.set_mode((400, 400))
mainloop()
drawing = False
last_pos = None
w = 1
color = (255, 0, 255)
def draw(event):
global drawing, last_pos, w
if event.type == pg.MOUSEMOTION:
if (drawing):
mouse_position = pg.mouse.get_pos()
if last_pos is not None:
pg.draw.line(screen, color, last_pos, mouse_position, w)
last_pos = mouse_position
elif event.type == pg.MOUSEBUTTONUP:
mouse_position = (0, 0)
drawing = False
last_pos = None
elif event.type == pg.MOUSEBUTTONDOWN:
drawing = True
def mainloop():
global screen
loop = 1
while loop:
# checks every user interaction in this list
for event in pg.event.get():
if event.type == pg.QUIT:
loop = 0
if event.type == pg.KEYDOWN:
if event.key == pg.K_s:
pg.image.save(screen, "image.png")
draw(event)
pg.display.flip()
pg.quit()
init()
The live coding video of drawing on the screen with pygame
This project on repl.it
How to clear the screen
drawnsave2.py
=============
changes:
c to clear the screen:
I simply paint the screen in black when hit c key
screen.fill((0, 0, 0))
The code in the while loop in the mainloop function
if event.type == pg.KEYDOWN:
if event.key == pg.K_s:
pg.image.save(screen, "image.png")
if event.key == pg.K_c:
screen.fill((0, 0, 0))
Save multiple images
With the following changes you can save different images with different names, progressively ordinated.
import pygame as pg
# pip install pygame==2.0.0.dev10
"""
With this program you can draw on the
screen with pygame
pythonprogramming.altervista.org
drawnsave2.py
=============
changes:
c to clear the screen:
I simply paint the screen in black when hit c key
screen.fill((0, 0, 0))
"""
def init():
global screen
pg.init()
screen = pg.display.set_mode((400, 400))
mainloop()
drawing = False
last_pos = None
w = 1
color = (255, 0, 255)
def draw(event):
global drawing, last_pos, w
if event.type == pg.MOUSEMOTION:
if (drawing):
mouse_position = pg.mouse.get_pos()
if last_pos is not None:
pg.draw.line(screen, color, last_pos, mouse_position, w)
last_pos = mouse_position
elif event.type == pg.MOUSEBUTTONUP:
mouse_position = (0, 0)
drawing = False
last_pos = None
elif event.type == pg.MOUSEBUTTONDOWN:
drawing = True
def mainloop():
global screen
loop = 1
imagecount = 0
while loop:
# checks every user interaction in this list
for event in pg.event.get():
if event.type == pg.QUIT:
loop = 0
if event.type == pg.KEYDOWN:
if event.key == pg.K_s:
if imagecount < 10:
imagecount = "0" + str(imagecount)
pg.image.save(screen, "image{}.png".format(imagecount))
imagecount = int(imagecount)
imagecount +=1
if event.key == pg.K_c:
screen.fill((0, 0, 0))
draw(event)
pg.display.flip()
pg.quit()
init()
Lets see the images with imageslider
With this code you can opend another python file (I made this some times ago) to watch the files you created).
if event.key == pg.K_i:
os.startfile("imageslider.py")
imageslider.py
This is the code of the program to watch the images
import tkinter as tk
import glob
from PIL import Image, ImageTk
import os
def insertfiles():
"loads the list of files in the directory"
for filename in glob.glob("*.png"):
lst.insert(tk.END, filename)
def delete_item(event):
"Deletes a file in the list: called by lst.bind('<Control-d>', delete_item)"
n = lst.curselection()
os.remove(lst.get(n))
lst.delete(n)
def get_window_size():
"Returns the width and height of the screen to set images and canvas alike it: called by root.bind <Configure>"
root_w = root.winfo_width()
if root.winfo_width() > 200 and root.winfo_height() >30:
w = root.winfo_width() - 200
h = root.winfo_height() - 30
else:
w = 200
h = 30
return w, h
def showimg(event):
"takes the selected image to show it, called by root.bind <Configure> and lst.bind <<ListboxSelect>>"
n = lst.curselection()
filename = lst.get(n)
im = Image.open(filename)
im = im.resize((get_window_size()), Image.ANTIALIAS)
img = ImageTk.PhotoImage(im)
w, h = img.width(), img.height()
canvas.image = img
canvas.config(width=w, height=h)
canvas.create_image(0, 0, image=img, anchor=tk.NW)
root.bind("<Configure>", lambda x: showimg(x))
root = tk.Tk()
root.geometry("800x600+300+50")
lst = tk.Listbox(root, width=20)
lst.pack(side="left", fill=tk.BOTH, expand=0)
lst.bind("<<ListboxSelect>>", showimg)
lst.bind("<Control-d>", delete_item)
insertfiles()
canvas = tk.Canvas(root)
canvas.pack()
root.mainloop()
Now you will see something like this
Let’s use it as an animator and the imageslider inside the main file
Now we can create gif pressing g and we can see the images in the image slider without the external file, because we put that code into a class insider the main file. Here is the code:
import pygame as pg
import os
import glob
from PIL import Image
import tkinter as tk
from PIL import Image, ImageTk
# pip install pygame==2.0.0.dev10
"""
With this program you can draw on the
screen with pygame
pythonprogramming.altervista.org
drawnsave2.py
=============
changes:
c to clear the screen:
I simply paint the screen in black when hit c key
screen.fill((0, 0, 0))
You can save all images with different progressive names
You can see the images with imageslider pressing i
drawnsave4.py
added g to make gif from saved files
now i opens imageslider from inside the progam drawnsave.py without external programs
"""
def init():
global screen
pg.init()
screen = pg.display.set_mode((400, 400))
mainloop()
drawing = False
last_pos = None
w = 1
color = (255, 0, 255)
def draw(event):
global drawing, last_pos, w
if event.type == pg.MOUSEMOTION:
if (drawing):
mouse_position = pg.mouse.get_pos()
if last_pos is not None:
pg.draw.line(screen, color, last_pos, mouse_position, w)
last_pos = mouse_position
elif event.type == pg.MOUSEBUTTONUP:
mouse_position = (0, 0)
drawing = False
last_pos = None
elif event.type == pg.MOUSEBUTTONDOWN:
drawing = True
def mainloop():
global screen
loop = 1
imagecount = 0
while loop:
# checks every user interaction in this list
for event in pg.event.get():
if event.type == pg.QUIT:
loop = 0
if event.type == pg.KEYDOWN:
if event.key == pg.K_s:
if imagecount < 10:
imagecount = "0" + str(imagecount)
pg.image.save(screen, "image{}.png".format(imagecount))
imagecount = int(imagecount)
imagecount +=1
if event.key == pg.K_c:
screen.fill((0, 0, 0))
if event.key == pg.K_i:
ImgSlide()
elif event.key == pg.K_g:
frames = []
imgs = glob.glob("*.png")
for i in imgs:
new_frame = Image.open(i)
frames.append(new_frame)
# Save into a GIF file that loops forever
frames[0].save('animated.gif', format='GIF',
append_images=frames[1:],
save_all=True,
duration=300, loop=0)
os.startfile("animated.gif")
draw(event)
pg.display.flip()
pg.quit()
class ImgSlide():
def __init__(self):
self.root = tk.Tk()
self.root.geometry("800x600+300+50")
self.lst = tk.Listbox(self.root, width=20)
self.lst.pack(side="left", fill=tk.BOTH, expand=0)
self.lst.bind("<<ListboxSelect>>", self.showimg)
self.lst.bind("<Control-d>", self.delete_item)
self.canvas = tk.Canvas(self.root)
self.canvas.pack()
self.insertfiles()
self.root.mainloop()
def insertfiles(self):
"loads the list of files in the directory"
for filename in glob.glob("*.png"):
self.lst.insert(tk.END, filename)
def delete_item(self, event):
"Deletes a file in the list: called by self.lst.bind('<Control-d>', delete_item)"
n = self.lst.curselection()
os.remove(lst.get(n))
lst.delete(n)
def get_window_size(self):
"Returns the width and height of the screen to set images and self.canvas alike it: called by self.root.bind <Configure>"
self.root_w = self.root.winfo_width()
if self.root.winfo_width() > 200 and self.root.winfo_height() >30:
w = self.root.winfo_width() - 200
h = self.root.winfo_height() - 30
else:
w = 200
h = 30
return w, h
def showimg(self, event):
"takes the selected image to show it, called by self.root.bind <Configure> and lst.bind <<ListboxSelect>>"
n = self.lst.curselection()
filename = self.lst.get(n)
im = Image.open(filename)
im = im.resize((self.get_window_size()), Image.ANTIALIAS)
img = ImageTk.PhotoImage(im)
w, h = img.width(), img.height()
self.canvas.image = img
self.canvas.config(width=w, height=h)
self.canvas.create_image(0, 0, image=img, anchor=tk.NW)
self.root.bind("<Configure>", lambda x: self.showimg(x))
init()
Subscribe to the newsletter for updates
Tkinter templatesTwitter: @pythonprogrammi - python_pygame
Claude's Games
1. Memory gameVideos
Speech recognition gamePygame's Platform Game

