Zugriff auf Variablen einer anderen Funktion

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.
Sirius3
User
Beiträge: 8116
Registriert: Sonntag 21. Oktober 2012, 17:20

Mittwoch 18. Juli 2018, 21:20

@Streifenhase1: aber was ist denn nun die Fehlermeldung, die Du bekommst? Und was sagt die darüber, was Du falsch machst?

PS: aussagekräftigere Funktions- und Variablennamen würden beim Verstehen und Beschreiben des Problems helfen.
Streifenhase1
User
Beiträge: 47
Registriert: Dienstag 22. Mai 2018, 07:15

Mittwoch 18. Juli 2018, 21:26

die Fehlermeldung ist
Traceback (most recent call last):
File "/data/user/0/ru.iiec.pydroid3/files/accomp_files/iiec_run/iiec_run.py", line 31, in <module> start(fakepyfile,mainpyfile) File "/data/user/0/ru.iiec.pydroid3/files/accomp_files/iiec_run/iiec_run.py", line 30, in start exec(open(mainpyfile).read(), __main__.__dict__) File "<string>", line 12, in <module> File "<string>", line 9, in b TypeError: a() takes 0 positional arguments but 1 was given [Program finished]
Streifenhase1
User
Beiträge: 47
Registriert: Dienstag 22. Mai 2018, 07:15

Mittwoch 18. Juli 2018, 21:33

hab es noch mal mit anderer Nennung, hoffe es ist jetzt übersichtlicher was ich möchte

Code: Alles auswählen

   
def a():
	
    wert=1
    print (wert)
    return wert
    

def b():
	
    wert=wert(a)
    print (wert)
    
b() 
Benutzeravatar
kbr
User
Beiträge: 895
Registriert: Mittwoch 15. Oktober 2008, 09:27

Mittwoch 18. Juli 2018, 21:52

Dein ursprüngliches Beispiel war an funktionierendem Code schon näher dran, als die vermeintlich übersichtlichere Variante. In der ersten Zeile von b() möchtest Du

Code: Alles auswählen

wert = a()
schreiben. Das ist aber trivial und es bleibt unklar, was du wirklich beabsichtigts.
Sirius3
User
Beiträge: 8116
Registriert: Sonntag 21. Oktober 2012, 17:20

Mittwoch 18. Juli 2018, 22:10

@Streifenhase1: mit den neuen Namen gibt es eine neue Fehlermeldung, die soviel sagt, dass »wert« nicht definiert ist, wenn Du versuchst es als Funktion aufzurufen, was ja auch keinen Sinn macht.
Streifenhase1
User
Beiträge: 47
Registriert: Dienstag 22. Mai 2018, 07:15

Mittwoch 18. Juli 2018, 22:21

ok bin etwas weiter.
Hier mal etwas genauer was ich möchte.

