Globale Variable (GUI mit Page)

Fragen zu Tkinter.
Antworten
Tinker232
User
Beiträge: 38
Registriert: Mittwoch 25. Juli 2018, 13:45

Mittwoch 25. Juli 2018, 14:11

Hallo Leute,

ich bin ganz neu auf diesem Gebiet unterwegs und möchte einen kleinen Daten loger mit dem RPi bauen. Dazu habe ich mittels dem Tool Page eine kleines GUI erstellt mit 4 Buttons.
Den Code habe für das GUI habe ich nun generiert und mittels Geany möchte ich die Funktionen füllen... soweit zum Projekt.
Page hat mir zwei .py angelegt, einmal MeinProjekt.py und MeinProjekt_support.py. Soweit ich das verstanden habe setze ich meine ganzen Funktionen nun in das ..._support.py.
Das funktioniert auch teilweise....

Mein eigentliches Problem ist, das ich gerne sobald der Start-Button im GUI betätigt wird eine globale Variable namens gstat von 0 auf 1 gesetzt wird.
Dies möchte ich nutzen um diverse andere Funktionen zu ermöglichen, z.B. Visualisierung einer Led auf Rot oder das der Text des buttons von "Start" auf "Stop" geändert wird.
Ich habe desweiteren noch eine weitere Funktion die meinen Status abfragt, den ich nutze um zu schauen ob sie die globale Variable wirklich geändert hat. Aber das tut sie nicht!
Die globale Variable wird in der def init deklariert, bzw. diese habe ich dort einfach hinzugefügt (def init wurde von PAGE erstellt)

Code: Alles auswählen

...

def init (top, gui, *args, **kwargs):
       global w, top_level, root, stat
       w = bla
       top_level usw...
       stat = 0
       request_status()

def request_status():
       if stat == 0:
               print("Wartet auf Anweisung")
       else:
              print("Zeichnet auf")

def Button_pressed(p1):
       print("Startet")
       stat = 1
       request_status()

....
Wie bereits erwähnt ändert sich der Status überhaupt nicht... Wieso?
Was mich ebenso irritiert ist, dass der Code vom PAGE bei den Bindings für den Button immer ein Parameter p1 drinstehen hat?! Was hat es damit auf sich?

Hoffe ihr könnt mir helfen :)

Danke Euch
LG Tina
Benutzeravatar
__blackjack__
User
Beiträge: 1435
Registriert: Samstag 2. Juni 2018, 10:21

Mittwoch 25. Juli 2018, 15:56

Vergiss als erstes das es ``global`` gibt, und am besten dann auch gleich die Existenz von PAGE. Das Programm erzeugt echt gruseligen Quelltext. Und so schwer ist es nun auch nicht Tk-GUIs programmatisch zu erstellen.

Allerdings wie gesagt, ohne ``global``, also sollte man bevor man sich an GUIs wagt, schon halbwegs sicher in den Grundlagen bis einschliesslich objektorientierter Programmierung (OOP) sein. Die braucht man nämlich für jede nicht-triviale GUI.

Code: Alles auswählen

    **** COMMODORE 64 BASIC V2 ****
 64K RAM SYSTEM  38911 BASIC BYTES FREE
   CYBERPUNX RETRO REPLAY 64KB - 3.8P
READY.
█
Tinker232
User
Beiträge: 38
Registriert: Mittwoch 25. Juli 2018, 13:45

Donnerstag 26. Juli 2018, 10:56

Danke für deine Antwort...
Na klar bin ich kein Profi, aber ich habe bereits vorher schon einige TK Guis so erstellt. Wollte es eben mal über einen Designer probieren. Werde vermutlich dann auf QtCreator umsteigen...
Ich muss mich in die ganze Sache eben schritt für schritt reinarbeiten. Wieso meinst du soll ich globale Variablen vergessen?
Ist es für manche Fälle nicht einfacherer, wie in meinem bei einer status variable diese global zu definieren?
Vielleicht eine doofe Frage, aber verzeiht mir meine "noch" Unwissenheit :-)
LG
Benutzeravatar
sls
User
Beiträge: 244
Registriert: Mittwoch 13. Mai 2015, 23:52
Wohnort: Tannhauser Gate

Donnerstag 26. Juli 2018, 11:27

