4

here's what I have in mind: I have data (numbers) in an OPC server, which I want to retrieve via a GUI. This data should be updated every 5 seconds and therefore also be displayed in the GUI. I had tried this via a while loop, which also works as print output, but then no window is displayed to me anymore.

Would there perhaps someone an idea how I can implement this?

#!/usr/bin/env python
# -*- coding: utf-8 -*-

import Tkinter
from Tkinter import *
import sys
import os
import time
from opcua import Client
    

url = "opc.tcp://xxxxxxx"
client = Client(url)
client.connect()

#create main window
master = Tkinter.Tk()
print('test')
master.title("GUI Raspberry")
master.geometry("900x900")


label = Tkinter.Label(master, text='test')
label2 = Tkinter.Label(master, text='')
label.pack(padx = 5, pady = 10, side = LEFT)

while True:     
    Mean = client.get_node("ns=2;i=3")
    MeanValue = Mean.get_value()
    label2['text'] = MeanValue
    label2.pack(padx = 5, pady = 20, side = LEFT)
    print(MeanValue)
    time.sleep(5)


master.update()
time.sleep(2)

master.mainloop()
master.destroy()
furas
  • 134,197
  • 12
  • 106
  • 148
Aless
  • 63
  • 4
  • are you aware that last four lines are never reached? – Roman Pavelka Aug 20 '21 at 08:16
  • yes I am aware of that, hence my question on how to set it up differently. – Aless Aug 20 '21 at 08:49
  • 1
    It should look like something like this: https://stackoverflow.com/a/459131/12118546 – Roman Pavelka Aug 20 '21 at 09:35
  • using `while True` in any GUI is not good idea. Most GUIs has some `timer` or other method to execute code without blocking `mainloop`. And `tkinter` has `root.after( 5000, function)` to run code after 5 seconds. – furas Aug 20 '21 at 10:27

1 Answers1

3

Using while True is not good idea in any GUI. It blocks mainloop which gets key/mouse event from system, sends them to widgets, runs functions assigned to button and other widgets, (re)draw window and widgets.

You may need to run while True in separated thread - but thread can't update widgets and it would have to send result to main thread - and this makes other problems.

Or you should check if you can use "timer" instead of while to run code periodically.
All GUIs have some "timer" for this.
And tkinter has master.after(milliseconds, function_name)

I couldn't test it but it could looks like this.

#!/usr/bin/env python
# -*- coding: utf-8 -*-

import sys
import os
import time
import Tkinter as tk
from opcua import Client
    
# --- functions ---

def function():
    mean = client.get_node("ns=2;i=3")  # PEP8: `lower_case_name` for variables
    mean_value = mean.get_value()       # PEP8: `lower_case_name` for variables
    label2['text'] = mean_value
    print(mean_value)
    master.after(5000, function)  # run again after 5000ms (5s)
    
# --- main ---

url = "opc.tcp://xxxxxxx"
client = Client(url)
client.connect()

# create main window  # PEP8: in comment add space after `#` (and two spaces before `#` if it is in line with code)
master = tk.Tk()
print('test')
master.title("GUI Raspberry")
master.geometry("900x900")

label1 = tk.Label(master, text='test')
label1.pack(padx=5, pady=10, side='left')

label2 = tk.Label(master, text='')
label2.pack(padx=5, pady=20, side='left')  # show it only once

function()  # run first time

master.mainloop()

PEP 8 -- Style Guide for Python Code

furas
  • 134,197
  • 12
  • 106
  • 148