Python Forum
[Tkinter] Tkinter GUI gets very slow and stuck
Thread Rating:
  • 0 Vote(s) - 0 Average
  • 1
  • 2
  • 3
  • 4
  • 5
[Tkinter] Tkinter GUI gets very slow and stuck
#1
Hello,
I have created a Tkinter GUI script which monitor a PLC unit's I/O's in real time.
Therefore , i created a Modbus TCP/IP communication to the PLC client so i receive the digital input register as a list of 30 elements.
In order to monitor those digital inputs and update their status i created LED symbols that turn green if the status is True and turn red if the status changes to False.
In order to change the status (acts like real time) i used .after() methods inside multiple functions that executes them every 0.5 second
The problem takes place when i adds more Led widgets like that which bound to one of the input register.

I think that the multiple usage of .after() method caused the problem , so as many bound widgets as i add , the more the gui gets slower and even stuck at some point.
Here is an example of a function with that method that i wrote:
class dig_in_rec():
    def __init__(self, canvas , index, x1,y1,x2,y2 ,label, img1 , img2):
        self.canvas = canvas
        self.index = index
        self.x1 = x1
        self.y1 = y1
        self.x2 = x2
        self.y2 = y2
        self.img1 = img1
        self.img2 = img2
        self.label=label

    def rec_create(self):

        in_arr = md.rd_dig_in(0, 30)
        self.label.place(x=self.x1, y=self.y1)
        if in_arr[self.index] == True:
            self.label.config(image=self.img1)


        elif in_arr[self.index] == False:
            self.label.config(image=self.img2)



        self.canvas.after(500, self.rec_create)
Reply
#2
Does any of these methods have loops, pauses, long-running code, that would block the GUI main loop? if so they will need to run in a separate thread.
Reply
#3
Are you calling md.rd_dig_in for each lamp? If you have 30 digital inputs that is 30 Modbus reads just to update each lamp once. Why not read the digital inputs once and then update all the lamps at the same time?
Reply
#4
how should i update them at once?
Reply
#5
I mean read all the input values and then update all the lamps. I think you are reading all the input values and update one lamp, repeat for each lamp. It doesn't take long to set 30 images, so the poor performance must be from reading the Modbus.

You should also have your lamps remember their state and only change the image when the associated digital input value changes. Not only will that be faster, but it gets rid of any redraw flicker.
class DigitalInputLamp():
    
    def __init__(self, x1, y1, x2, y2, label, img1 , img2):
        self.x1 = x1
        self.y1 = y1
        self.x2 = x2
        self.y2 = y2
        # Are images same for all lamps?  Make a class variable?
        self.images = [img1, img2]
        self.label = label
        # Placing widget should probably happen outside the class
        # when the widget is created
        self.label.place(x=self.x1, y=self.y1)
        self.state = 0
        self.label.config(image=self.images[self.state))

    def show_state(self, state):
        if state != self.state:
            self.state = state
            self.label.config(image=self.images[self.state))


def update_lamps(lamps, period, canvas):
    digital_inputs = md.rd_dig_in(0, len(lamps))
    for i, lamp in enumerate(lamps)
        lamp.show_state(digital_inputs[i])
    canvas.after(period, lamps)


# Make a bunch of lamps and start updating
lamps = []
for I in range(number_of_lamps)
    lamps.append(DigitalInputLamp…
...
update_lamps(lamps, 500, canvas)
Reply
#6
Thanks for the response ill try that
Reply
#7
When i run this code:
import Modbus_PLC as md
from tkinter import *


class DigitalInputLamp():

    def __init__(self, x1, y1, label, img1, img2):
        self.x1 = x1
        self.y1 = y1

        # Are images same for all lamps?  Make a class variable?
        self.images = [img1, img2]
        self.label = label
        # Placing widget should probably happen outside the class
        # when the widget is created
        self.label.place(x=self.x1, y=self.y1)
        self.state = 0
        self.label.config(image=self.images[self.state])

    def show_state(self, state):
        if state != self.state:
            self.state = state
            self.label.config(image=self.images[self.state])
#############################################################



def Main_Page():

    root1 = Tk()
    root1.title("GUI App")

    canvas44 = Canvas(root1, height=512, width=898)
    canvas44.pack()
    img_butt8 = PhotoImage(file='C:\\Users\\Omer\\Desktop\\Green_led1.png')
    img_butt9 = PhotoImage(file='C:\\Users\\Omer\\Desktop\\Red_led1.png')
    label1 = Label(canvas44)
    label2 = Label(canvas44)
    label3 = Label(canvas44)
    label4 = Label(canvas44)
    label5 = Label(canvas44)
    label_list=[label1,label2,label3,label4,label5]
    # Make a bunch of lamps and start updating
    lamps = [DigitalInputLamp(i*80,10,label_list[i], img_butt8,img_butt9) for i in range(5)]
    update_lamps(lamps, 500, canvas44)
    print(lamps)
    root1.mainloop()


def update_lamps(lamps, period, canvas):
    digital_inputs = md.rd_dig_in(0, len(lamps))
    for i, lamp in enumerate(lamps):
        lamp.show_state(digital_inputs[i])
    canvas.after(period, lamps)


Main_Page()
Main_Page()[/python]

I get lamp.show_state as NoneType object:
Output:
Traceback (most recent call last): File "C:/Users/Omer/test.py", line 57, in <module> Main_Page() File "C:/Users/Omer/test.py", line 45, in Main_Page update_lamps(lamps, 500, canvas44) File "C:/Users/Omer/test.py", line 53, in update_lamps lamp.show_state(digital_inputs[i]) TypeError: 'NoneType' object is not subscriptable
Reply
#8
The line
digital_inputs = md.rd_dig_in(0, len(lamps))
is returning None not the iterable you are expecting.
Reply
#9
yes , i just dont understand why...it supposed to read digital input through modbus tcp/ip
Reply
#10
What does the rd_dig_in code look like? I cannot find the Modbus_PLC package.
Reply


Possibly Related Threads…
Thread Author Replies Views Last Post
  [Tkinter] Button widget gets stuck from using tkinter.messagebox? Nwb 2 3,892 Jun-20-2018, 02:21 PM
Last Post: Nwb

Forum Jump:

User Panel Messages

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