Seite 1 von 1

GUI Label Werte aktualisieren

Verfasst: Samstag 6. April 2019, 06:43
von Kevin214
Grüße,

Ich lasse mir Werte aus einer SPS in einer GUI anzeigen. Leider werden die Werte, die mir angezeigt werden, nicht aktualisiert.
Ich habe hier schon viel über die "While True" Schleife innerhalb eines Tkinter Programmes gelesen, aber ich kann mir leider nichts aus den vielen codes zusammen addieren das funktioniert.
Wichtig ist mir auch, dass das Programm überschaubar bleibt und es für meine Kollegen, die fast nichts mit python am Hut haben, relativ verständlich bleibt.


Villeicht kann mir jemand von euch auf die Sprünge helfen oder einen Lösungsvorschlag geben...
auch wenn euch das Thema eventuell schon nervt, wäre ich euch sehr dankbar dafür :D

Code: Alles auswählen

# -*- coding: utf-8 -*- 
from time import sleep
import time
import snap7
from snap7 import util
from snap7.util import *
import struct
from Tkinter import *


root = Tk()
root.title("Übersicht Auftrag")
root.geometry("2000x1200")
	
					
plc = snap7.client.Client()
plc.connect("192.168.0.1", 0, 2)
con = plc.get_connected()
print ("---PLC connected: "), con
data_all = plc.db_read(db_number=21, start=0, size=226)
data1 = util.get_int(data, 0)
data2 = util.get_dword(data, 64)
data3 = util.get_dword(data, 72)	


Label(root, 
			text='Auftrag Sollzahl:= ' + str (data2) +  'stk.',
			font = "Verdana 40 bold").pack()
Label(root, 
			text='Auftrag Istzahl:= ' + str (data3) +  'stk.',
			font = "Verdana 40 bold").pack()
			
Label(root, 
			text='Taktzahl:= ' + str (data1) +  'stk.',
			font = "Verdana 40 bold").pack()


root.mainloop()




Re: GUI Label Werte aktualisieren

Verfasst: Samstag 6. April 2019, 09:55
von Sirius3
Erstens kein Python2 mehr benutzen, das ist veraltet.
Zweitens, keine *-Importe.
Drittens, struct, time und time.sleep werden importiert aber gar nicht benutzt. ebenso nichts, was Du per `from snap7.utils import *` importierst.
Viertens, `data` ist nirgends definiert. `data123` sind auch zu generische Namen, Du weißt doch konkret, was die Zahlen bedeuten.

Um etwas zu aktualisieren, muß man das explizit machen, die statischen Texte in den Labels ändern sich nicht auf magische Art und Weise.

Das ganze in Python3.7:

Code: Alles auswählen

import tkinter as tk
import snap7
from snap7 import util

def update(labels, plc):
    data = plc.db_read(db_number=21, start=0, size=226)
    taktzahl = util.get_int(data, 0)
    sollzahl = util.get_dword(data, 64)
    istzahl = util.get_dword(data, 72)
    labels[0]['text'] = f"Auftrag Sollzahl:= {sollzahl}stk."	
    labels[1]['text'] = f"Auftrag Istzahl:= {istzahl}stk."	
    labels[2]['text'] = f"Auftrag Taktzahl:= {taktzahl}stk."
    labels[0].after(1000, update, labels, plc)

def main():
    root = tk.Tk()
    root.title("Übersicht Auftrag")
    root.geometry("2000x1200")
    plc = snap7.client.Client()
    plc.connect("192.168.0.1", 0, 2)
    labels = [
        tk.Label(root, font="Verdana 40 bold")
        for _ in range(3)
    ]
    for label in labels:
        label.pack()
    update(labels, plc)
    root.mainloop()

if __name__ == '__main__':
    main()

Re: GUI Label Werte aktualisieren

Verfasst: Samstag 6. April 2019, 22:06
von Kevin214
Hallo,

Vielen Dank für den Code :)
Leider kommt bei:

labels[0] ['text'] = f"Auftrag Sollzahl:= {sollzahl}stk."

die Fehlermeldung:

SyntaxError: invalid syntax

Woran könnte es liegen?

Und kannst du mir eventuell noch verraten wie bzw wo genau im Code ich die Labels an sich programmieren kann?
Angenommen ich möchte die Labels unterschiedlich groß und an unterschiedlichen Stellen im Bild haben?

Schonmal ein großes Dankeschön im Vorraus :D

Re: GUI Label Werte aktualisieren

Verfasst: Samstag 6. April 2019, 22:33
von Sirius3
Wie schon geschrieben, mein Beispiel ist für Python3.7.

Re: GUI Label Werte aktualisieren

Verfasst: Samstag 6. April 2019, 22:37
von Kevin214
okay, aber ich Habe im Terminal eingegeben:

python3 Dateiname.py

dürfte doch dann mit Python3.x bearbeitet werden?

Re: GUI Label Werte aktualisieren

Verfasst: Sonntag 7. April 2019, 00:45
von __deets__
3.x. — f-strings gibt es erst ab 3.6.

Re: GUI Label Werte aktualisieren

