2 oder mehr Aufgaben gleichzeitig

Wenn du dir nicht sicher bist, in welchem der anderen Foren du die Frage stellen sollst, dann bist du hier im Forum für allgemeine Fragen sicher richtig.
Streifenhase1
User
Beiträge: 75
Registriert: Dienstag 22. Mai 2018, 07:15

Donnerstag 9. Mai 2019, 11:47

Ich Werte permanent, aller 300ms Werte aus einer SPS aus und zähle damit einen Wert.

wenn nun ein bestimmtes Signal kommt wird über ein Netzwerk ein Bild geladen und angezeigt.

dieses dauert relativ lange 5 sec.

und in dieser Zeit steht nun der Wert (wird mit tkinter angezeigt) solange bis das Bild geladen wurde und macht beim zählen dann einen großen Sprung.

Ist es möglich das auswerten der SPS und aktualisieren des Tkinter ohne diese Unterbrechung umzusetzen und wenn wie.
Benutzeravatar
__blackjack__
User
Beiträge: 3864
Registriert: Samstag 2. Juni 2018, 10:21
Wohnort: 127.0.0.1
Kontaktdaten:

Donnerstag 9. Mai 2019, 12:11

@Streifenhase1: Das `threading`-Modul – und all die Probleme die das dann mit sich bringt. Also das man die GUI nur aus dem Thread heraus ändern darf in dem die `mainloop()` läuft. Das löst man dann üblicherweise mit Queues zwischen den Threads und `after()` in `tkinter` wo man dann regelmässig prüft ob das Bild in der Queue steckt und angezeigt werden kann. Und der Thread der das Bild lädt, steckt das dann in die Queue wenn er fertig ist.
“There's also a certain pleasure in actually getting things to work in Java, somewhat like the pleasure, I imagine, of building ships in bottles.”
— David Cook in c.l.p
Streifenhase1
User
Beiträge: 75
Registriert: Dienstag 22. Mai 2018, 07:15

Donnerstag 9. Mai 2019, 13:03

ok danke also mit 'threading' versuche ich es gerade...

kann ich 'threading' mit after kombinieren oder macht man das mit while?

weil wenn ich die Funktion mit after wieder Aufrufe ist es dann kein eigener Thread mehr

wenn ich
__deets__
User
Beiträge: 6049
Registriert: Mittwoch 14. Oktober 2015, 14:29

Donnerstag 9. Mai 2019, 13:09

Im Thread benutzt du while, und fragst deine SPS ab. Den Zaehlerstand kommunizierst zu zB ueber eine queue, und mit after fragst du die regelmaessig ab. Wenn es zwischendurch mal 5 Sekunden dauert, ein Bild zu laden, macht das nichts, denn die queue hat die anderen Messergebnisse gespeichert. Und ganz verrueckt wird es natuerlich, wenn du die Abfrage des Bildes *auch* in einem (anderen!) Thread machst, und ebenfalls kommunizierst, dass das Bild fertig ist mit einer Queue. Auf die Art und Weise bleibt deine GUI immer ansprechbar.
Streifenhase1
User
Beiträge: 75
Registriert: Dienstag 22. Mai 2018, 07:15

Donnerstag 9. Mai 2019, 15:49

Ok. Danke für die Tips also mit dem Laden des Bildes über Thread funktioniert schon mal so einigermaßen.

Jetzt aber noch mal was anderes...

Ich nutze Python auf Windows(7) und habe im Netzwerk einen Rechner mit XP (geht leider nicht anders) den Freigegebenen Ordner vom XP Rechner habe ich auf dem Windows 7 als ein Laufwerk zugewiesen. Der zugriff Funktioniert recht schnell bzw. das öffnen der Bilder.

wenn ich aber das Bild bei Python lade durch Angabe des Pfades des Netzwerklaufwerkes dauert es eben so lange. (Das Verzeichnis wird nach der neusten Datei durchsucht und diese dann geladen). Wenn ich das selbe lokal mache geht es sehr schnell.

gibt es da eine andere Möglichkeit für den Zugriff auf das Netzwerklaufwerk über python und der IP?
Sirius3
User
Beiträge: 10216
Registriert: Sonntag 21. Oktober 2012, 17:20

Donnerstag 9. Mai 2019, 17:53

@Streifenhase1: Es kann sein, dass da ungünstig in kleinen Häppchen gelesen wird. Kannst Du mal den Code zeigen?
Du weißt, dass XP mit freigegebenem Ordner offen ist wie ein Scheunentor? Das Netzwerk ist hoffentlich schön abgeschottet.
Streifenhase1
User
Beiträge: 75
Registriert: Dienstag 22. Mai 2018, 07:15

Donnerstag 9. Mai 2019, 19:23

@Sirius3 also der XP hängt nicht im Internet und sind nur die 2 Rechner die miteinander verbunden sind.

der Code für die Bilder sieht etwa so aus... wobei "Z:\" das Netzwerk ist. Wie gesagt wenn ich es mit einem auf dem Rechner befindlichen Ordner mache gibt es keine Probleme und ist in Bruchteilen einer Sekunde geladen.

