Seite 1 von 1

Pfad in image variabel

Verfasst: Mittwoch 15. Juli 2020, 12:27
von metme01454
Hallo liebe Gemeinde,

ich hoffe ich bin hier richtig und ihr könnt mir helfen. :-)

Meine Python Erfahrungen sind wirklich rudimentär und ich möchte das gern ändern. Ich hab ein relativ "einfaches" Problem:
Ich lasse mir ein Bild ausgeben über:

Code: Alles auswählen

 picture = Picture(app, image="/home/pi/Documents/test.jpg", grid=[0,2]) 
Das funktioniert auch super. Nun möchte ich aber den Pfad variabel definieren. Das sieht dann ungefähr so aus:
Weiter oben möchte ich eine eingelesene RFID ID in den Pfad schreiben:

Code: Alles auswählen

foto.value = "/home/pi/Documents/" + row["RFid"] + ".jpg"
Wenn ich mir nun weiter unten die Variable ausgeben lasse, kommt das von mir gewünschte Ergebnis raus:
/home/pi/Documents/1234567891.jpg
Nun möchte ich die Variable foto benutzen als Pfadangabe in dem Code:

Code: Alles auswählen

 picture = Picture(app, image=FOTO, grid=[0,2]) 
Das scheint aber nicht zu gehen, habe die unterschiedlichsten Varianten probiert.
Hab ich hier einen Denkfehler?

Danke vorab
Grüße
Steve

Re: Pfad in image variabel

Verfasst: Mittwoch 15. Juli 2020, 12:50
von Sirius3
Was ist denn foto für ein Objekt, dass es ein value-Attribut hat?

Und genau das mußt Du auch verwenden:

Code: Alles auswählen

picture = Picture(app, image=foto.value, grid=[0,2]) 
Falls das nicht tut:
Was Du genau machst, kann man an Deinen Code-Fragmenten nicht sehen. Bitte poste den kompletten relevanten Code und die ganze Fehlermeldung inclusive Traceback.

Re: Pfad in image variabel

Verfasst: Mittwoch 15. Juli 2020, 12:54
von sparrow
Erstmal: fot.value und FOTO sind für mich zwei grundverschiedene Namen.
"Scheint nicht zu gehen" ist nicht sehr konkret. Was geht nicht? Fehlermeldung? Bitte die komplette Fehlermeldung + den Code, der sie auslöst.

Pfade baut man nicht mit + zusammen sondern benutzt pathlib.

Code: Alles auswählen

>>> import pathlib
>>> root = pathlib.Path("c:\\")
>>> root
WindowsPath('c:/')
>>> root / "Windows"
WindowsPath('c:/Windows')
>>> filename = "write"
>>> root / "Windows" / f"{filename}.exe"
WindowsPath('c:/Windows/write.exe')

Re: Pfad in image variabel

Verfasst: Mittwoch 15. Juli 2020, 14:15
von metme01454
Ok, danke schon mal für die bisherigen Antworten.
@Sirius3:
foto wird ganz am Anfang leer deklariert

Code: Alles auswählen

 foto = "" 
Im Verlauf des Skriptes soll dann ein RFID Tag ausgelesen werden und die RFID Nummer soll als Dateiname verwendet werden.

Code: Alles auswählen

 foto.value = "/home/pi/Documents/" + row["RFid"] + ".jpg" 
Zum testen habe ich mir im Anschluss eine Ausgabe in der app gebaut:

Code: Alles auswählen

 app = App(title="Test", width=640, height=440, layout="grid")
foto = Text(app, text="", grid=[0,0], size="23", font="calibri", color="grey")
app.display() 
Die Ausgabe passt perfekt und gibt mir genau den kompletten Pfadnamen an, den ich haben will.
Nun habe ich versucht diesen generierten Pfad zu nutzen um mir ein Bild mit der ID ausgeben zu lassen:

Code: Alles auswählen

 app = App(title="Test", width=640, height=440, layout="grid")
picture = Picture(app, image=foto.value, grid=[0,2])
app.display() 
Da bekomme ich den Fehler:
Traceback (most recent call last):
File "/home/pi/Documents/RFIDGui.py", line 65, in <module>
picture = Picture(app, image=foto.value, grid=[0,2])
AttributeError: 'str' object has no attribute 'value'

@sparrow:
Das FOTO habe ich nur verwendet um zu zeigen wo ich die Variable einbauen wollte. Sorry für das Missverständnis.


Das mit dem pathlib klingt wirklich vernünftiger, ich verstehe es nur noch nicht 100%ig und werd mich da erstmal einlesen. Danke für den Tip.

Re: Pfad in image variabel

Verfasst: Mittwoch 15. Juli 2020, 14:41
von __blackjack__
@metme01454: Das kann nicht sein, dass Du *da* einen/den Fehler bekommst, denn die Zuweisung vorher funktioniert schon nicht:

Code: Alles auswählen

In [140]: foto = ""                                                             