Verfasst: Sonntag 7. April 2019, 03:43
von Kevin214
Ja habe ich auch mitbekommen.
Dachte eigentlich das ich das neuste update habe...
Wäre cool wenn mir nochmal jemand kurz erklären könnte wie ich die Labels unterschiedlich groß und an verschiedenen Positionen bringen kann.

Habe es jetzt folgendermaßen programmiert:

Code: Alles auswählen

#!/usr/bin/env python3
import tkinter as tk
import snap7
from snap7 import util

def update(labels, plc):
    data = plc.db_read(db_number=21, start=0, size=226)
    taktzahl = util.get_int(data, 0)
    sollzahl = util.get_dword(data, 64)
    istzahl = util.get_dword(data, 68)
    labels[0]['text'] = "Auftrag Sollzahl: = " + str(sollzahl) + " stk."	
    labels[1]['text'] = "Auftrag Istzahl: = " + str(istzahl) + "stk."	
    labels[2]['text'] = "Auftrag Taktzahl: = " + str(taktzahl) + "stk."
    labels[0].after(100, update, labels, plc)

def main():
    root = tk.Tk()
    root.title("Übersicht Auftrag")
    root.geometry("2000x1200")
    plc = snap7.client.Client()
    plc.connect("192.168.0.1", 0, 2)
    labels = [
        tk.Label(root, font="Verdana 40 bold")
        for labels in range(3)
    ]
    for label in labels:
        label.pack()
    update(labels, plc)
    root.mainloop()

if __name__ == '__main__':
    main()


Re: GUI Label Werte aktualisieren

Verfasst: Sonntag 7. April 2019, 08:49
von Sirius3
Statt `f"Auftrag Sollzahl:= {sollzahl}stk."` kann man in älteren Versionen

Code: Alles auswählen

"Auftrag Sollzahl:= {}stk.".format(sollzahl)
schreiben.

Schriftgröße gibst Du doch schon an, und wie Du die Labels positionieren willst, davon hängt ab, wie man das am besten macht.

Re: GUI Label Werte aktualisieren

Verfasst: Sonntag 7. April 2019, 10:49
von wuf
Hi Kevin214

Hier mein Tipp für eine GUI-Darstellung:

Code: Alles auswählen

#!/usr/bin/env python3
import tkinter as tk
import random
#import snap7
#from snap7 import util

from functools import partial

import tkinter as tk

APP_TITLE = "Snap7 Display"
APP_XPOS = 100
APP_YPOS = 100
APP_WIDTH = 2000 #2000
APP_HEIGHT = 1200 #1200


class Application(object):
    LABELS = ["Auftrag Sollzahl", "Auftrag Istzahl", "Auftrag Taktzahl"]
    LABEL_FONT = "Verdana 40 bold"
    VALUE_LABEL_WIDTH = 6


    def __init__(self, main_win):
        self.main_win = main_win
        
        self.label_vars = list()
        self.build()
        self.display_test_loop()
        
    def build(self):
        main_frame = tk.Frame(self.main_win)
        main_frame.pack(fill='both', expand=True)

        label_frame = tk.Frame( main_frame)
        label_frame.pack(expand=True)
        
        name_label_width = 0
        for label in self.LABELS:
            if len(label) > name_label_width:
                name_label_width = len(label)

        for index, label in enumerate(self.LABELS):
            tk.Label(label_frame, font=self.LABEL_FONT, bg='gray60', fg='white',
                text="{}:".format(label), width=name_label_width, anchor='e',
                padx=20
                ).grid(row=index, column=0, pady=6)
            var = tk.StringVar(self.main_win, 0)
            tk.Label(label_frame, font=self.LABEL_FONT, textvariable=var,
                 width=self.VALUE_LABEL_WIDTH, bg='white'
                ).grid(row=index, column=1, pady=6)
            self.label_vars.append(var)

    def display_test_loop(self):
        for index, var in enumerate(self.label_vars):
            random_value = random.randint(0, 200)
            var.set(random_value)
        self.main_win.after(500, self.display_test_loop)
            
            
def main():
    main_win = tk.Tk()
    main_win.title(APP_TITLE)
    #main_win.geometry("+{}+{}".format(APP_XPOS, APP_YPOS))
    main_win.geometry("{}x{}".format(APP_WIDTH, APP_HEIGHT))
    
    app = Application(main_win)
    
    main_win.mainloop()
 
 
if __name__ == '__main__':
    main()      
Versuche deine Snap7 Zugehörigkeiten selber zu integrieren. Viel Spass beim Studium.

Gruss wuf :-)

Re: GUI Label Werte aktualisieren

Verfasst: Sonntag 7. April 2019, 12:42
von Sirius3
@wuf: statt `max` nachzuprogrammieren, am besten es direkt nutzen:

Code: Alles auswählen

name_label_width = max(map(len, self.LABELS))
`label_vars` wird in `__int__` angelegt, aber erst in `build` gefüllt. Da wäre es besser `build` wegzulassen und alles gleich in __init__ zu integrieren.
ikinter wird zwei mal importiert, partial importiert aber nie benutzt.