Zugriff auf Variablen einer anderen Funktion
@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.
PS: aussagekräftigere Funktions- und Variablennamen würden beim Verstehen und Beschreiben des Problems helfen.
-
- User
- Beiträge: 90
- Registriert: Dienstag 22. Mai 2018, 07:15
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]
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]
-
- User
- Beiträge: 90
- Registriert: Dienstag 22. Mai 2018, 07:15
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()
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
schreiben. Das ist aber trivial und es bleibt unklar, was du wirklich beabsichtigts.
Code: Alles auswählen
wert = a()
-
- User
- Beiträge: 90
- Registriert: Dienstag 22. Mai 2018, 07:15
ok bin etwas weiter.
Hier mal etwas genauer was ich möchte.
Das ist die Funktion die variable "o" aufruft.
Und möchte "o" mit einer anderen Funktion beenden.
könnte das funktionieren?
Kann es vor Ort nicht probieren
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)
Kann es vor Ort nicht probieren
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.
- __blackjack__
- User
- Beiträge: 13006
- Registriert: Samstag 2. Juni 2018, 10:21
- Wohnort: 127.0.0.1
- Kontaktdaten:
Unglückliche Wortwahl — natürlich *nicht* *global* sondern auf dem Objekt. Wo übrigens auch die `camera` hingehören würde.
“Most people find the concept of programming obvious, but the doing impossible.” — Alan J. Perlis
@__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.
@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)
-
- User
- Beiträge: 90
- Registriert: Dienstag 22. Mai 2018, 07:15
@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
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
-
- User
- Beiträge: 90
- Registriert: Dienstag 22. Mai 2018, 07:15
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.
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
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
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
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)
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()
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`.
-
- User
- Beiträge: 90
- Registriert: Dienstag 22. Mai 2018, 07:15
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
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?
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)
@Sirius3
Soll ich den kompletten Code mal Posten?
-
- User
- Beiträge: 90
- Registriert: Dienstag 22. Mai 2018, 07:15
OK...
Ich habe nun einen anderen weg eingeschlagen und eine Klasse für die Funktionen für die Kamera erstellt.
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?
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?
-
- 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
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()
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.
Dann fällt auch auf, dass in stopoverlay self vor camera fehlt.
-
- 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
kannst mir das am vielleicht am Code verdeutlichen
-
- User
- Beiträge: 90
- Registriert: Dienstag 22. Mai 2018, 07:15
Ich habe versucht im MainFrame __init__ diese zeilen
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
den code so zu nehmen und so kann ich den zwar das Overlay starten und beenden kann aber keine
z.b.mit
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
Code: Alles auswählen
camera = picamera.PiCamera(resolution=(1280,720))
self.camera=camera
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()
z.b.mit
Code: Alles auswählen
MainFrame().capture()
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