In [141]: foto.value = "test"                                                   
---------------------------------------------------------------------------
AttributeError                            Traceback (most recent call last)
<ipython-input-141-5c93a321026c> in <module>
----> 1 foto.value = "test"

AttributeError: 'str' object has no attribute 'value'
Zeichenketten haben halt kein `value`-Attribut. Wie kommst Du darauf die hätten das?

Re: Pfad in image variabel

Verfasst: Mittwoch 15. Juli 2020, 15:45
von Sirius3
@metme01454: Du verwendest die Variable `foto` an verschiedenen Stellen mit unterschiedlichen Typen. Das führt, wie man ja sieht, zu Verwirrung. Wir kennen Deinen Code nicht und aus den Fragmenten kann man wirklich nicht ableiten, was Du statt dessen richtig machen mußt. An der Stelle, an der Du foto.value zuweist, wirst Du aus auch auf diese Art wieder lesen können.

Re: Pfad in image variabel

Verfasst: Mittwoch 15. Juli 2020, 20:59
von metme01454
Ok tut mir Leid, wie gesagt ich bin neu... ich habe nun mal den kompletten Code auf das wichtigste reduziert. Dazu gehört natürlich noch eine Database.csv im folgenden Format:
No,RFid,User,1,2
1,0011863141,Lise Lotte,Ja,Ja
2,0011437683,Hans Wurst,Nein,Nein
3,0011281747,Leo Löwe,Ja,Nein

Code: Alles auswählen

 
from gpiozero import LED, Buzzer
from guizero import App, Picture, Box, Text, TextBox, warn

import csv
led8 = LED(19)

def clearDisplay():
    print("Clear display")
    platzhalter = " "
    rfidStatus.value = ""
    rfidStatus2.value = ""
    rfidStatus3.value = ""
    rfidStatus4.value = ""
    rfidStatus5.value = ""
    rfidStatus6.value = ""
    rfidStatus7.value = ""
    rfidText.value = ""
    foto = ""
    led8.off()
    rfidStatus.repeat(1000, checkRFidTag)

def checkRFidTag():
    tagId = rfidText.value
    if tagId != "":
        RFidRegistered = False
        print(tagId)
        with open("Database.csv") as csvfile:
            reader = csv.DictReader(csvfile)
            for row in reader:
                if row["RFid"] == tagId:
                    RFidRegistered = True
                    rfidStatus.value = "Test" + row["User"]
                    foto.value = "/home/pi/Documents/" + row["RFid"] + ".jpg"
                    if row["1"] == "Ja":
                        rfidStatus2.value = "  Tu X: " + row["1"]
                        
                    if row["1"] == "Nein":    
                        rfidStatus6.value = "  Tu Y: " + row["1"]
                        rfidStatus7.value = "Bitte beachten!"
                        
                    if row["2"] == "Ja":
                        rfidStatus3.value = "  Test: " + row["2"]
                        
                    if row["2"] == "Nein":    
                        rfidStatus4.value = "  Test: " + row["2"]
                        rfidStatus5.value = "Ebenfalls beachten!"
                        
                    led8.on()
                    rfidStatus.after(8000, clearDisplay)

        if RFidRegistered == False:
            rfidStatus.value = "Mitglied nicht bekannt"
            rfidStatus.after(1000, clearDisplay)
          
        rfidStatus.cancel(checkRFidTag)


app = App(title="Verein", width=640, height=440, layout="grid")
# picture = Picture(app, image=foto, grid=[0,2])
foto = Text(app, text="", grid=[0,0], size="23", font="calibri", color="grey")
rfidText = TextBox(app, grid=[0,1], width=50)
rfidStatus = Text(app, text="", grid=[0,3,], align="left", size="28", font="calibri", color="#558B63")
rfidStatus2 = Text(app, text="", grid=[0,4], align="left", size="28", font="calibri", color="#558B63")
rfidStatus6 = Text(app, text="", grid=[0,4], align="left",size="28", font="calibri", color="red")
rfidStatus3 = Text(app, text="", grid=[0,5], align="left", size="28", font="calibri", color="#558B63")
rfidStatus4 = Text(app, text="", grid=[0,5], align="left", size="28", font="calibri", color="red")
rfidStatus7 = Text(app, text="", grid=[0,7], size="28", font="calibri", color="red")
rfidStatus5 = Text(app, text="", grid=[0,8], size="28", font="calibri", color="red")
rfidStatus.repeat(1000, checkRFidTag)
app.display()
Das mit dem .value war wirklich nur probieren muss ich zugeben. So wie der Code oben steht, bekomme ich nach einscannen des RFID Chips unter Anderem eine Ausgabe die ungefähr so aussieht:
"/home/pi/Documents/1234567891.jpg" --> Damit wollte ich erstmal testen ob die Variable foto so gefüllt wird wie ich es mir vorstelle. Das ist der Fall.
Ändere ich aber die Zeile:

