LionSora
Posts: 5
Joined: Mon Jul 20, 2020 12:38 am

Real Time GUI help on loops

Mon Aug 10, 2020 2:30 am

Good day all, currently I'm working on a project using Python. Before that, my Python level is at beginner level, so yeah, there are a lot of stuff I'm still learning. So my project is about doing a Real Time GUI, I'm learning on how to use Tkinter and PyQt, at the same time I'm using freeopcua to obtain data in a loop to get it real time. Both of them requires a loop, so should I use threading? or is there any other method that allow me to use both of them together. I did some study and I'm kinda lost. Thank you in advance.

jayben
Posts: 80
Joined: Mon Aug 19, 2019 9:56 pm

Re: Real Time GUI help on loops

Mon Aug 10, 2020 8:01 am

Yes, you do need to create a separate thread for the data acquisition, but to start with, I'd ignore the OPC UA application, and just create a data acquisition thread that generates some simple dummy data, such as reporting the time every second.

Then the question is how your display thread accesses that information, bearing in mind that you have little control over when each thread is executed. You can't just use global variables; you need a 'thread safe' mechanism for data access. There are various ways to do this, the easiest is probably a queue, as I've used in my OpenCV example https://iosoft.blog/rpi-camera-display-pyqt-opencv/ Basically the data acquisition application feeds data in, and the display application retrieves and displays it.

Alternatively you can use signals (a message with data), so the arrival of the signal triggers the display application to do an update; I've written a simple serial comms application that uses the technique, see https://iosoft.blog/pyqt-serial-terminal/

Finally, don't forget to clean up the threads when your program exits, or it may hang.

LionSora
Posts: 5
Joined: Mon Jul 20, 2020 12:38 am

Re: Real Time GUI help on loops

Tue Aug 11, 2020 3:42 am

Yes, you do need to create a separate thread for the data acquisition, but to start with, I'd ignore the OPC UA application, and just create a data acquisition thread that generates some simple dummy data, such as reporting the time every second.

Then the question is how your display thread accesses that information, bearing in mind that you have little control over when each thread is executed. You can't just use global variables; you need a 'thread safe' mechanism for data access. There are various ways to do this, the easiest is probably a queue, as I've used in my OpenCV example https://iosoft.blog/rpi-camera-display-pyqt-opencv/ Basically the data acquisition application feeds data in, and the display application retrieves and displays it.

Alternatively you can use signals (a message with data), so the arrival of the signal triggers the display application to do an update; I've written a simple serial comms application that uses the technique, see https://iosoft.blog/pyqt-serial-terminal/

Finally, don't forget to clean up the threads when your program exits, or it may hang.
Thanks for the reply, so I really need threading for this case. This makes me wonder, is there a limit on how many threads that I can use? Cause I'm currently applying it in a Raspberry Pi for my project. I noticed when I took like few data and process it with simple calculation, the system took some times to answer it. This is where threading shines right?

I will try looking into how to use queue. Seems like I still got a lot to learn before I can apply it.

I will look into the method you written. Thanks alot ya! It really gave me an idea on how to proceed with my project.

MarkDH102
Posts: 409
Joined: Fri Feb 13, 2015 3:18 pm

Re: Real Time GUI help on loops

Tue Aug 11, 2020 6:16 am

In Tkinter

Code: Select all

def functionName() :
  doStuff
 ' Repeat every 5000mS
  root.after(5000, functionName)
Then in the startup part of the code

Code: Select all

' start the timed interval stuff running before getting the Tkinter loop running
functionName()
root.mainloop()
This avoids threading...

LionSora
Posts: 5
Joined: Mon Jul 20, 2020 12:38 am

Re: Real Time GUI help on loops

Tue Aug 11, 2020 8:13 am

In Tkinter

Code: Select all

def functionName() :
  doStuff
 ' Repeat every 5000mS
  root.after(5000, functionName)
Then in the startup part of the code

[code]' start the timed interval stuff running before getting the Tkinter loop running
functionName()
root.mainloop()
This avoids threading...
So I'm just curious, how do I control the root.mainloop? Normal loop you can use the root.after, how bout the mainloop? It keeps on refreshing right? How do I call the loop?

MarkDH102
Posts: 409
Joined: Fri Feb 13, 2015 3:18 pm

Re: Real Time GUI help on loops

Tue Aug 11, 2020 9:54 am

Code: Select all

root.mainloop()
runs all the Tkinter GUI stuff automatically, generating events that you link functions to when buttons are pressed etc.

Code: Select all

def resetAllMinMax(e):
    #Do all the reset stuff

Code: Select all

btnResetAll=Button(root, text="Reset ALL Mn/Mx", width=20)
btnResetAll.bind('<Button-1>',resetAllMinMax)
So for example when the button called btnResetAll is clicked, the

Code: Select all

root.mainloop() 
(part of Tkinter internals) code automatically sees that there is a function bound to it called resetAllMinMax() and calls it.

Code: Select all

root.mainloop()
once it has been called does not return to the user.
Any other regular things that need to be called in a Tkinter application can either be done using threading or by using multiple

Code: Select all

root.after()
type functions.

Return to “Python”