Code: Alles auswählen


def Defects_update(self):


    list_of_files = glob.glob("Z:\Bilder")
    if len(list_of_files) > 0:

        latest_file = max(list_of_files, key=os.path.getctime)
        found = latest_file
        print (found)
        time_string = datetime.datetime.fromtimestamp(os.stat(found).st_mtime)
        datum = time_string.strftime("%d.%m.%Y    %H:%M:%S")
        self.Pictur_date_threshold.set(datum)

        baseheight = 480
        im = Image.open(found)
        width, height = 480, 480
        wpercent = baseheight/height
        newwidth = width * wpercent
        newwidth = int(newwidth)
        newsize = (482, 482)
        imnew = im.resize(newsize, PIL.Image.ANTIALIAS)

        try:

            self.canvas.image = ImageTk.PhotoImage(imnew)
            self.canvas.itemconfig(self.Defects_image, image = self.canvas.image)


        except IOError:
            print ("close")
            pass

    else:

        found = "Data\NoPicture.bmp"
        self.Picture1_threshold.set("")

       baseheight = 480
       im = Image.open(found)
       width, height = 480, 480
                
       wpercent = baseheight/height
       newwidth = width * wpercent
       newwidth = int(newwidth)
       newsize = (482, 482)
       imnew = im.resize(newsize, PIL.Image.ANTIALIAS)
       self.canvas.image = ImageTk.PhotoImage(imnew)
       self.canvas.itemconfig(self.Defects_image, image = self.canvas.image)
Sirius3
User
Beiträge: 10216
Registriert: Sonntag 21. Oktober 2012, 17:20

Donnerstag 9. Mai 2019, 19:47

Deine Einrückungen sind kaputt. Ich rate mal, wie das gemeint ist. Da hast Du 10 Zeilen Code im if- und else-Block, die identisch sind.

Wie viele Dateien hast Du denn? Von jedem die Zeit abzufragen dauert halt. Oder hast Du mal geschaut, wo die Zeit verschwendet wird?

Warum nennst Du `latest_file` in `found` um? `time_string` ist gar kein String.
`newwidth` wird gar nicht verwendet, damit auch nicht `width`, `wpercent`, `baseheight`, und `height`.

Bleibt das:

Code: Alles auswählen

def get_latest_file(path):
    return max(glob.glob(path), key=os.path.getctime)

def defects_update(self):
    try:
        filename = get_latest_file("Z:\Bilder")
        ctime = os.path.getctime(filename)
        datum = "{:%d.%m.%Y    %H:%M:%S}".format(
            datetime.datetime.fromtimestamp(ctime))
    except ValueError:
        found = r"Data\NoPicture.bmp"
        datum = ""

    self.Picture1_threshold.set(datum)
    newsize = (482, 482)
    imnew = im.resize(newsize, PIL.Image.ANTIALIAS)
    self.canvas.image = ImageTk.PhotoImage(imnew)
    self.canvas.itemconfig(self.defects_image, image=self.canvas.image)
Streifenhase1
User
Beiträge: 75
Registriert: Dienstag 22. Mai 2018, 07:15

Mittwoch 15. Mai 2019, 12:02

Also ich habe jetzt 2 Threads laufen einer liest die SPS aus und der andere die Bilder. Jetzt brauche ich aber ein Signal der SPS, was ich in eine Queue schreibe.
der wert in der Queue kann "0" sein oder größer. Wenn der wert größer "0" ist soll das bild geladen werden.

Funktioniert aber leider nur 1x wenn der wert der Queue von "0" auf >0 springt und wieder auf "0" wir in einer Endlosschleife das Bild geladen.

Kann mir jemand helfen!?


anders würde es auch funktionieren wenn ich das letzte geladene Bild (Dateiname) mit dem Aktuellem Bild nach dem durchsuchen des Verzeichnisses (neuste Datei) vergleiche und nur lade wenn der Name anders ist.