Code: Alles auswählen

 foto.value = "/home/pi/Documents/" + row["RFid"] + ".jpg" 
in

Code: Alles auswählen

 foto = "/home/pi/Documents/" + row["RFid"] + ".jpg" 
Funktioniert die Ausgabe nicht mehr. Es war also an der Stelle wirklich nur trial and error, dass ich das .value angehängt habe.

Der nächste Schritt sollte sein die Zeile:

Code: Alles auswählen

 # picture = Picture(app, image=foto, grid=[0,2]) 
einzukommentieren und da sollte möglichst der Pfad (image=) durch die Variable gefüllt werden. Und der Punkt funktioniert nicht (sicher wegen Fehlern die ich vorher mache wie ich jetzt dank euch schonmal gelernt habe).

Danke vorab
Grüße

Re: Pfad in image variabel

Verfasst: Freitag 17. Juli 2020, 08:20
von metme01454
Keiner mehr eine Idee? :cry:

Re: Pfad in image variabel

Verfasst: Freitag 17. Juli 2020, 08:36
von Sirius3
Du versuchst ja, einmal am Anfang das Bild zu setzen.
Statt dessen mußt Du picture.image jedesmal dort neu setzen, wo Du foto.value bisher setzt.

Variablennamen werden komplett klein geschrieben. Nenne Deine Variablen sprechend, durchnummierierte Namen sind das nicht.
Alles was eine Funktion braucht, muß sie über ihre Argumente bekommen, bei clearDisplay fehlen die rfidStati und rfidText, bei checkRFidTag zusätzlich noch foto und picture.

Re: Pfad in image variabel

Verfasst: Freitag 17. Juli 2020, 12:17
von metme01454
@Sirius3
Danke für deine bisherige Geduld. Und danke für die Hinweise bzgl. Variablen und einer gescheiten Vorgehensweise. Ich habe versucht mal all deine Hinweise umzusetzen:

Code: Alles auswählen

from gpiozero import LED, Buzzer
from guizero import App, Picture, Box, Text, TextBox, warn


import csv

led8 = LED(19)

def clearDisplay():
    print("Clear display")
    user.value = ""
    permission.value = ""
    licence.value = ""
    licence_no.value = ""
    licence_no_warning.value = ""
    permission_no.value = ""
    permission_no_warning.value = ""
    rfidtext.value = ""
    foto = ""
    rfidtext.value = ""
    rfidregistered = ""
    led8.off()
    user.repeat(1000, check_rfid_tag)
    


def check_rfid_tag():
    foto = ""
    picture = ""
    tagId = rfidtext.value
    if tagId != "":
        rfidregistered = False
        print(tagId)
        with open("Database.csv") as csvfile:
            reader = csv.DictReader(csvfile)
            for row in reader:
                if row["RFid"] == tagId:
                    rfidregistered = True
                    user.value = "Test" + row["User"]
                    picture.image = "/home/pi/Documents/" + row["RFid"] + ".jpg"
                    if row["1"] == "Ja":
                        permission.value = "  Tu X: " + row["1"]
                        
                    if row["1"] == "Nein":    
                        permission_no.value = "  Tu Y: " + row["1"]
                        permission_no_warning.value = "Bitte beachten!"
                        
                    if row["2"] == "Ja":
                        licence.value = "  Test: " + row["2"]
                        
                    if row["2"] == "Nein":    
                        licence_no.value = "  Test: " + row["2"]
                        licence_no_warning.value = "Ebenfalls beachten!"
                        
                    led8.on()
                    user.after(8000, clearDisplay)

        if rfidregistered == False:
            user.value = "Mitglied nicht bekannt"
            user.after(1000, clearDisplay)
          
        user.cancel(check_rfid_tag)


app = App(title="Verein", width=640, height=440, layout="grid")
# picture = Picture(app, image=foto, grid=[0,2])
foto = Text(app, text="", grid=[0,0], size="23", font="calibri", color="grey")
rfidtext = TextBox(app, grid=[0,1], width=50)
user = Text(app, text="", grid=[0,3,], align="left", size="28", font="calibri", color="#558B63")
permission = Text(app, text="", grid=[0,4], align="left", size="28", font="calibri", color="#558B63")
permission_no = Text(app, text="", grid=[0,4], align="left",size="28", font="calibri", color="red")
licence = Text(app, text="", grid=[0,5], align="left", size="28", font="calibri", color="#558B63")
licence_no = Text(app, text="", grid=[0,5], align="left", size="28", font="calibri", color="red")
permission_no_warning = Text(app, text="", grid=[0,7], size="28", font="calibri", color="red")
licence_no_warning = Text(app, text="", grid=[0,8], size="28", font="calibri", color="red")
user.repeat(1000, check_rfid_tag)
app.display()
Nun bekomme ich folgenden Fehler:
picture.image = "/home/pi/Documents/" + row["RFid"] + ".jpg"
AttributeError: 'str' object has no attribute 'image'