Code: Alles auswählen

 
def capture(self):
    print("Capture")
    camera.start_preview()
    img = Image.open('test.png')
    pad = Image.new('RGBA',(
    ((img.size[0] + 31) // 32) * 32,
    ((img.size[1] + 15) // 16) * 16,
    ))
    pad.paste(img, (fx, fy),)

    o = camera.add_overlay(pad.tostring(), size=img.size)

    o.alpha = 25
    o.layer = 4 
    return o
 


Das ist die Funktion die variable "o" aufruft.
Und möchte "o" mit einer anderen Funktion beenden.

Code: Alles auswählen

def stop(self):
    o=capture()
    print("Stop Capture")
    camera.stop_preview()
    camera.remove_overlay(o)
könnte das funktionieren?
Kann es vor Ort nicht probieren
__deets__
User
Beiträge: 3117
Registriert: Mittwoch 14. Oktober 2015, 14:29

Donnerstag 19. Juli 2018, 01:04

Nein. Du musst das o (ganz schlechter Name. Warum nicht overlay?) global abspeichern, und dich drauf beziehen im stop. So wie du das jetzt machst, startest du beim stoppen NOCHMAL die Wiedergabe (was krachen wird), und nichts ist gewonnen.
Benutzeravatar
__blackjack__
User
Beiträge: 809
Registriert: Samstag 2. Juni 2018, 10:21

Donnerstag 19. Juli 2018, 08:20

Unglückliche Wortwahl — natürlich *nicht* *global* sondern auf dem Objekt. Wo übrigens auch die `camera` hingehören würde.
Global warming is caused by the sun.
Sirius3
User
Beiträge: 8116
Registriert: Sonntag 21. Oktober 2012, 17:20

Donnerstag 19. Juli 2018, 08:29

@__deets__: `global` ist ein unglücklich gewählter Begriff. Das doofe `o` kommt so direkt aus der PiCamera-Dokumentation, wo der Code herkopiert ist.

@Streifenhase1: es sieht ja so aus, als ob Du Methoden einer Klasse hast, so dass Du `o` gar nicht zurückgeben mußt, sondern den Zustand als Attribut auf der Instanz dieser Klasse speichern kannst.

Code: Alles auswählen

    def capture(self):
        print("Capture")
        self.camera.start_preview()
        img = Image.open('test.png')
        pad = Image.new('RGBA',(
            ((img.size[0] + 31) // 32) * 32,
            ((img.size[1] + 15) // 16) * 16,
        ))
        pad.paste(img, (fx, fy))

        self.overlay = self.camera.add_overlay(pad.tostring(), size=img.size)
        self.overlay.alpha = 25
        self.overlay.layer = 4 

    def stop(self):
        print("Stop Capture")
        self.camera.stop_preview()
        self.camera.remove_overlay(self.overlay)
Streifenhase1
User
Beiträge: 47
Registriert: Dienstag 22. Mai 2018, 07:15

Donnerstag 19. Juli 2018, 09:31

@Sirius3 genau ich habe eine Klasse.
Ich werde es so probieren.
Langsam verstehe ich einiges mehr.

Ich möchte dann das Overlay auch in einer anderen klasse ansprechen, hoffe das geht dann auch.

werd es selber erst mal probieren.
Wenn ich es nicht hin bekomme melde ich mich wieder.

Danke
Streifenhase1
User
Beiträge: 47
Registriert: Dienstag 22. Mai 2018, 07:15

Donnerstag 19. Juli 2018, 18:48

So ich bin leider kläglich mit der der Übergabe des Overlay in eine andere class gescheitert
der rest von gestern funktioniert so weit

Hier mal ein Ausschnitt von der class die das Overlay Startet.


Code: Alles auswählen

class MainFrame(tk.Frame):
    
    
    def __init__(self, haupt_fenster):
        super().__init__(haupt_fenster)
        self.haupt_fenster = haupt_fenster
        self.haupt_fenster.protocol("WM_DELETE_WINDOW", self.close)
        self.camera=camera
        self.build()


    def capture(self):
        print("Capture")
        self.camera.start_preview()
        img = Image.open('gelb.png')
        pad = Image.new('RGBA',(
        ((img.size[0] + 31) // 32) * 32,
        ((img.size[1] + 15) // 16) * 16,
        ))
        pad.paste(img, (fx, fy),)
        self.overlay = self.camera.add_overlay(pad.tostring(), size=img.size)
        self.overlay.alpha = 25
        self.overlay.layer = 4
        return self.overlay
jetzt habe ich eine andere class in dem ein Fenster mit Buttons definiert werden.
Ein Button soll nun das Overlay verschieben

habe mir gedacht das es so gehen könnte

Code: Alles auswählen

class Settings(tk.Toplevel):
    def __init__(self, parent, noborder=True):
        super().__init__(parent)

        self.title("Settings")
        self.geometry("{}x{}".format(180, 550))
        self.geometry("+{}+{}".format(10, 175))
        self.configure(bg='steelblue1')
        self.wm_overrideredirect(noborder)
        self.camera=camera



    def flinks(self):
        self.camera.remove_overlay(self.overlay)
        global fx
        wert = 5
        fx = min(100, fx + wert)
        self.overlay.set(fx.get() + wert)
fx ist ein wert der in der Grundebene festgelegt ist fx = 0

Also ich möchte jetzt aus Overlay in die class Settings übergeben und dann de wert fx um wert = 5 erhöhen und dann das overlay updaten


jetzt habe ich noch das Problem das ich Captur in class MainFrame beim ausführen des Programmes starten möchte aber bringt den Fehler MainFrame ist nicht definiert

Code: Alles auswählen

MainFrame().capture()
Sirius3
User
Beiträge: 8116
Registriert: Sonntag 21. Oktober 2012, 17:20

Donnerstag 19. Juli 2018, 19:05

Ohne den ganzen Code zu kennen und die genauen Fehlermeldungen, ist das nur herumgerate, was Du denn falsch machst. Wenn Settings etwas mit camera anfangen soll, so mußt Du eine Methode in MainFrame definieren, die das macht und die Mainframe-Instanz beim Erzeugen von Settings übergeben. `global` solltest Du nicht benutzen, fx sollte Attribut von Settings, oder Mainframe, je nachdem, sein und ein int kennt kein `get`.
Streifenhase1
User
Beiträge: 47
Registriert: Dienstag 22. Mai 2018, 07:15

Donnerstag 19. Juli 2018, 19:33

ok fx habe ich in MainFrame genommen

Ja würde den Code zur Verfügung stellen aber weiß nicht ob das zu viel durcheinander wird

bisher habe ich mit dieser funktion

Code: Alles auswählen

def flinks(self):
    global fx
    wert = 5
    fx = min(100, fx + wert)
Das der fx Wert sich verändert hat und bei erneutem ausführen des Overlay dieses versetzt erschienen ist.

@Sirius3
Soll ich den kompletten Code mal Posten?
Streifenhase1
User
Beiträge: 47
Registriert: Dienstag 22. Mai 2018, 07:15

Freitag 20. Juli 2018, 14:55

OK...

Ich habe nun einen anderen weg eingeschlagen und eine Klasse für die Funktionen für die Kamera erstellt.

Code: Alles auswählen

class Kamera:

    

    def __init__(self):
                
        self.camera=camera
        self.fx = 0
        self.fy = 0
        
    
    def startpreview(self):
        print("Starte_ Preview")
        self.camera.start_preview()
        

    def stoppreview(self):
        print("Stop_Preview")
        self.camera.stop_preview()
         

    def overlay(self):
        print("Start_Overlay")
        self.camera=camera
        img = Image.open('test.png')
        pad = Image.new('RGBA',(
        ((img.size[0] + 31) // 32) * 32,
        ((img.size[1] + 15) // 16) * 16,
        ))
        pad.paste(img, (self.fx, self.fy),)
        self.overlay = self.camera.add_overlay(pad.tostring(), size=img.size)
        self.overlay.alpha = 25
        self.overlay.layer = 4
        
        
    def stopoverlay(self):
        print("Stop_Oberlay")
        self.camera.remove_overlay(self.overlay)


Nun rufe ich die Einzelnen Funktionen von eine anderen Klasse auf, was auch soweit Funktioniert

z.B. wird die Kamera und das Overlay gestartet.

wenn ich jetzt aber das Overlay beenden möchte kommt die Fehlermeldung

Exception in Tkinter callback
Traceback (most recent call last):
File "/usr/lib/python3.4/tkinter/__init__.py", line 1536, in __call__
return self.func(*args)
File "/media/pi/Transcend/Kamera/Camera mit cameramodul.py", line 383, in close
Kamera().stopoverlay()
File "/media/pi/Transcend/Kamera/Camera mit cameramodul.py", line 84, in stopoverlay
camera.remove_overlay(self.overlay)
File "/usr/lib/python3/dist-packages/picamera/camera.py", line 908, in remove_overlay
"The specified overlay is not owned by this instance of "
picamera.exc.PiCameraValueError: The specified overlay is not owned by this instance of PiCamera

Das bedeutet ja das nicht auf das selbe overlay zugegriffen wird.

Was mache ich falsch?
Sirius3
User
Beiträge: 8116
Registriert: Sonntag 21. Oktober 2012, 17:20

Freitag 20. Juli 2018, 15:08

Wo kommt denn `camera` in __init__ her? Und was soll das Überschreiben von self.camera in `overlay`? Und wie wird `Kamera` benutzt?
Antworten