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.
Streifenhase1
User
Beiträge: 90
Registriert: Dienstag 22. Mai 2018, 07:15

Das mit dem Überschreiben von self.camera ist natürlich falsch
Was meinst du wie wird Kamera benutzt
Hier noch mal etwas mehr Code.


Hoffe damit könnt ihr mir weiter helfen

Code: Alles auswählen

from tkinter import messagebox
import tkinter as tk
import picamera
import time
import numpy as np
from PIL import Image


APP_TITLE = "Kamera"
APP_XPOS = 10
APP_YPOS = 10
APP_WIDTH = 1280
APP_HEIGHT = 800
Hintergrundbild = "Hintergrund.gif"

camera = picamera.PiCamera(resolution=(1280,720))
cam_bri = 45
cam_con = 100
cam_shu = 20000
cam_iso = 100


camera.brightness = cam_bri
camera.contrast = cam_con
camera.shutter_speed = cam_shu
camera.iso = cam_iso

camera.vflip=False
camera.hflip=False
camera.saturation = -100
#camera.framerate = 60
camera.awb_mode='auto'
camera.exposure_mode='auto'
camera.video_stabilization=True
camera.preview_fullscreen=False
camera.preview_window=(200, 50, 1050, 800)


    
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")
        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")
        camera.remove_overlay(self.overlay)




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.build()
        
    def build(self):
        button_frame = tk.Button(self)
        button_frame.pack(pady=6)
        button_frame.configure(bg='steelblue1')
        
       
              
    def capture(self):
        print("Capture")
        Kamera().startpreview()
        Kamera().overlay()


    def stop(self):
        print("Stop")
        Kamera().stoppreview()
        Kamera().stopoverlay()

def main():
    haupt_fenster = tk.Tk()
    haupt_fenster.title(APP_TITLE)
    haupt_fenster.attributes('-fullscreen',True)


    
    
    
    haupt_fenster.option_add("*highlightThickness", 0)
    haupt_fenster.configure(bg='steelblue1')
    background_image = tk.PhotoImage(file=Hintergrundbild)
    tk.Label(haupt_fenster, image=background_image).place(x=0, y=0)
    
    main_frame = MainFrame(haupt_fenster)
    main_frame.pack(fill='both', expand=False, padx=0, pady=0,)
    main_frame.configure(bg='steelblue1')

            
    haupt_fenster.mainloop()
 
 
if __name__ == '__main__':
    main()	

Sirius3
User
Beiträge: 17750
Registriert: Sonntag 21. Oktober 2012, 17:20

falsch ist, dass Du viele Kamera-Instanzen erzeugst, Du darfst nur eine in MainFrame.__init__ erzeugen. Die Variable `camera` ist eine globale und sollte gar nicht auf oberster Ebene exisitieren. Das Erzeugen der PiCamera-Instanz und das setzen aller Parameter gehört in Kamera.__init__.
Dann fällt auch auf, dass in stopoverlay self vor camera fehlt.
Streifenhase1
User
Beiträge: 90
Registriert: Dienstag 22. Mai 2018, 07:15

hab es jetzt noch mal versucht das so zu machen wie ich es von dir bestanden habe aber da klappt gleich gar nichts mehr :-(

kannst mir das am vielleicht am Code verdeutlichen
Sirius3
User
Beiträge: 17750
Registriert: Sonntag 21. Oktober 2012, 17:20

was hast Du denn versucht?
Streifenhase1
User
Beiträge: 90
Registriert: Dienstag 22. Mai 2018, 07:15

Ich habe versucht im MainFrame __init__ diese zeilen

Code: Alles auswählen

camera = picamera.PiCamera(resolution=(1280,720))
self.camera=camera
einzufügen

und alle Parameter der Kamera in Kamera.__init__

bei stopoverlay() habe ich das camera in self.camera geändert


Dann habe ich ein Probiert

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.fx=0
        self.fy=0
        self.build()
        
    def build(self):
        button_frame = tk.Button(self)
        button_frame.pack(pady=6)
        button_frame.configure(bg='steelblue1')
        
       
              
    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, (self.fx, self.fy),)
        self.overlay = self.camera.add_overlay(pad.tostring(), size=img.size)
        self.overlay.alpha = 25
        self.overlay.layer = 4
        return self.overlay
                     
        
           

    def stop(self):
        print("Stop")
        camera.stop_preview()
        self.camera.remove_overlay(self.overlay)

    def close(self):
        print("Application-Shutdown")
        self.master.destroy()
        self.camera.stop_preview()
        self.camera.remove_overlay(self.overlay)
    