Liegt das an der Art und Weise wie ich die Variable picture definiere?
Vielen Dank für eure bisherige Mühe und Geduld

Grüße

Re: Pfad in image variabel

Verfasst: Freitag 17. Juli 2020, 12:39
von __blackjack__
(Achtung der Beitrag bezieht sich noch auf den vorletzten Quelltextstand!)

@metme01454: Es werden Sachen importiert die nirgends verwendet werden.

Der Hinweis von Sirius3 mit den Argumenten wird schnell deutlich wenn man den Code und die Variablen auf Modulebene in einer Funktion verschwinden lässt. Das hat auf Modulebene nämlich nichts zu suchen.

Bei Textdateien sollte man beim öffnen immer die Kodierung explizit angeben und bei CSV-Dateien die mit dem `csv`-Modul verarbeitet werden sollen, muss man ``newline=""`` als Argument übergeben.

Bei sich gegenseitig ausschliessenden ``if``-Bedingungen verwendet man ``elif`` denn es macht ja keinen Sinn Bedingungen zu prüfen von denen man schon sicher weiss, das sie nicht zutreffen können.

In den Spalten in der CSV-Datei wo "Ja"/"Nein" steht, kann/darf da auch etwas anderes stehen? Falls nicht, sollte man auch diesen Fall im Programm berücksichtigen und beispielsweise eine Warnung ausgeben, protokollieren, oder gar in einem Fenster ausgeben.

Ich vermute mal die RFID in der CSV-Datei sollte eindeutig sein, das heisst wenn man die in der Datei gefunden hat, kann man die Schleife abbrechen, denn die wird dann ja in den weiteren Zeilen nicht noch mal gefunden werden. Dann kann man sich auch das Flag sparen ob der Wert gefunden wurde und mit ``break`` und ``else`` arbeiten.

In `clear_display()` wird `platzhalter` definiert aber nirgends verwendet.

Zwischenstand:

Code: Alles auswählen

#!/usr/bin/env python3
import csv
from pathlib import Path

from gpiozero import LED
from guizero import App, Picture, Text, TextBox

DOCUMENTS_PATH = Path("/home/pi/Documents")


def clear_display(
    led_needing_a_better_name,
    rfid_text,
    foto,
    rfid_status,
    rfid_status2,
    rfid_status3,
    rfid_status4,
    rfid_status5,
    rfid_status6,
    rfid_status7,
):
    print("Clear display")
    for widget in [
        rfid_status,
        rfid_status2,
        rfid_status3,
        rfid_status4,
        rfid_status5,
        rfid_status6,
        rfid_status7,
        rfid_text,
        foto,
    ]:
        widget.value = ""
    led_needing_a_better_name.off()
    rfid_status.repeat(
        1000,
        check_rfid_tag,
        [
            led_needing_a_better_name,
            rfid_text,
            foto,
            rfid_status,
            rfid_status2,
            rfid_status3,
            rfid_status4,
            rfid_status5,
            rfid_status6,
            rfid_status7,
        ],
    )


def check_rfid_tag(
    led_needing_a_better_name,
    rfid_text,
    foto,
    rfid_status,
    rfid_status2,
    rfid_status3,
    rfid_status4,
    rfid_status5,
    rfid_status6,
    rfid_status7,
):
    tag_id = rfid_text.value
    if tag_id:
        print(tag_id)
        with open("Database.csv", encoding="utf-8", newline="") as csv_file:
            for row in csv.DictReader(csv_file):
                if row["RFid"] == tag_id:
                    rfid_status.value = "Test " + row["User"]
                    foto.value = DOCUMENTS_PATH / row["RFid"] + ".jpg"
                    if row["1"] == "Ja":
                        rfid_status2.value = "  Tu X: " + row["1"]
                    elif row["1"] == "Nein":
                        rfid_status6.value = "  Tu Y: " + row["1"]
                        rfid_status7.value = "Bitte beachten!"

                    if row["2"] == "Ja":
                        rfid_status3.value = "  Test: " + row["2"]
                    elif row["2"] == "Nein":
                        rfid_status4.value = "  Test: " + row["2"]
                        rfid_status5.value = "Ebenfalls beachten!"

                    led_needing_a_better_name.on()
                    clear_display_delay = 8000
                    break
            else:
                clear_display_delay = 1000
                rfid_status.value = "Mitglied nicht bekannt"

            rfid_status.after(
                clear_display_delay,
                clear_display,
                [
                    led_needing_a_better_name,
                    rfid_text,
                    foto,
                    rfid_status,
                    rfid_status2,
                    rfid_status3,
                    rfid_status4,
                    rfid_status5,
                    rfid_status6,
                    rfid_status7,
                ],
            )

        rfid_status.cancel(check_rfid_tag)