Code: Alles auswählen

 def picture_update(self):
  
        while self.schnitt1.get() > 0 :

            try:                
                filename = max(glob.glob("Z:\Bilder), key=os.path.getctime)
                ctime = os.path.getctime(filename)
                datum = "{:%d.%m.%Y    %H:%M:%S}".format(datetime.datetime.fromtimestamp(ctime))

            except ValueError:
                filename = r"Data\NoPicture.bmp
                datum = ""
                
            self.Picture1_threshold.set(datum)
            newsize = (482, 482)
            imnew = filename.resize(newsize, PIL.Image.ANTIALIAS)
            self.canvas.image = ImageTk.PhotoImage(imnew)
            self.canvas.itemconfig(self.defects_image, image=self.canvas.image)
Benutzeravatar
__blackjack__
User
Beiträge: 3864
Registriert: Samstag 2. Juni 2018, 10:21
Wohnort: 127.0.0.1
Kontaktdaten:

Mittwoch 15. Mai 2019, 12:08

@Streifenhase1: Also mir wird aus der Beschreibung weder klar was Du willst, noch was im Code passiert.
“There's also a certain pleasure in actually getting things to work in Java, somewhat like the pleasure, I imagine, of building ships in bottles.”
— David Cook in c.l.p
Streifenhase1
User
Beiträge: 75
Registriert: Dienstag 22. Mai 2018, 07:15

Mittwoch 15. Mai 2019, 13:30

Also es soll in einer while schleife die Queue

Code: Alles auswählen

self.schnitt1.get()  :

gelesen werden. Wenn der Wert der Queue "0" ist dann soll nichts passieren auser weiter die Queue lesen. Wenn deren Inhalt größer als 0 ist soll die Funktion ausgeführt werden.

Code: Alles auswählen

 try:                
     filename = max(glob.glob("Z:\Bilder), key=os.path.getctime)
     ctime = os.path.getctime(filename)
     datum = "{:%d.%m.%Y    %H:%M:%S}".format(datetime.datetime.fromtimestamp(ctime))

     except ValueError:
     filename = r"Data\NoPicture.bmp
     datum = ""
                
     self.Picture1_threshold.set(datum)
     newsize = (482, 482)
     imnew = filename.resize(newsize, PIL.Image.ANTIALIAS)
     self.canvas.image = ImageTk.PhotoImage(imnew)
     self.canvas.itemconfig(self.defects_image, image=self.canvas.image)
            



Wenn der Inhalt der Queue wieder "0" ist soll wieder nur die "Queue" abgefragt werden.


Hoffe jetzt ist es verständlicher
Benutzeravatar
sparrow
User
Beiträge: 1286
Registriert: Freitag 17. April 2009, 10:28

Mittwoch 15. Mai 2019, 13:32

Dann sollte aber der Wert aus der Queue nicht in die Bedingung für die while-Schleife sein. Wenn die Bedingung nicht mehr erfüllt ist, bricht die Schleife nämlich ab und wird gar nicht mehr ausgeführt.
Benutzeravatar
__blackjack__
User
Beiträge: 3864
Registriert: Samstag 2. Juni 2018, 10:21
Wohnort: 127.0.0.1
Kontaktdaten:

Mittwoch 15. Mai 2019, 15:15

@sparrow: Das ist ja auch gut so, und die Bedingung ist hoffentlich ziemlich schnell nicht mehr erfüllt, denn in der Schleife wird an der GUI etwas geändert, das heisst die muss in den Thread sein in dem die `mainloop()` läuft. Darum verwirrt mich das ja auch so was da steht. Das sieht auf die eine oder andere Art falsch aus.
“There's also a certain pleasure in actually getting things to work in Java, somewhat like the pleasure, I imagine, of building ships in bottles.”
— David Cook in c.l.p
Streifenhase1
User
Beiträge: 75
Registriert: Dienstag 22. Mai 2018, 07:15

Mittwoch 15. Mai 2019, 15:36

Hab es noch mal geändert aber ohne Erfolg.
Funktionier 1x und wenn "If schnitt > 0" erfolgt ist macht er keine abfrage mehr.

Code: Alles auswählen

def picture_update(self):
  
    while 1:
        self.schnitt1.get()
        schnitt = self.schnitt1
        
	if schnitt  > 0 :
            try:                
                filename = max(glob.glob("Z:\Bilder), key=os.path.getctime)
                ctime = os.path.getctime(filename)
                datum = "{:%d.%m.%Y    %H:%M:%S}".format(datetime.datetime.fromtimestamp(ctime))

            except ValueError:
                filename = r"Data\NoPicture.bmp
                datum = ""
                
    self.Picture1_threshold.set(datum)
    newsize = (482, 482)
    imnew = filename.resize(newsize, PIL.Image.ANTIALIAS)
    self.canvas.image = ImageTk.PhotoImage(imnew)
    self.canvas.itemconfig(self.defects_image, image=self.canvas.image)
            	            

habe noch ein andere Frage!

wenn diese Zeile im Programm ausgeführt wird

Code: Alles auswählen

 filename = max(glob.glob("Z:\Bilder), key=os.path.getctime)
 
kommt es gelegentlich zu Fehlern das der Pfad bzw. die Datei nicht gefunden wird und die Schleife bricht ab. Grund daführ ist das Schreiben und löschen von Dateien.

Wie könnte ich das beheben, z.B. wenn Datei nicht gefunden dann noch mal Prüfen
Sirius3
User
Beiträge: 10216
Registriert: Sonntag 21. Oktober 2012, 17:20

Mittwoch 15. Mai 2019, 15:48

@Streifenhase1: aus den Schnipseln, die Du hier zeigt, wird überhaupt nicht klar, was Du da versuchst. Du hast also irgendwie einen Trigger, wann das Bild aktualisiert werden soll. Wie ist denn das mit Deiner Dateiablage synchonisiert? Und was soll das mit > oder == 0?

Zur Frage: genau, einfach nochmal versuchen, wenn es einen Fehler gibt.
Antworten