def main():
    haupt_fenster = tk.Tk()
    haupt_fenster.title(APP_TITLE)
    #haupt_fenster.overrideredirect(True)
    #haupt_fenster.geometry("{0}x{1}+0+0".format(haupt_fenster.winfo_screenwidth(), haupt_fenster.winfo_screenheight()))
    #haupt_fenster.geometry("+{}+{}".format(APP_XPOS, APP_YPOS))
    #haupt_fenster.geometry("{}x{}".format(APP_WIDTH, APP_HEIGHT))
    #haupt_fenster.overrideredirect(True)
    #haupt_fenster.overrideredirect(False)
    haupt_fenster.attributes('-fullscreen',True)


    haupt_fenster.option_add("*highlightThickness", 0)
    haupt_fenster.configure(bg='steelblue1')
    background_image = tk.PhotoImage(file=Hintergrundbild)
    tk.Label(haupt_fenster, image=background_image).place(x=0, y=0)
    
    main_frame = MainFrame(haupt_fenster)
    main_frame.pack(fill='both', expand=False, padx=0, pady=0,)
    main_frame.configure(bg='steelblue1')

    
	
    haupt_fenster.mainloop()

 
if __name__ == '__main__':
    main()

den code so zu nehmen und so kann ich den zwar das Overlay starten und beenden kann aber keine

z.b.mit

Code: Alles auswählen

MainFrame().capture()
die Funktion nicht aufrufen als Fehlemldung


Traceback (most recent call last):
File "/media/pi/Transcend/Kamera/Camera.py", line 353, in <module>
main()
File "/media/pi/Transcend/Kamera/Camera.py", line 348, in main
MainFrame().capture()
TypeError: __init__() missing 1 required positional argument: 'haupt_fenster'

Da ich das Kamerabild und die Vorschau seperat ausführen möchte wollte ich in einer Funktion die Benötigen Funktionen aufrufen
Sirius3
User
Beiträge: 17750
Registriert: Sonntag 21. Oktober 2012, 17:20

Die Zeile mit der Fehlermeldung kommt in dem gezeigten Code gar nicht vor. Wie soll man helfen, wenn man nicht weiß, was Du machst. Generell hast Du noch ein ungenaues Verständnis darüber, was Instanzen sind, und welche Lebensdauer, bzw. Gültigkeit sie haben. MainFrame ist der Rahmen, der das Kamerabild anzeigt, davon gibt es bei Dir genau eines, deshalb darfst Du von dieser Klasse auch nur genau eine Instanz erzeugen, die Du halt dann überall dort hin übergeben mußt, wo Du etwas am Kamerabild ändern willst.
Streifenhase1
User
Beiträge: 90
Registriert: Dienstag 22. Mai 2018, 07:15

Ja da gebe ich dir recht das mein Verständnis recht klein ist.

Und verstehe auch nur zum Teil was du meinst.

Aber das MainFrame ist ja nur ein Fenster auf dem Buttons und ein Hintergrundbild besteht.

Das kamera fenster wird ja mit

Code: Alles auswählen

camera.preview_window=(200, 50, 1050, 800)
erstellt

Ich geb zu das ich nicht verstehe warum ich die das Kamera Bild starten und beenden kann...
Aber das Overlay auf selbe weise starten aber danach keinen Zugriff mehr auf das Overlay bekomme
Streifenhase1
User
Beiträge: 90
Registriert: Dienstag 22. Mai 2018, 07:15

Würdet ihr mit trotzdem noch mal helfen und mir erklären warum das so ist und wie das Problem löse?



Ich habe eine Klasse

Code: Alles auswählen

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

in dieser habe ich einen Button, der Eine Funktion aus einem anderen Frame starten soll

Code: Alles auswählen

  overlay_rechtsbutton = Button(self, text="rechts", background='steelblue1', activebackground='steelblue3', command=Main_Frame(haupt_fenster).self.frechts)
  overlay_rechtsbutton.place(x = 110, y = 460, width=60, height=40)
Wenn ich da so mache kommt als Fehlermeldung


command=MainFrame(haupt_fenster).self.frechts)
NameError: name 'haupt_fenster' is not defined

Wie muss ich Haupt fenster definieran damit das funktioniert?