def main():
    led_needing_a_better_name = LED(19)

    app = App(title="Verein", width=640, height=440, layout="grid")
    # picture = Picture(app, image=foto, grid=(0, 2))
    foto = Text(app, grid=(0, 0), size=23, font="calibri", color="grey")
    rfid_text = TextBox(app, grid=(0, 1), width=50)

    rfid_status = Text(
        app,
        grid=(0, 3),
        align="left",
        size=28,
        font="calibri",
        color="#558B63",
    )
    rfid_status2 = Text(
        app,
        grid=(0, 4),
        align="left",
        size=28,
        font="calibri",
        color="#558B63",
    )
    rfid_status6 = Text(
        app, grid=(0, 4), align="left", size=28, font="calibri", color="red",
    )
    rfid_status3 = Text(
        app,
        grid=(0, 5),
        align="left",
        size=28,
        font="calibri",
        color="#558B63",
    )
    rfid_status4 = Text(
        app, grid=(0, 5), align="left", size=28, font="calibri", color="red",
    )
    rfid_status7 = Text(app, grid=(0, 7), size=28, font="calibri", color="red")
    rfid_status5 = Text(app, grid=(0, 8), size=28, font="calibri", color="red")

    rfid_status.repeat(
        1000,
        check_rfid_tag,
        [
            led_needing_a_better_name,
            rfid_text,
            foto,
            rfid_status,
            rfid_status2,
            rfid_status3,
            rfid_status4,
            rfid_status5,
            rfid_status6,
            rfid_status7,
        ],
    )
    app.display()


if __name__ == "__main__":
    main()
Es muss hier aber deutlich zu viel an Argumenten durch die gegend gereicht werden. Für jede nicht-triviale GUI braucht man objektorientierte Programmierung (OOP).

Re: Pfad in image variabel

Verfasst: Freitag 17. Juli 2020, 13:23
von Sirius3
Warum, weißt Du picture oder foto einen leeren String zu?

Re: Pfad in image variabel

Verfasst: Dienstag 21. Juli 2020, 08:25
von metme01454
@Sirius3: Ich dachte so werden Variablen erstmal leer deklariert. Mein Fehler.

@__blackjack__:
Wahnsinnigen Dank für die ganzen Hinweise.

"Der Hinweis von Sirius3 mit den Argumenten wird schnell deutlich wenn man den Code und die Variablen auf Modulebene in einer Funktion verschwinden lässt. Das hat auf Modulebene nämlich nichts zu suchen." --> Danke, hier hat mir wohl noch grundlegendes Wissen über die Struktur generell gefehlt.

"Bei Textdateien sollte man beim öffnen immer die Kodierung explizit angeben und bei CSV-Dateien die mit dem `csv`-Modul verarbeitet werden sollen, muss man ``newline=""`` als Argument übergeben." --> Da werde ich mich nochmal einlesen um es zu verstehen, weil es ja auch ohne funktioniert hat. Möchte es aber verstehen, danke für den Hinweis.

"Bei sich gegenseitig ausschliessenden ``if``-Bedingungen verwendet man ``elif`` denn es macht ja keinen Sinn Bedingungen zu prüfen von denen man schon sicher weiss, das sie nicht zutreffen können." --> Das klingt mehr als logisch. auch dafür vielen Dank.

"In den Spalten in der CSV-Datei wo "Ja"/"Nein" steht, kann/darf da auch etwas anderes stehen? Falls nicht, sollte man auch diesen Fall im Programm berücksichtigen und beispielsweise eine Warnung ausgeben, protokollieren, oder gar in einem Fenster ausgeben." --> Da darf nix anderes stehen, dass mit der Warnung ist eine gute Idee.

"Ich vermute mal die RFID in der CSV-Datei sollte eindeutig sein, das heisst wenn man die in der Datei gefunden hat, kann man die Schleife abbrechen, denn die wird dann ja in den weiteren Zeilen nicht noch mal gefunden werden. Dann kann man sich auch das Flag sparen ob der Wert gefunden wurde und mit ``break`` und ``else`` arbeiten." --> Da hast du vollkommen Recht, die RFID ist eindeutig. Nach dem gefunden werden, soll aber das Display gecleared werden und anschließend gleich eine neuer RFID Chip eingelesen werden können... usw

"In `clear_display()` wird `platzhalter` definiert aber nirgends verwendet." --> Das war noch ein Überbleibsel aus dem allerersten Versuch, hatte ich übersehen, danke.

Ich habe nun deinen Code mal genutzt und angepasst (Variablennamen eindeutig wie von @Sirius3 empfohlen) und ich musste die grid Referenzen mit eckigen Klammern angeben, sonst gab es Fehler.
Also grid=[0,1] statt grid=(0,1)

Das mit dem image Path funktioniert aber trotzdem nicht...

Code: Alles auswählen

#!/usr/bin/env python3
import csv
from pathlib import Path

from gpiozero import LED
from guizero import App, Picture, Text, TextBox

DOCUMENTS_PATH = Path("/home/pi/Documents")