Tinker232 hat geschrieben:
Donnerstag 26. Juli 2018, 10:56
Wieso meinst du soll ich globale Variablen vergessen?
Weil die Verwendung von global in den allermeisten Fällen falsch ist, zu unerwarteten Nebeneffekten und zu einem schwer nachvollziehbaren Programmstatus führen kann.
Tinker232 hat geschrieben:
Donnerstag 26. Juli 2018, 10:56
Ist es für manche Fälle nicht einfacherer, wie in meinem bei einer status variable diese global zu definieren?
Deine Funktion `request_status()` sollte den Wert vom Status über einen Parameter erhalten.

Außerdem solltest du dir PEP8 anschauen, `w` usw. sind keine eindeutigen Variablenbezeichner, diese sollten eindeutig beschreiben was eine Variable macht / wofür sie gut ist. Funktionen / Methoden schreibt man in Python klein_mit_unterstrich.
With great processing power comes great responsibility.
Tinker232
User
Beiträge: 38
Registriert: Mittwoch 25. Juli 2018, 13:45

Donnerstag 26. Juli 2018, 13:10

Alles klar! Danke...
Aber wie kann ich es ermöglichen, dass viele Funktionen auf diese variabel status zurückgreifen können bzw sie auswerten. Z.b. beim drücken des Beenden-Button soll geprüft werden welcher Wert die Variable status hat und entsprechend dann reagieren, aber dazu muss ich den Wert von status ja in diese Funktion bekommen... Wie mache ich das :/
LG Tina
Benutzeravatar
sls
User
Beiträge: 244
Registriert: Mittwoch 13. Mai 2015, 23:52
Wohnort: Tannhauser Gate

Donnerstag 26. Juli 2018, 13:50

Wie gesagt, in dem du den Status der Funktion übergibst. Der Status wird ja irgendwo gesetzt, in deinem Falle bei `button_pressed()`, innerhalb dieser Funktion rufst du ja sogar die Funktion `request_status()` auf, das eignet sich doch gut um den Status als Parameter an diese Funktion zu übergeben.

Code: Alles auswählen

def request_status(status):
    if status == 0:
        print("Wartet auf Anweisung")
    else:
        print("Zeichnet auf")

def button_pressed(p1):
    print("Startet")
    status = 1
    request_status(status)
Ich glaube aber, dass du dich wirklich in Python einarbeiten solltest. Ich bin mir nicht sicher, ob man *so* programmieren möchte. Ich verstehe auch nicht so recht, warum du Parameter wie `gui` in eine Pseudo-Init-Funktion übergibst. GUI und "Geschäfts"logik sollten nicht vermengt werden. Eine andere Überlegung ist auch, ob man eine Klasse für dein Programm entwirft (neben GUI-Logik), in welcher ein Attribut mit dem Status existiert das von mehreren Methoden innerhalb der Klasse verwendet werden kann. Wie gesagt, dafür solltest du dir aber die Mühe machen und entsprechende Tutorials durchackern, alles andere führt mit wachsendem Programmfortschritt nur zu Spaghetti-Code.
With great processing power comes great responsibility.
Benutzeravatar
__blackjack__
User
Beiträge: 1435
Registriert: Samstag 2. Juni 2018, 10:21

Donnerstag 26. Juli 2018, 15:08

@sls: Fast alles von dem gezeigten Code ist ja von PAGE generiert. Das kann man Tinker232 nicht anlasten. Siehe auch den generierten Quelltext in der PAGE-Dokumentation: http://page.sourceforge.net/html/modules.html

Ach so: PAGE benutzt auch `place()` für's Layout, weil der Author von dem Programm das von VisualBasic her kennt und mag. Vorsichtig ausgedrückt: das ist für die Tonne.

Code: Alles auswählen

    **** COMMODORE 64 BASIC V2 ****
 64K RAM SYSTEM  38911 BASIC BYTES FREE
   CYBERPUNX RETRO REPLAY 64KB - 3.8P
READY.
█
Tinker232
User
Beiträge: 38
Registriert: Mittwoch 25. Juli 2018, 13:45

Montag 30. Juli 2018, 08:21

Danke für die Ratschläge! Richtig, das hat Page generiert...
Ich habe mich die letzten Tage nun eingelesen, möchte dennnoch ein GUI Designer verwenden. Welches Tool könnt ihr mir empfehlen?
Ich dachte jetzt an QtCreator?
LG Tina
__deets__
User
Beiträge: 3704
Registriert: Mittwoch 14. Oktober 2015, 14:29

Montag 30. Juli 2018, 09:04

QtCreator ist kein GUI Designer. Das ist eine IDE. Aber Qt kommt mit Designer”, und der ist ganz gut.
Antworten