Hier noch mal etwas mehr Code mit dem MainFrame zusammen

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, 700))
        self.geometry("+{}+{}".format(10, 70))
        self.configure(bg='steelblue1')
        self.wm_overrideredirect(noborder)
        self.camera=camera
        self.fx = 0
        self.fy = 0

        self.cambri_threshold = tk.IntVar(value=cam_bri)
        self.camcon_threshold = tk.IntVar(value=cam_con)
        self.camiso_threshold = tk.IntVar(value=cam_iso)
        self.camshu_threshold = tk.IntVar(value=cam_shu)
        self.fx_threshold=tk.IntVar(value=self.fx)
        self.fy_threshold=tk.IntVar(value=self.fy)

       


        main_frame = tk.Frame(self)
        main_frame .pack(padx=10, pady=10)
       #Der Button der aus anderer Klasse die Funktion aufrufen soll

        overlay_rechtsbutton = Button(self, text="rechts", background='steelblue1', activebackground='steelblue3', command=self.frechts)
        overlay_rechtsbutton.place(x = 110, y = 460, width=60, height=40)




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.fx= 0
        self.fy= 0
        

        self.build()
        
    def build(self):
        button_frame = tk.Button(self)
        button_frame.pack(pady=6)
        button_frame.configure(bg='steelblue1')

  def frechts(self):
        print("Fendenkreuz liks")
        wert = 5
        self.fx = min(100, self.fx + wert)
        self.fx_threshold.set(self.fx_threshold.get() + wert)
        img = Image.open('gelb.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_renderer.update(pad.tostring())
def main():
    haupt_fenster = tk.Tk()
    haupt_fenster.title(APP_TITLE)
    #haupt_fenster.overrideredirect(True)
    #haupt_fenster.geometry("{0}x{1}+0+0".format(haupt_fenster.winfo_screenwidth(), haupt_fenster.winfo_screenheight()))
    haupt_fenster.geometry("+{}+{}".format(APP_XPOS, APP_YPOS))
    haupt_fenster.geometry("{}x{}".format(APP_WIDTH, APP_HEIGHT))
    #haupt_fenster.overrideredirect(True)
    #haupt_fenster.overrideredirect(False)
    #haupt_fenster.attributes('-fullscreen',True)


    
    
    
    haupt_fenster.option_add("*highlightThickness", 0)
    haupt_fenster.configure(bg='steelblue1')
    background_image = tk.PhotoImage(file=Hintergrundbild)
    tk.Label(haupt_fenster, image=background_image).place(x=0, y=0)
    
    main_frame = MainFrame(haupt_fenster)
    main_frame.pack(fill='both', expand=False, padx=0, pady=0,)
    main_frame.configure(bg='steelblue1')

    
    settings = Settings(haupt_fenster)
    
    haupt_fenster.mainloop()
    
 
if __name__ == '__main__':
    main()

Sirius3
User
Beiträge: 17750
Registriert: Sonntag 21. Oktober 2012, 17:20

Es gibt da nicht mehr viel zu helfen, außer, dass Du dringend mit einem Tutorial Deiner Wahl Objektorientierte Programmierung zu lernen. Solange Du nicht von Grund auf verstanden hast, was die Instanz einer Klasse ist, was Attribute sind, wie man Variablen an Funktionen übergibt, etc. hilft Dir das zeigen der Fehler, die Du machst, überhaupt nichts, weil Du bei der nächsten Änderung Deines Programms wieder mit den selben Fragen hier aufschlägst.

Wenn Du dann Fragen stellst, sollte die Fehlermeldung zum Code, den Du zeigst passen, und es sollte der Code soweit gepostet werden, dass es hier jeder ausprobieren kann, um den Fehler reproduzieren zu können.
Streifenhase1
User
Beiträge: 90
Registriert: Dienstag 22. Mai 2018, 07:15

Ich glaube ja auch das es nervt wenn man immer Fragen gestellt bekommt die für einen Einfach zu lösen sind, aber wir haben alle mal klein angefangen...
Ich möchte auch nicht Programmierer werden und das wird auch nicht mein Hobby, es ist einfach nur was um meine Tägliche Arbeit zu erleichtern....

Ich möchte es ja auch begreifen was ich falsch mache deshalb bitte ich ja auch um eine Erklärung, und am eigenem Beispiel ist es ja dann auch immer verständlicher.

Hier noch mal ein Code zum ausprobieren und vielleicht Hilft mir noch jemand, ansonsten trotzdem vielen Dank für die bisherige Hilfe...

Code: Alles auswählen

from tkinter import *
from tkinter import messagebox
import tkinter as tk
import picamera
import time
import numpy as np
from PIL import Image

APP_TITLE = "Kamera"
APP_XPOS = 10
APP_YPOS = 10
APP_WIDTH = 1280
APP_HEIGHT = 800
Hintergrundbild = "Hintergrund.gif"

camera = picamera.PiCamera(resolution=(1280,720))

cam_bri = 45
cam_con = 100
cam_shu = 20000
cam_iso = 100


camera.brightness = cam_bri
camera.contrast = cam_con
camera.shutter_speed = cam_shu
camera.iso = cam_iso

camera.vflip=False
camera.hflip=False
camera.saturation = -100
camera.framerate = 60
camera.awb_mode='auto'
camera.exposure_mode='auto'
camera.video_stabilization=True
camera.preview_fullscreen=False
camera.preview_window=(200, 50, 1050, 800)

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

        
        self.title("Settings")
        self.geometry("{}x{}".format(180, 700))
        self.geometry("+{}+{}".format(10, 70))
        self.configure(bg='steelblue1')
        self.wm_overrideredirect(noborder)
        self.camera=camera
        self.fx = 0
        self.fy = 0

        self.cambri_threshold = tk.IntVar(value=cam_bri)
        self.camcon_threshold = tk.IntVar(value=cam_con)
        self.camiso_threshold = tk.IntVar(value=cam_iso)
        self.camshu_threshold = tk.IntVar(value=cam_shu)
        self.fx_threshold=tk.IntVar(value=self.fx)
        self.fy_threshold=tk.IntVar(value=self.fy)
               


        main_frame = tk.Frame(self)
        main_frame .pack(padx=10, pady=10)

        settings_label = Label(self, bg="steelblue1", text="Einstellungen")
        settings_label.place(x = 20, y = 5, width=150, height=40)
        settings_label.config(font=("Arial", 15))

       
        overlay_linksbutton = Button(self, text="links", background='steelblue1', activebackground='steelblue3', command=self.flinks)
        overlay_linksbutton.place(x = 10, y = 460, width=60, height=40)

        Quit_button = Button(self, text="schließen", background='steelblue1', activebackground='steelblue3', command=self.destroy)
        Quit_button.place(x = 25, y = 640, width=120, height=40)

    def flinks(self):
        print("Fendenkreuz liks")
        wert = 5
        self.fx = min(100, self.fx - wert)
        self.fx_threshold.set(self.fx_threshold.get() - wert)
        img = Image.open('gelb.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_renderer.update(pad.tostring())

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.fx= 0
        self.fy= 0
        

        self.build()
        
    def build(self):
        button_frame = tk.Button(self)
        button_frame.pack(pady=6)
        button_frame.configure(bg='steelblue1')

        tk_Button = Button(self, text="Beenden", background='steelblue1', activebackground='steelblue3', command=self.close)
        tk_Button.place(x = 800, y = 3, width=100, height=30)

       
        tk_Button = Button(self, text="Einstellungen", background='steelblue1', activebackground='steelblue3', command=self.set_fenster)
        tk_Button.place(x = 600, y = 3, width=100, height=30)

        tk_Button = Button(self, text="Stoppen", background='steelblue1', activebackground='steelblue3', command=self.stop)
        tk_Button.place(x = 500, y = 3, width=100, height=30)

        tk_Button = Button(self, text="Starten", background='steelblue1', activebackground='steelblue3', command=self.capture)
        tk_Button.place(x = 400, y = 3, width=100, height=30)

    def capture(self):
         print("Starte_ Preview")
         self.camera.start_preview()
         print("Starte_Overlay")
         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, (self.fx, self.fy),)
         self.overlay_renderer = self.camera.add_overlay(pad.tostring(), size=img.size)
         self.overlay_renderer.alpha = 25
         self.overlay_renderer.layer = 4
         self.overlay_renderer.update(pad.tostring())
         return self.overlay_renderer
        
           
    def set_fenster(self):
        print("set_fenster")
        self.settings = Settings(self.haupt_fenster)

    def stop(self):
        print("Stop_Preview")
        self.camera.stop_preview()
        print("Stop_Oberlay")
        self.camera.remove_overlay(self.overlay_renderer)
        print("Fendenkreuz liks")
        
    def close(self):
        print("Stop_Preview")
        self.camera.stop_preview()
        print("Stop_Oberlay")
        self.camera.remove_overlay(self.overlay)
        print("Application-Shutdown")
        self.master.destroy()

def main():
    haupt_fenster = tk.Tk()
    haupt_fenster.title(APP_TITLE)
    #haupt_fenster.overrideredirect(True)
    #haupt_fenster.geometry("{0}x{1}+0+0".format(haupt_fenster.winfo_screenwidth(), haupt_fenster.winfo_screenheight()))
    haupt_fenster.geometry("+{}+{}".format(APP_XPOS, APP_YPOS))
    haupt_fenster.geometry("{}x{}".format(APP_WIDTH, APP_HEIGHT))
    #haupt_fenster.overrideredirect(True)
    #haupt_fenster.overrideredirect(False)
    #haupt_fenster.attributes('-fullscreen',True)


    
    
    
    haupt_fenster.option_add("*highlightThickness", 0)
    haupt_fenster.configure(bg='steelblue1')
    #background_image = tk.PhotoImage(file=Hintergrundbild)
    #tk.Label(haupt_fenster, image=background_image).place(x=0, y=0)
    
    main_frame = MainFrame(haupt_fenster)
    main_frame.pack(fill='both', expand=False, padx=0, pady=0,)
    main_frame.configure(bg='steelblue1')

    
    settings = Settings(haupt_fenster)
    
    
    haupt_fenster.mainloop()
    
 
if __name__ == '__main__':
    main()


Antworten