def clear_display(
    led_needing_a_better_name,
    rfid_text,
    foto,
    user,
    permission,
    licence,
    no_licence,
    no_licence_warning,
    no_permission,
    no_permission_warning,
):
    print("Clear display")
    for widget in [
        user,
        permission,
        licence,
        no_licence,
        no_licence_warning,
        no_permission,
        no_permission_warning,
        rfid_text,
        foto,
    ]:
        widget.value = ""
    led_needing_a_better_name.off()
    user.repeat(
        1000,
        check_rfid_tag,
        [
            led_needing_a_better_name,
            rfid_text,
            foto,
            user,
            permission,
            licence,
            no_licence,
            no_licence_warning,
            no_permission,
            no_permission_warning,
        ],
    )


def check_rfid_tag(
    led_needing_a_better_name,
    rfid_text,
    foto,
    user,
    permission,
    licence,
    no_licence,
    no_licence_warning,
    no_permission,
    no_permission_warning,
):
    tag_id = rfid_text.value
    if tag_id:
        print(tag_id)
        with open("Database.csv", encoding="utf-8", newline="") as csv_file:
            for row in csv.DictReader(csv_file):
                if row["RFid"] == tag_id:
                    user.value = "Test " + row["User"]
                    foto.value = DOCUMENTS_PATH / row["RFid"] + ".jpg"
                    if row["1"] == "Ja":
                        permission.value = "  Tu X: " + row["1"]
                    elif row["1"] == "Nein":
                        no_permission.value = "  Tu Y: " + row["1"]
                        no_permission_warning.value = "Bitte beachten!"

                    if row["2"] == "Ja":
                        licence.value = "  Test: " + row["2"]
                    elif row["2"] == "Nein":
                        no_licence.value = "  Test: " + row["2"]
                        no_licence_warning.value = "Ebenfalls beachten!"

                    led_needing_a_better_name.on()
                    clear_display_delay = 8000
                    break
            else:
                clear_display_delay = 1000
                user.value = "Mitglied nicht bekannt"

            user.after(
                clear_display_delay,
                clear_display,
                [
                    led_needing_a_better_name,
                    rfid_text,
                    foto,
                    user,
                    permission,
                    licence,
                    no_licence,
                    no_licence_warning,
                    no_permission,
                    no_permission_warning,
                ],
            )

        user.cancel(check_rfid_tag)


def main():
    led_needing_a_better_name = LED(19)

    app = App(title="Verein", width=640, height=440, layout="grid")
    # picture = Picture(app, image=foto, grid=(0, 2))
    foto = Text(app, grid=[0,0], size=23, font="calibri", color="grey")
    rfid_text = TextBox(app, grid=[0,1], width=50)

    user = Text(
        app,
        grid=[0,3],
        align="left",
        size=28,
        font="calibri",
        color="#558B63",
    )
    permission = Text(
        app,
        grid=[0,4],
        align="left",
        size=28,
        font="calibri",
        color="#558B63",
    )
    no_permission = Text(
        app, grid=[0,4], align="left", size=28, font="calibri", color="red",
    )
    licence = Text(
        app,
        grid=[0,5],
        align="left",
        size=28,
        font="calibri",
        color="#558B63",
    )
    no_licence = Text(
        app, grid=[0,5], align="left", size=28, font="calibri", color="red",
    )
    no_permission_warning = Text(app, grid=[0,7], size=28, font="calibri", color="red")
    no_licence_warning = Text(app, grid=[0,8], size=28, font="calibri", color="red")

    user.repeat(
        1000,
        check_rfid_tag,
        [
            led_needing_a_better_name,
            rfid_text,
            foto,
            user,
            permission,
            licence,
            no_licence,
            no_licence_warning,
            no_permission,
            no_permission_warning,
        ],
    )
    app.display()


if __name__ == "__main__":
    main()

Der Fehler lautet:
foto.value = DOCUMENTS_PATH / row["RFid"] + ".jpg"
TypeError: unsupported operand type(s) for +: 'PosixPath' and 'str'

Das mit dem Setzen des DOCUMENTS_PATH find ich klasse. Danke auch für diesen Tipp...

Viele Grüße

Re: Pfad in image variabel

Verfasst: Dienstag 21. Juli 2020, 09:02
von Sirius3
Du mußt richtig Klammern (Punkt-vor-Strich):

Code: Alles auswählen

foto.value = DOCUMENTS_PATH / (row["RFid"] + ".jpg")
oder besser gleich Format-Strings:

Code: Alles auswählen

foto.value = DOCUMENTS_PATH / f'{row["RFid"]}.jpg'
An der großen Anzahl an Argumenten (und immer gleichen) für die Funktionen siehst Du schön, dass es besser wäre, alle Widgets in ein Objekt zu packen, das bedeutet, dass Du Dir eine Klasse definieren mußt, die das Fenster mit all seinen Elementen repräsentiert.

Code: Alles auswählen

#!/usr/bin/env python3
import csv
from pathlib import Path
from gpiozero import LED
from guizero import App, Picture, Text, TextBox

