0
import tkinter as tk  
import time

class Example(tk.Toplevel):

    def __init__(self, root):
        tk.Toplevel.__init__(self, root)
        self.canvas = tk.Canvas(self, borderwidth=0, background="#ffffff")
        self.frame = tk.Frame(self.canvas, background="#ffffff")
        self.vsb = tk.Scrollbar(self, orient="vertical", command=self.canvas.yview)
        self.canvas.configure(yscrollcommand=self.vsb.set)

        self.vsb.pack(side="right", fill="y")

        self.canvas.pack(side="left", fill="both", expand=True)
        self.canvas.create_window((4,4), window=self.frame, anchor="nw", 
                              tags="self.frame")

        self.frame.bind("<Configure>", self.onFrameConfigure)

        self.populate()

        self.l= tk.Label(self.frame, text= 1)
        self.l.grid()
        self.cb= tk.Button(self.frame, text= "asdf", command= self.cnt)
        self.cb.grid()
    def cnt(self):
        slowlist= []
        slow= 0
        for x in range(10000):
            now= time.time()
            self.l["text"]+=1
            end= time.time()
            if end-now >= 0.001:
                slow+=1
                slowlist.append(end-now)
        print (slow)
        print (slowlist[:5])

    def populate(self):
        '''Put in some fake data'''
        for row in range(100):
            tk.Label(self.frame, text="%s" % row, width=3, borderwidth="1", 
                 relief="solid").grid(row=row, column=0)
            t="this is the second column for row %s" %row
            tk.Label(self.frame, text=t).grid(row=row, column=1)

    def onFrameConfigure(self, event):
        '''Reset the scroll region to encompass the inner frame'''
        self.canvas.configure(scrollregion=self.canvas.bbox("all"))

if __name__ == "__main__":
    root=tk.Tk()
    Example(root)
    root.mainloop()

Above is my code, a large part of the code comes from this post. And I am concerned when I repeatedly update the label text by using self.l["text"]+=1, there would be rare cases (about 70 instances out of 10000 updates) that it takes around 0.11 sec to update the label text, while the remaining iterations act a lot faster.

I wonder a) why would there be cases where updating become considerably slower? especially when it seems kind of constant to have about 70 slow cases in every iteration of 10000, I wonder if there is any reason for that "constant" time drift. and b) how to avoid those slow instances when running a large iteration loop that requires to update the label text quite often?

  • Please fix the formatting of your code. – Bryan Oakley Jul 11 '18 at 19:41
  • I just fixed the formatting of the first line, guess that's where the problem is. Do you have any idea why the above question would appear? or maybe what information would be helpful? – nakamurayuristeph Jul 11 '18 at 19:49
  • There are still problems with the formatting. The import statements aren't part of the code block. – Bryan Oakley Jul 11 '18 at 19:54
  • So I think we don't have any insight into this issue at this time. For those who are interested in the problem, please feel free to forward this to whomever you think might help so that the community might be able to benefit from their solutions. – nakamurayuristeph Jul 24 '18 at 19:28

1 Answers1

0

I am still uncertain about the reason for the overhead and how to resolve it, but here's a partial way around to reduce the impact.

So we know that there would be about 70 slow cases out of 10000 consecutive runs, I found out that this result is actually proportional to the amount of runs executed. Simply, around every 140 times of execution of tkLabelObject["text"]= "value reassignment" would emerge one slow execution such that it takes 0.01 sec to reassign the value and present on GUI (consider the fact that other 139 executions' time elapse couldn't be catched within 1xe-07 timeframe, that 0.01 sec execution is significantly slow).

As a result, to reduce such impact is to call a short break after about every 130 executions. so doing the following would be able to avoid "slow cases" in updating tkLabel text 10000 times (well, the example code only update 9100 times, but we just need to change the range value in the first for loop to adjust)

import time

for x in range(70):

    time.sleep(0.0000000001) 

    for x in range(130):

        tkLabelObj["text"]= "value reassignment"

But then, this is by no means the best practice. As stated upfront, I consider this to just be a way around until more elegant solutions emerge.