Welcome, guest | Sign In | My Account | Store | Cart

This program was adapted from the SAMPLES directory that comes with Python. It allows two people to draw on a program with someone else watching and, at the same time watch what the other person is drawing also.

Python, 111 lines
  1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
HOST = '127.0.0.1'
PORT = 8080

from Tkinter import *
import tkColorChooser

import socket
import thread
import spots

################################################################################

def main():
    global hold, fill, draw, look
    hold = []
    fill = '#000000'
    connect()
    root = Tk()
    root.title('Paint 2.0')
    root.resizable(False, False)
    upper = LabelFrame(root, text='Your Canvas')
    lower = LabelFrame(root, text='Their Canvas')
    draw = Canvas(upper, bg='#ffffff', width=400, height=300, highlightthickness=0)
    look = Canvas(lower, bg='#ffffff', width=400, height=300, highlightthickness=0)
    cursor = Button(upper, text='Cursor Color', command=change_cursor)
    canvas = Button(upper, text='Canvas Color', command=change_canvas)
    draw.bind('<Motion>', motion)
    draw.bind('<ButtonPress-1>', press)
    draw.bind('<ButtonRelease-1>', release)
    draw.bind('<Button-3>', delete)
    upper.grid(padx=5, pady=5)
    lower.grid(padx=5, pady=5)
    draw.grid(row=0, column=0, padx=5, pady=5, columnspan=2)
    look.grid(padx=5, pady=5)
    cursor.grid(row=1, column=0, padx=5, pady=5, sticky=EW)
    canvas.grid(row=1, column=1, padx=5, pady=5, sticky=EW)
    root.mainloop()

################################################################################

def connect():
    try:
        start_client()
    except:
        start_server()
    thread.start_new_thread(processor, ())

def start_client():
    global ZSP
    server = socket.socket()
    server.connect((HOST, PORT))
    ZSP = spots.ZSP(server)

def start_server():
    global ZSP
    server = socket.socket()
    server.bind(('', PORT))
    server.listen(1)
    ZSP = spots.ZSP(server.accept()[0])

def processor():
    while True:
        func, args, kwargs = ZSP.recv()
        getattr(look, func)(*args, **kwargs)

def call(func, *args, **kwargs):
    ZSP.send((func, args, kwargs))

################################################################################

def change_cursor():
    global fill
    color = tkColorChooser.askcolor(color=fill)[1]
    if color is not None:
        fill = color

def change_canvas():
    color = tkColorChooser.askcolor(color=draw['bg'])[1]
    if color is not None:
        draw.config(bg=color)
        call('config', bg=color)

################################################################################

def motion(event):
    if hold:
        hold.extend([event.x, event.y])
        event.widget.create_line(hold[-4:], fill=fill, tag='TEMP')
        call('create_line', hold[-4:], fill=fill, tag='TEMP')

def press(event):
    global hold
    hold = [event.x, event.y]

def release(event):
    global hold
    if len(hold) > 2:
        event.widget.delete('TEMP')
        event.widget.create_line(hold, fill=fill, smooth=True)
        call('delete', 'TEMP')
        call('create_line', hold, fill=fill, smooth=True)
    hold = []

def delete(event):
    event.widget.delete(ALL)
    call('delete', ALL)

################################################################################

if __name__ == '__main__':
    main()

This program is useful for communication of a network where the drawing is more helpful than than typing. A server program has also been tested for Paint 2.0 that allows a record of the drawing to be saved and later played back from a file.