Python Forum
[Tkinter] Draw two lines and show independently in one event
Thread Rating:
  • 0 Vote(s) - 0 Average
  • 1
  • 2
  • 3
  • 4
  • 5
[Tkinter] Draw two lines and show independently in one event
#1
Hi, all,

If need display red line first, and wait 2 seconds, draw green line.
However, current program will wait and display two line at a time.
Any idea?

Here is the demo code.
from tkinter import *
import time

def draw_line(event):
    global preX, preY, w
    if preX is not None:
        w.create_line(preX, preY, event.x, event.y, fill='red')
        time.sleep(2)  # sleep for 2 seconds, to ensure that we can find the delay
        w.create_line(preX, preY + 10, event.x, event.y + 10, fill='green')

    preX, preY = event.x, event.y

master = Tk()
w = Canvas(master, width=500, height=500)
w.pack(expand=YES, fill=BOTH)
preX, preY = None, None
w.bind("<ButtonRelease-1>", draw_line)
mainloop()
Reply
#2
I think this happens because you are blocking the mainloop until the function is running.
You can use a class and a thread to do this task:

from tkinter import *
from threading import Thread
import time


class Line:
    def startpoint(self, event):
        self.x1 = event.x
        self.y1 = event.y

    def endpoint(self, event):
        self.x2 = event.x
        self.y2 = event.y
        Thread(target=self.draw).start()

    def draw(self):
        w.create_line(self.x1, self.y1, self.x2, self.y2, fill='red')
        time.sleep(2)
        w.create_line(self.x1, self.y1 + 10, self.x2, self.y2 + 10, fill='green')

master = Tk()
line = Line()
w = Canvas(master, width=500, height=500)
w.pack(expand=YES, fill=BOTH)
w.bind("<ButtonPress-1>", line.startpoint)
w.bind("<ButtonRelease-1>", line.endpoint)
master.mainloop()
Almost dead, but too lazy to die: https://sourceserver.info
All humans together. We don't need politicians!
Reply
#3
(Feb-01-2018, 10:15 AM)DeaD_EyE Wrote: Fabulous. Exactly what I'm searching for. :)
Fabulous. Exactly what I'm searching for. :)

(Feb-01-2018, 10:15 AM)DeaD_EyE Wrote: I think this happens because you are blocking the mainloop until the function is running. You can use a class and a thread to do this task:
 from tkinter import * from threading import Thread import time class Line: def startpoint(self, event): self.x1 = event.x self.y1 = event.y def endpoint(self, event): self.x2 = event.x self.y2 = event.y Thread(target=self.draw).start() def draw(self): w.create_line(self.x1, self.y1, self.x2, self.y2, fill='red') time.sleep(2) w.create_line(self.x1, self.y1 + 10, self.x2, self.y2 + 10, fill='green') master = Tk() line = Line() w = Canvas(master, width=500, height=500) w.pack(expand=YES, fill=BOTH) w.bind("<ButtonPress-1>", line.startpoint) w.bind("<ButtonRelease-1>", line.endpoint) master.mainloop() 
DeaD_EyE, FYI, adding following command also resolve it.
master.update_idletasks()
Reply
#4
(Feb-01-2018, 05:45 PM)haha001 Wrote: DeaD_EyE, FYI, adding following command also resolve it.
I think you can avoid both threads and time.sleep(). First use master.update_idletask() as you said, and use method after() to draw the second line after 2000 milliseconds. Something like
w.after(2000, w.create_line, self.x1, self.y1 + 10, self.x2, self.y2 + 10, fill='green')
Reply
#5
(Feb-01-2018, 08:47 PM)Gribouillis Wrote:
(Feb-01-2018, 05:45 PM)haha001 Wrote: DeaD_EyE, FYI, adding following command also resolve it.
I think you can avoid both threads and time.sleep(). First use master.update_idletask() as you said, and use method after() to draw the second line after 2000 milliseconds. Something like
 w.after(2000, w.create_line, self.x1, self.y1 + 10, self.x2, self.y2 + 10, fill='green') 
Fabulous!!!
Reply


Forum Jump:

User Panel Messages

Announcements
Announcement #1 8/1/2020
Announcement #2 8/2/2020
Announcement #3 8/6/2020