slightlynybbled / tk_tools

Python tkinter tools, Python3.7+
MIT License
101 stars 25 forks source link

RotaryScale blinks on high refresh rate #12

Closed AokiAhishatsu closed 6 years ago

AokiAhishatsu commented 6 years ago

Check this out:

import tkinter as tk
import tk_tools
import threading, random, time

class Runner(threading.Thread):
    def __init__(self, rscale, pause):
        threading.Thread.__init__(self)
        self.rscale = rscale
        self.pause = pause

    def run(self):
        while True:
            self.rscale.set_value(random.randint(0, 101))
            time.sleep(self.pause)

root = tk.Tk()
rs = tk_tools.RotaryScale(root, max_value=100.0, size=100, unit='km/h')
rs.grid(row=0, column=0)

Runner(rs, 0.02).start()

root.mainloop()

If increase the pause to 0.1 it's fine, but what is causing this in first place?

slightlynybbled commented 6 years ago

Thanks, I'll take a look at this.

slightlynybbled commented 6 years ago

Thank you for taking time to look at this.

Tkinter is notoriously unsafe with threading, so your script may work at low rates, but I suspect that the thread interface is interrupting the canvas draws. When working with tkinter, use the after. I have re-written your script to do the same thing with much better results:

import tkinter as tk
import tk_tools
import random

class Runner:
    def __init__(self, parent, rscale, pause):
        self.parent = parent
        self.rscale = rscale
        self.pause = pause

        self.parent.after(self.pause, self.run)

    def run(self):
        self.rscale.set_value(random.randint(0, 101))
        self.parent.after(self.pause, self.run)

root = tk.Tk()
rs = tk_tools.RotaryScale(root, max_value=100.0, size=100, unit='km/h')
rs.grid(row=0, column=0)

Runner(root, rs, 1)

root.mainloop()

Let me know if this addresses your issue so I can close this out. Thanks!

AokiAhishatsu commented 6 years ago

Ok, it was a threading issue. Thx alot! Your solution causes short freezing in my application, so I stick to time.sleep(0.9) for now.

slightlynybbled commented 6 years ago

The solution that I posted updates every 1ms. Maybe try 10 or 100? The after method takes time as milliseconds. I used 1ms to get the fastest update possible to see if it would flash.