tkinter askcolor - can't receive data while choosing color

Viewed 33

i'm building an online paint with tkinter, and use the function "askcolor" to pick a color. when the color palette is open, i can't receive any data that comes from the server, which causes paintings that someone did on one computer not viewing on the computer of the person who was choosing color. i need a solution that will let me receive data while the color palette is on.

class Paint(object):

    DEFAULT_PEN_SIZE = 5.0
    DEFAULT_COLOR = 'black'

    def __init__(self):
        self.root = Tk()
        self.root.config(cursor="@curs.cur")
        self.root.geometry("1300x731")
        self.root.resizable(width=False, height=False)
        self.c = Canvas(self.root, bg='white', width=1300, height=731)
        self.c.grid(row=0, columnspan=5)
        self.color = "black"
        self.toolbar_img = Image.open("toolbar.png")
        self.zoom = 1
        self.pixels_x, self.pixels_y = tuple([int(self.zoom * x) for x in self.toolbar_img.size])
        self.toolbar_photo = ImageTk.PhotoImage(self.toolbar_img.resize((self.pixels_x, self.pixels_y)))
        self.toolbar = Label(self.root, image=self.toolbar_photo).place(relx=0.5, rely=0.03, anchor='center')


        self.pen_button = Button(self.root, text='pen', command=self.use_pen)
        self.pen_button.place(relx=0.1, rely=0.035, anchor='center')

        self.brush_button = Button(self.root, text='back', command=self.use_brush)
        self.brush_button.place(relx=0.3, rely=0.035, anchor='center')

        self.brush_button = Button(self.root, text='brush', command=self.use_brush)
        self.brush_button.place(relx=0.45, rely=0.035, anchor='center')

        self.color_button = Button(self.root, text='color', command=self.choose_color)
        self.color_button.place(relx=0.6, rely=0.035, anchor='center')

        self.eraser_button = Button(self.root, text='eraser', command=self.use_eraser)
        self.eraser_button.place(relx=0.75, rely=0.035, anchor='center')

        self.choose_size_button = Scale(self.root, from_=1, to=99, orient=HORIZONTAL)
        self.choose_size_button.place(relx=0.9, rely=0.035, anchor='center')


        self.root.protocol("WM_DELETE_WINDOW", self.on_closing)
        self.setup()
        self.run()
        self.root.mainloop()

    def on_closing(self):
        msg = "quit,"
        my_socket.send(msg.encode())
        my_socket.close()
        self.root.destroy()
        exit()


    def setup(self):
        self.old_x = None
        self.old_y = None
        self.old_x2 = None
        self.old_y2 = None
        self.line_width = self.choose_size_button.get()
        self.color = self.DEFAULT_COLOR
        self.eraser_on = False
        self.active_button = self.pen_button
        self.c.bind('<B1-Motion>', self.paint)
        self.c.bind('<ButtonRelease-1>', self.reset)

    def use_pen(self):
        self.activate_button(self.pen_button)

    def use_brush(self):
        self.activate_button(self.brush_button)

    def choose_color(self):
        self.eraser_on = False
        self.color = askcolor(color=self.color)[1]

    def use_eraser(self):
        self.activate_button(self.eraser_button, eraser_mode=True)

    def activate_button(self, some_button, eraser_mode=False):
        self.active_button.config(relief=RAISED)
        some_button.config(relief=SUNKEN)
        self.active_button = some_button
        self.eraser_on = eraser_mode

    def paint(self, event):
        self.line_width = self.choose_size_button.get()
        paint_color = 'white' if self.eraser_on else self.color
        if self.old_x and self.old_y:
            self.c.create_line(self.old_x, self.old_y, event.x, event.y,
                               width=self.line_width, fill=paint_color,
                               capstyle=ROUND, smooth=TRUE, splinesteps=36)
        self.old_x = event.x
        self.old_y = event.y
        data_list = [str(self.old_x), str(self.old_y), paint_color, str(self.line_width), current_room]
        datasend = pickle.dumps(data_list, -1)
        my_socket.sendall(datasend)


    def paint_server(self, x, y, color, width):
        self.line_width = self.choose_size_button.get()
        paint_color = 'white' if self.eraser_on else self.color
        if self.old_x2 and self.old_y2:
            self.c.create_line(self.old_x2, self.old_y2, x, y,
                               width=width, fill=color,
                               capstyle=ROUND, smooth=TRUE, splinesteps=36)
        self.old_x2 = x
        self.old_y2 = y

    def reset(self, event):
        self.old_x, self.old_y = None, None
        self.old_x2, self.old_x2 = None, None
        time.sleep(0.1)
        data=["reset", current_room]
        datasnd = pickle.dumps(data, -1)
        my_socket.send(datasnd)


    def reset_server(self):
        self.old_x, self.old_y = None, None
        self.old_x2, self.old_x2 = None, None


    def run(self):
        while True:
            rlist, wlist, xlist = select.select([my_socket], [my_socket], [])
            for sock in rlist:
                data = sock.recv(1024)
                try:
                    data = pickle.loads(data)
                except:
                    continue
                print(data)
                if data[0] == "reset":
                    self.reset_server()
                else:
                    newx = int(data[0])
                    newy = int(data[1])
                    newcolor = data[2]
                    newwidth = int(data[3])
                    self.paint_server(newx, newy, newcolor, newwidth)
            self.root.update()
0 Answers
Related