DOCUMENTS_PATH = Path("/home/pi/Documents")


class RfidApp(object):
    def __init__(self):
        self.led_needing_a_better_name = LED(19)

        self.app = App(title="Verein", width=640, height=440, layout="grid")
        # picture = Picture(app, image=foto, grid=(0, 2))
        self.foto = Text(app, grid=[0,0], size=23, font="calibri", color="grey")
        self.rfid_text = TextBox(app, grid=[0,1], width=50)

        self.user = Text(
            self.app,
            grid=[0,3],
            align="left",
            size=28,
            font="calibri",
            color="#558B63",
        )
        self.permission = Text(
            self.app,
            grid=[0,4],
            align="left",
            size=28,
            font="calibri",
            color="#558B63",
        )
        self.no_permission = Text(
            self.app, grid=[0,4], align="left", size=28, font="calibri", color="red",
        )
        self.licence = Text(
            self.app,
            grid=[0,5],
            align="left",
            size=28,
            font="calibri",
            color="#558B63",
        )
        self.no_licence = Text(
            self.app, grid=[0,5], align="left", size=28, font="calibri", color="red",
        )
        self.no_permission_warning = Text(self.app, grid=[0,7], size=28, font="calibri", color="red")
        self.no_licence_warning = Text(self.app, grid=[0,8], size=28, font="calibri", color="red")
        self.app.repeat(1000, self.check_rfid_tag)

    def clear_display(self):
        for widget in [
            self.user,
            self.permission,
            self.licence,
            self.no_licence,
            self.no_licence_warning,
            self.no_permission,
            self.no_permission_warning,
            self.rfid_text,
            self.foto,
        ]:
            widget.value = ""
        self.led_needing_a_better_name.off()
        self.app.repeat(1000, self.check_rfid_tag)

    def check_rfid_tag(self):
        tag_id = self.rfid_text.value
        if tag_id:
            print(tag_id)
            with open("Database.csv", encoding="utf-8", newline="") as csv_file:
                for row in csv.DictReader(csv_file):
                    if row["RFid"] == tag_id:
                        self.user.value = f"Test {row['User']}"
                        self.foto.value = DOCUMENTS_PATH / f"{row['RFid']}.jpg"
                        if row["1"] == "Ja":
                            self.permission.value = f"Tu X: {row['1']}"
                        elif row["1"] == "Nein":
                            self.no_permission.value = f"Tu Y: {row['1']}"
                            self.no_permission_warning.value = "Bitte beachten!"

                        if row["2"] == "Ja":
                            self.licence.value = f"Test: {row['2']}"
                        elif row["2"] == "Nein":
                            self.no_licence.value = f"Test: {row['2']}"
                            self.no_licence_warning.value = "Ebenfalls beachten!"

                        self.led_needing_a_better_name.on()
                        clear_display_delay = 8000
                        break
                else:
                    clear_display_delay = 1000
                    self.user.value = "Mitglied nicht bekannt"

                self.app.after(clear_display_delay, self.clear_display)
            self.app.cancel(self.check_rfid_tag)

    def display():
        self.app.display()

def main():
    rfid_app = RfidApp()
    rfid_app.display()

if __name__ == "__main__":
    main()

Re: Pfad in image variabel

Verfasst: Donnerstag 6. August 2020, 07:58
von metme01454
@Sirius3 vielen Dank für deine Mühe...
Sorry für die späte Antwort, da waren mal ein paar Tage Urlaub dazwischen. :-)


Ich habe nun versucht durch das richtige Klammern mein Skript anzupassen. Dann klappt auch die Textausgabe des Dateipfades wieder. Aber scheinbar verstehe ich einfach noch nicht wo überall Variablen deklariert werden müssen, denn ich bekomme den Fehler wenn ich versuche mir das Bild ausgeben zu lassen:
Traceback (most recent call last):
File "/home/pi/Documents/new.py", line 175, in <module>
main()
File "/home/pi/Documents/new.py", line 118, in main
picture = Picture(app, image=foto, grid=(0, 2))
NameError: name 'foto' is not defined
Das leuchtet mir nicht ein, weil die Textausgabe funktioniert. (Zeile 118 und 119)

Code: Alles auswählen

#!/usr/bin/env python3
import csv
from pathlib import Path

from gpiozero import LED
from guizero import App, Picture, Text, TextBox

DOCUMENTS_PATH = Path("/home/pi/Documents")


def clear_display(
    led_needing_a_better_name,
    rfid_text,
    foto,
    user,
    permission,
    licence,
    no_licence,
    no_licence_warning,
    no_permission,
    no_permission_warning,
):
    print("Clear display")
    for widget in [
        user,
        permission,
        licence,
        no_licence,
        no_licence_warning,
        no_permission,
        no_permission_warning,
        rfid_text,
        foto,
    ]:
        widget.value = ""
    led_needing_a_better_name.off()
    user.repeat(
        1000,
        check_rfid_tag,
        [
            led_needing_a_better_name,
            rfid_text,
            foto,
            user,
            permission,
            licence,
            no_licence,
            no_licence_warning,
            no_permission,
            no_permission_warning,
        ],
    )


