__deets__ hat geschrieben: ↑Mittwoch 20. April 2022, 16:38
Du kannst in einem extra Thread in der GUI einen HTTP Server laufen lassen. Der kann dann den geteilten Zustand modifizieren. Einfach ein anderes Skript laufen lassen bringt nix. Das ist, als ob du das gleiche Word Dokument zweimal öffnest - da siehst du auch keine Änderung des einen im anderen.
Vielen Dank für den Hinweis!
Da ich mich noch nie wirklich mit Threads beschäftigt habe, hat es sehr lange gedauert bis ich etwas funktionierendes hinbekommen habe...
Allerdings bin ich mit dieser Lösung nicht wirklich zufrieden.
slideshow.py:
Code: Alles auswählen
timer = 5000
debug = True
root = tk.Tk()
SCREEN_WIDTH = root.winfo_screenwidth()
SCREEN_HEIGHT = root.winfo_screenheight()
pic_list = []
for name in glob.glob(r'C:\Coding\PythonSlideshow\images\*'):
pic_list.append(name)
class SlideGui:
def __init__(self, main_window, pause):
self.new_pic = None
self.pause = pause
self.mainWindow = main_window
self.mainWindow.title("Python Slideshow")
self.mainWindow.geometry('%dx%d' % (SCREEN_WIDTH, SCREEN_HEIGHT))
if not debug:
root.attributes('-fullscreen', True)
self.mainWindow.configure(bg="black")
self.img = tk.Label(self.mainWindow)
self.img.pack()
self.label = tk.Label(self.mainWindow)
self.label.pack(side="top", fill="both", expand=True)
self.check_pause()
self.pic()
def stop(self):
root.after_cancel(self.new_pic)
def resume(self):
self.pic()
def pic(self):
load = Image.open(random.choice(pic_list))
load = ImageOps.exif_transpose(load)
pic_width, pic_height = load.size
real_aspect = pic_width / pic_height
cal_width = int(real_aspect * SCREEN_HEIGHT)
load2 = load.resize((cal_width, SCREEN_HEIGHT))
render = ImageTk.PhotoImage(load2)
self.img.config(image=render, borderwidth=0, highlightthickness=0)
self.img.image = render
self.new_pic = root.after(timer, self.pic)
def check_pause(self):
if self.pause.value == 1:
self.stop()
root.after(timer, self.check_not_pause)
else:
root.after(timer, self.check_pause)
def check_not_pause(self):
if self.pause.value == 0:
self.resume()
root.after(timer, self.check_pause)
else:
root.after(timer, self.check_not_pause)
if __name__ == "__main__":
pause = multiprocessing.Value('i', 0)
slideshow = SlideGui(root, pause)
x = threading.Thread(target=webview.startWebview, args=(pause,))
x.start()
y = threading.Thread(target=root.mainloop(), args=(pause,))
y.start()
webview.py:
Code: Alles auswählen
app = Flask(__name__)
class WebView(FlaskView):
def start(self, pause):
self.pause = pause
app.run(debug=False, host='0.0.0.0')
def index(self):
return 'Hello world'
@route("/screen", methods=["GET"])
def screenOn(self):
if "state" in request.args:
state = request.args["state"]
if state == "on":
# run("vcgencmd display_power 1", shell=True)
self.pause.value = 1
print("Web: " + str(self.pause.value))
return "Bildschirm an"
elif state == "off":
# run("vcgencmd display_power 0", shell=True)
self.pause.value = 0
return "Bildschirm wird ausgeschaltet"
else:
return "Unbekannter Status"
else:
return "Error: Kein Status angegeben"
WebView.register(app, route_base="/")
def startWebview(pause):
WebView.start(FlaskView, pause)
Die HTTP Requests werden momentan genutzt zum ein und ausschalten des Bildschirms. Ich hab die jetzt einfach unverändert reingeschmissen also bitte nicht über /screen etc. wundern.
An sich funktioniert soweit alles, allerdings wirkt das für mich sehr aufwendig wenn ich noch andere Requests wie z.B. skip, timer, debug, etc. einbauen will.
Ich müsste dann für jeden Request eine eigene Value übergeben oder? Gibt es da geeignetere Wege?
Gibt es hier sonst noch Punkte die man verbessern kann?