def check_rfid_tag(
    led_needing_a_better_name,
    rfid_text,
    foto,
    user,
    permission,
    licence,
    no_licence,
    no_licence_warning,
    no_permission,
    no_permission_warning,
):
    tag_id = rfid_text.value
    if tag_id:
        print(tag_id)
        with open("Database.csv", encoding="utf-8", newline="") as csv_file:
            for row in csv.DictReader(csv_file):
                if row["RFid"] == tag_id:
                    user.value = "Test " + row["User"]
                    foto.value = DOCUMENTS_PATH / (row["RFid"] + ".jpg")
                    if row["1"] == "Ja":
                        permission.value = "  Tu X: " + row["1"]
                    elif row["1"] == "Nein":
                        no_permission.value = "  Tu Y: " + row["1"]
                        no_permission_warning.value = "Bitte beachten!"

                    if row["2"] == "Ja":
                        licence.value = "  Test: " + row["2"]
                    elif row["2"] == "Nein":
                        no_licence.value = "  Test: " + row["2"]
                        no_licence_warning.value = "Ebenfalls beachten!"

                    led_needing_a_better_name.on()
                    clear_display_delay = 8000
                    break
            else:
                clear_display_delay = 1000
                user.value = "Mitglied nicht bekannt"

            user.after(
                clear_display_delay,
                clear_display,
                [
                    led_needing_a_better_name,
                    rfid_text,
                    foto,
                    user,
                    permission,
                    licence,
                    no_licence,
                    no_licence_warning,
                    no_permission,
                    no_permission_warning,
                ],
            )

        user.cancel(check_rfid_tag)


def main():
    led_needing_a_better_name = LED(19)

    app = App(title="Verein", width=640, height=440, layout="grid")
    picture = Picture(app, image=foto, grid=(0, 2))
    #foto = Text(app, grid=[0,0], size=23, font="calibri", color="grey")
    rfid_text = TextBox(app, grid=[0,1], width=50)

    user = Text(
        app,
        grid=[0,3],
        align="left",
        size=28,
        font="calibri",
        color="#558B63",
    )
    permission = Text(
        app,
        grid=[0,4],
        align="left",
        size=28,
        font="calibri",
        color="#558B63",
    )
    no_permission = Text(
        app, grid=[0,4], align="left", size=28, font="calibri", color="red",
    )
    licence = Text(
        app,
        grid=[0,5],
        align="left",
        size=28,
        font="calibri",
        color="#558B63",
    )
    no_licence = Text(
        app, grid=[0,5], align="left", size=28, font="calibri", color="red",
    )
    no_permission_warning = Text(app, grid=[0,7], size=28, font="calibri", color="red")
    no_licence_warning = Text(app, grid=[0,8], size=28, font="calibri", color="red")

    user.repeat(
        1000,
        check_rfid_tag,
        [
            led_needing_a_better_name,
            rfid_text,
            foto,
            user,
            permission,
            licence,
            no_licence,
            no_licence_warning,
            no_permission,
            no_permission_warning,
        ],
    )
    app.display()


if __name__ == "__main__":
    main()


Wenn ich deinen Code 1:1 nutze (der wirklich viel besser und übersichtlicher aussieht, danke dafür!), bekomme ich folgenden Fehler:
Traceback (most recent call last):
File "/home/pi/Documents/new2.py", line 108, in <module>
main()
File "/home/pi/Documents/new2.py", line 104, in main
rfid_app = RfidApp()
File "/home/pi/Documents/new2.py", line 16, in __init__
self.foto = Text(app, grid=[0,0], size=23, font="calibri", color="grey")
NameError: name 'app' is not defined

Ich danke euch vorab

Re: Pfad in image variabel

Verfasst: Donnerstag 6. August 2020, 08:40
von __blackjack__
@metme01454: Wieso leuchtet Dir der `NameError` für `foto` nicht ein? Wo wird denn Deiner Meinung nach der Wert definiert? Ich sehe da *gar keine* Definition. Weder vor der Verwendung des Namens noch danach. Direkt nach der Zeile wo es den `NameError` gibt steht eine auskommentierte Definition wo `foto` als `Text`-Objekt definiert wird. *Das* könnte man natürlich nicht als `image` eines `Picture`-Objekts verwenden, denn ein `Text`-Objekt ist kein passendes Objekt um ein Bild zu repräsentieren.

Re: Pfad in image variabel

Verfasst: Donnerstag 6. August 2020, 09:24
von Sirius3
Du mußt wirklich lernen, was Namensräume sind, und wo welche Variablen sichtbar sind.
Der Fehler in meinem Code ist recht simple, da app nur als self.app existiert.