Mein FotoBox-Projekt

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.
Antworten
DaZeller
User
Beiträge: 14
Registriert: Sonntag 8. Februar 2015, 21:05

Hallo zusammen,

Ich möchte nun einfach mal mein Projekt etwas vorstellen evtl. kann ja jemand davon etwas gebrauchen oder sich zumindest anregungen für ein Eigenes Projekt holen.
Um es auch gleich vorweg zu nehmen, dies ist mein erstes Projekt in Python, der Code ist also mit sicherheit alles andere als schön.
Ich hoffe jedoch dies mit eurer Hilfe zu verbessern.

Ausgeführt wird das Projekt auf einem Raspberry-Py mit Raspbian.

Der Funktionsablauf soll ungefähr folgender sein:
- Der Raspberry ist auf Stand-by und wartet auf den Start vom User über GPIO
- Anschließend triggert der Pi via GPIO 4 Fotos
- Sind die Fotos im Kasten baue ich mittels PIL eine Art Collage aus den Aufnahmen
- Nun Soll der User Gelegenheit Bekommen zu der Collage noch einen Persönlichen text hinzu zu fügen
- Der User kann nun über eine Button eine Vorschau der fertigen Collage ansehen oder
- Über eine zweiten Button die Bearbeitung abschließen und die fertige Collage abspeichern
- Danach werden alle bisherigen Werke in Zufälliger Reihenfolge angezeigt und der Raspberry geht parallel wieder zurück auf Anfang und wartet auf den nächsten Trigger

Momentan stecke ich daran fest, Informationen an die Button-Events zu übergeben.
Diese rufe ich ja nicht direkt auf (mit Übergabeparameter und Co.), wie macht man das da?

Dem einen oder anderen dürfte das Projekt schon bekannt vorkommen :wink:
Ich habe auch versucht eure Ratschläge aus anderen Beiträgen so gut ich kann umzusetzen.
Leider bekomme ich es noch immer nicht hin, die "bösen global" komplett zu eliminieren.

Könnte mir da evtl. jemand sagen, wie ich es besser machen könnte?

Hier mal der komplette code:

Code: Alles auswählen

#!/usr/bin/python
# -*- coding: utf-8 -*-
##########################################################################################################
#
#	Script zum anordnen mehrerer Bilder in einem vorgegebenen Schema
#	Written by Michael Zeller zeller-michael(at)gmx.net 2015-02-10
#
##########################################################################################################

# Import of librarys
#--------------------------------------------------------------------------------------------------   
# Externe Module / librarys laden
from Tkinter import *
from os import *
from PIL import Image, ImageDraw, ImageFont, ImageTk
try:
    import RPi.GPIO as GPIO
except RuntimeError:
    print("Error importing RPi.GPIO!  This is probably because you need superuser privileges.  You can achieve this by using 'sudo' to run your script")
import time
import glob

# Projekt Einstellungen:
#--------------------------------------------------------------------------------------------------
# Positionen der Bilder. Angaben in Pixel von der oberen linken Ecke des Hintergrundes bemessen
# Aufbau Array: PildPos 1,2,3,4 und TextPos
ImgPositions = [(15,15),(15,796),(350,796),(700,796),(1200, 400)]
# Groessen auf die die Bilder skaliert werden sollen. Angaben in Pixel Breite,Hoehe
# Nur zwei verschiedene bildergroessen, da die Bilder 2 bis 4 gleich gross sein sollen
ImgSizes = [(1150, 768),(617, 375)]

# Verzeichnisse
font = ImageFont.truetype("/usr/share/fonts/truetype/msttcorefonts/Comic_Sans_MS.ttf",40)
PictureSource = "/home/pi/Desktop/FotoBox/EingangsBilder/" # Die Speicherkarte der angeschlossenen Kammera
Collagen = "/home/pi/Desktop/FotoBox/Collagen/"
VerarbeiteteBilder = "/home/pi/Desktop/FotoBox/VerarbeiteteBilder/"
Background = Image.open("Hintergrund_1.png")
# Belegung der GPIO
triggerInPin = 11
triggerOutPin = 13
pictureCount = 0
# use the Board-numbering to identify the GPIO signals
GPIO.setmode(GPIO.BOARD)

# HW-Initalisation
#--------------------------------------------------------------------------------------------------
GPIO.setup(triggerInPin, GPIO.IN, pull_up_down = GPIO.PUD_DOWN)
GPIO.setup(triggerOutPin, GPIO.OUT)

##########################################################################################################
# Funktionen:
##########################################################################################################

# ISR (Interrupt routine)
#--------------------------------------------------------------------------------------------------
def Interrupt(channel):
	oneCycle(ImgPositions, ImgSizes, PictureSource, Background)


# Button Event "Preview":
#--------------------------------------------------------------------------------------------------
def callbackPreview():
	global Background
	global ImgPositions
	
	print "Button event Preview"
	BackgroundDummy = Background.copy()

	# Text auf dem Hintergund platzieren
	draw = ImageDraw.Draw(BackgroundDummy)
	draw.text(ImgPositions[4], TextBoxDedication.get("1.0",END), font=font)

	BackgroundDummy = BackgroundDummy.resize(ImgSize1)
	photo = ImageTk.PhotoImage(BackgroundDummy)
	LabelPreview = Label(window, height=768, width=1150, background="#F10", foreground="#F10", image=photo)
	LabelPreview.image = photo
	LabelPreview.grid(row=0, columnspan=3)
		

# Button Event "Complete":
#--------------------------------------------------------------------------------------------------
def callbackComplete():
	global Background
	global ImgPositions
	global Collagen

	print "Button event Complete"

	# Text auf dem Hintergund platzieren
	draw = ImageDraw.Draw(Background)
	draw.text(ImgPositions[4], TextBoxDedication.get("1.0",END), font=font)
	
	Background.save(Collagen + time.strftime("%d.%m.%Y_%H:%M:%S") + "_" + TextBoxPersons.get("1.0",END) + ".jpg", "JPEG")

	window.destroy()	

	
# Funktion für einen Programmablauf
#--------------------------------------------------------------------------------------------------
def oneCycle(myImgPositions, myImgSizes, myPictureSource, myBackground):
	pictureCount = 0
	time.sleep(2)
	while pictureCount < 4:
	        GPIO.output(triggerOutPin,GPIO.HIGH)
                time.sleep(1)
		GPIO.output(triggerOutPin,GPIO.LOW)
        	pictureCount = pictureCount + 1
        	print "Bild Nr.: " + str(pictureCount) + " geschossen"
		time.sleep(2)
		
	time.sleep(2)
	EingangsBilder = glob.glob(myPictureSource + "*.JPG")	# ! Case-Sensitive bei Dateiendung
	print "Die Eingangsbilder:"
	for filename in EingangsBilder:
		print filename

	# Aufbereitung der einzelnen Biler
	# Öffnen der Bilder
	Img1 = Image.open(EingangsBilder[0])	# grosses bild links Oben
	Img2 = Image.open(EingangsBilder[1])	# kleines Bild unten links
	Img3 = Image.open(EingangsBilder[2])	# kleines Bild unten mitte
	Img4 = Image.open(EingangsBilder[3])	# kleines Bild unten rechts

	# Resize
	Img1 = Img1.resize(myImgSizes[0])
	Img2 = Img2.resize(myImgSizes[1])
	Img3 = Img3.resize(myImgSizes[1])
	Img4 = Img4.resize(myImgSizes[1])

	# Platzierung der Bilder auf dem Hintergrund
	Background.paste(Img1, myImgPositions[0])
	Background.paste(Img2, myImgPositions[1])
	Background.paste(Img3, myImgPositions[2])
	Background.paste(Img4, myImgPositions[3])
	# Dateien wieder schließen
	#Img1.close()
	#Img2.close()
	#Img3.close()
	#Img4.close()
	print "Resized und zusammengebaut"
	##########################################################################################################
	# GUI erzeugen
	window=Tk()
	window.title('Geburtstags-Fotoerinnerungen-Box')
	# folgende zwei zeilen für Fenserdarstellung (nicht vollbild)	
	#window.geometry('900x500')				# Breite mal Hoehe vom window, Einheit: Pixel
	#window.resizable(width=None, height=None)
	window.attributes("-fullscreen", True)			# Öffnet das Fenster im vollbildmodus
	# Label zur anzeige des Bildes erzeugen
	photo = ImageTk.PhotoImage(Background.resize(myImgSizes[0]))
	LabelPreview = Label(window, height=768, width=1150, background="#F10", foreground="#F10", image=photo)
	LabelPreview.image = photo
	LabelPreview.grid(row=0, columnspan=3)
	# Label Glückwünsche erzeugen
	LabelDedication = Label(window, height=2, width=30, bd=1, font=("Comic_Sans_MS", 16))
	LabelDedication.configure(text="Deine/Eure besten Wünsche \n an das Geburtstagskind:")
	LabelDedication.grid(row=1, column=0)
	# Textfeld erzeugen
	TextBoxDedication = Text(window, height=10, width=30, font=("Comic_Sans_MS", 16))
	TextBoxDedication.grid(row=2, column=0, rowspan=2)
	TextBoxDedication.insert(END, "")
	# Label Personen erzeugen
	LabelPersons = Label(window, height=2, width=30, font=("Comic_Sans_MS", 16))
	LabelPersons.configure(text="Wer ist alles auf dem Bild?:")
	LabelPersons.grid(row=1, column=1)
	# Textfeld erzeugen
	TextBoxPersons = Text(window, height=10, width=30, font=("Comic_Sans_MS", 16), takefocus=TRUE)
	TextBoxPersons.grid(row=2, column=1, rowspan=2)
	TextBoxPersons.insert(END, "")
	# Button preview erzeugen
	ButtonPreview = Button(window, text="Vorschau", command=callbackPreview)
	ButtonPreview.grid(row=2, column=2)
	# Button complete erzeugen
	ButtonComplete = Button(window, text="Go", command=callbackComplete)
	ButtonComplete.grid(row=3, column=2)

	# Dateien aus dem Eingangs in den Ausgangsordner verschieben
	for filename in EingangsBilder:
		EinBild = filename
		AusBild = filename.replace("EingangsBilder", "VerarbeiteteBilder")
		print EinBild
		print AusBild
	#	rename(EinBild, AusBild)	#Nur zum Testen Auskommentiert, da das Verschieben der Bilder lästig wurde... ;)
	print "Bilder verschoben"
	
	window.mainloop()
	print "after window.mainloop"
	
	return


# Interrupt Event hinzufuegen. Pin 17, auf steigende Flanke reagieren und ISR "Interrupt" deklarieren
GPIO.add_event_detect(triggerInPin, GPIO.RISING, callback = Interrupt, bouncetime = 1000)

# Endlosschleife
while True:
	time.sleep(1)
Wie immer frue ich mich auf eure Tipps und Ratschläge. :D

viele Grüße

DaZeller

PS: Bitte geht nicht zu hart mit mir in's Gericht, ich versuche wirklich dazu zu lernen und es ist nunmal noch kein Meister vom Himmel gefallen. :wink:

EDIT:
Um das Problem an dem im momentan hänge besser zu verdeutlichen hier die Ausgabe der Konsole:

Code: Alles auswählen

pi@FotoBoxPi ~/Desktop/FotoBox $ sudo python PythonCollage_8.py 
PythonCollage_8.py:48: RuntimeWarning: This channel is already in use, continuing anyway.  Use GPIO.setwarnings(False) to disable warnings.
  GPIO.setup(triggerOutPin, GPIO.OUT)
Bild Nr.: 1 geschossen
Bild Nr.: 2 geschossen
Bild Nr.: 3 geschossen
Bild Nr.: 4 geschossen
Die Eingangsbilder:
/home/pi/Desktop/FotoBox/EingangsBilder/sticky-notes.JPG
/home/pi/Desktop/FotoBox/EingangsBilder/wasser2.JPG
/home/pi/Desktop/FotoBox/EingangsBilder/IMG_3301.JPG
/home/pi/Desktop/FotoBox/EingangsBilder/IMG_3358.JPG
Resized und zusammengebaut
/home/pi/Desktop/FotoBox/EingangsBilder/sticky-notes.JPG
/home/pi/Desktop/FotoBox/VerarbeiteteBilder/sticky-notes.JPG
/home/pi/Desktop/FotoBox/EingangsBilder/wasser2.JPG
/home/pi/Desktop/FotoBox/VerarbeiteteBilder/wasser2.JPG
/home/pi/Desktop/FotoBox/EingangsBilder/IMG_3301.JPG
/home/pi/Desktop/FotoBox/VerarbeiteteBilder/IMG_3301.JPG
/home/pi/Desktop/FotoBox/EingangsBilder/IMG_3358.JPG
/home/pi/Desktop/FotoBox/VerarbeiteteBilder/IMG_3358.JPG
Bilder verschoben
Button event Preview
Exception in Tkinter callback
Traceback (most recent call last):
  File "/usr/lib/python2.7/lib-tk/Tkinter.py", line 1437, in __call__
    return self.func(*args)
  File "PythonCollage_8.py", line 71, in callbackPreview
    draw.text(ImgPositions[4], TextBoxDedication.get("1.0",END), font=font)
NameError: global name 'TextBoxDedication' is not defined
Button event Complete
Exception in Tkinter callback
Traceback (most recent call last):
  File "/usr/lib/python2.7/lib-tk/Tkinter.py", line 1437, in __call__
    return self.func(*args)
  File "PythonCollage_8.py", line 91, in callbackComplete
    draw.text(ImgPositions[4], TextBoxDedication.get("1.0",END), font=font)
NameError: global name 'TextBoxDedication' is not defined
after window.mainloop
Bild Nr.: 1 geschossen
Bild Nr.: 2 geschossen
^CBild Nr.: 3 geschossen
Traceback (most recent call last):
  File "PythonCollage_8.py", line 197, in <module>
    time.sleep(1)
KeyboardInterrupt
Wie gehe ich richtig vor, die Information aus den Textboxen in das Bild ein zu bauen (bzw. an die entsprechende Funktion zu übergeben)?
BlackJack

@DaZeller: Hier gibt's jetzt sicher Wiederholungen, aber wenn Du die Anmerkungen nicht umsetzt, hörst Du halt einiges mehrfach. :-P

Ganz grundsätzlich mal den Style Guide for Python Code anwenden, also keine Zeilen die länger als 80 Zeichen sind, und die Namensschreibweisen ändern. Letzteres hört sich nicht so wichtig an, aber wenn man sich erst einmal an ein Schema gewöhnt hat, dann liest sich abweichender Quelltext deutlich schwieriger.

Wenn man sich zum Beispiel an „Konstanten werden komplett in Grossbuchstaben benannt” hält dann erkennt man nicht nur auf den ersten Blick welche Namen für Konstanten stehen, sondern man kann sich auch so unsinnige Präfixe wie `my*` sparen um zwischen Konstante und Variable zu unterscheiden. Wobei das auch nur jemand unterscheiden kann der weiss das der Name ohne Präfix eine Konstante ist, und welche Namen ohne Präfixe Konstanten sind und welche nicht.

Sternchen-Importe sind böse. Bei `Tkinter` holst Du Dir ca. 190 Namen ins Modul. Und bei `os` ist sogar einer dabei über den gerne gestolpert wird: `open()`. Das Modul hat nämlich eine `open()`-Funktion die bei so einem Import die eingebaute `open()`-Funktion verdeckt.

Der erste Kommentar im Quelltext würde auch prima als Docstring durchgehen.

Auf Modulebene sollten nur Konstanten, Klassen, und Funktionen definiert werden. Das Hauptprogramm steht üblicherweise in einer Funktion die `main()` heisst.

Kommentare sollten dem Leser einen Mehrwert gegenüber dem Code liefern und nicht das offensichtliche noch einmal als Kommentar wiederholen. Kommentare die erklären was die darauf folgende Funktion tut sind als Docstrings besser aufgehoben.

Kommentare mit Trennlinien sollten überflüssig sein. Man kann an der Codestruktur erkennen wo Funktionen oder Klassen definiert werden.

Die `Interrupt()`-Funktion erscheint mir überflüssig. Die ignoriert ja nur das übergebene Argument und ruft eine weitere Funktion mit lauter Konstanten als Argumenten auf. Die Konstanten hätte man in der aufgerufenen Funktion als Default-Werte für die Argumente setzen können und um das Argument zu ignorieren hätte auch ein ``lambda``-Ausdruck gereicht.

Sowie ich das sehe ist kein einziges ``global`` in dem Quelltext sinnvoll. Das sind alles Konstanten die sowieso nicht neu zugewiesen werden, also kann man diese ``global``-Zeilen alle einfach entfernen ohne das sich etwas ändert.

Während `oneCycle()` läuft sollte man IMHO verhindern dass es erneut aufgerufenen werden kann. Der Benutzer könnte ja auf die Idee kommen noch mal auf den Knopf zu drücken.

Über nummerierte Namen wurde ja schon was gesagt.

Die Funktion ist auch ein bisschen lang. Da wird zu viel auf einmal gemacht. Insbesondere Sachen die man bei der Entwicklung sicher gerne einzeln mal testen.

`callbackPreview()` und `callbackComplete()` teilen sich am Anfang Code.

An der Stelle kommt man IMHO auch nicht an einer Klasse für die GUI vorbei. Das kann man zwar auch mit Closures oder `functool.partial()` lösen, aber eine Klasse wäre hier in Python das Sprachmittel der Wahl. Das würde dann auch Dein ``global``-Problem lösen.
DaZeller
User
Beiträge: 14
Registriert: Sonntag 8. Februar 2015, 21:05

Hallo BlackJack,

vielen Dank für deine Geduld. Ich versuche deine Ratschläge zu berücksichtigen.

Leider muss ich dir gestehen, dass ich von dem geschriebenen aus deinem Beitrag nicht die Hälfte verstehe :cry:
Ich werde trotz dem versuchen nach und nach möglichst viel davon umzusetzen, so wie ich es verstehe!
Ihr dürf jedoch keine Wunder von mir verlangen... (ich war eigentlich schon recht Stolz, dass ich es geschafft hatte die Größen nicht durch zu nummerieren sondern in ein Array zu verpacken. :| )

Es wäre mir eine große Hilfe, wenn mir jemand (evtl. anhand eines Konkreten Beispieles) zeigen könnte, wie ich sauber die GUI erstelle und daraus aus der Textbox die Information haraus bekome.

viele Grüße

DaZeller

EDIT:
Was die ISR angeht, die benötige ich einfach, um auf das Signal vom GPIO zu reagieren.
DaZeller
User
Beiträge: 14
Registriert: Sonntag 8. Februar 2015, 21:05

Ich versuche gerade das angemerkte Umzusetzen, und die Durchnummerierung der Images zu ersetzen.

Code: Alles auswählen

	# Alle Bilder öffnen, verkleinern und auf dem Hintergrund platzieren
	i = 0
	for filename in EingangsBilder:
		print filename
		Images[i] = Image.open(filename)
		if i < 1:
			Images[i] = Images[i].resize(myImgSizes[0])
		else:
			Images[i] = Images[i].resize(myImgSizes[1])
		Background.paste(Images[i], myImgPositions[i])
		i = i + 1
Ist das jetzt besser, in eurem Sinne?
Üpsilon
User
Beiträge: 222
Registriert: Samstag 15. September 2012, 19:23

Ich würde zumindest das Öffnen der Bilder in eine List-Comprehension verschieben.
Dann alle Bilder der Liste auf my_img_sizes[1] resizen.
Und dann das 0te der Bilderliste extra resizen.
Und dann in einer Schleife die Bilder pasten.

Vielleicht wäre es clever, ein {Bilddateiname:Position}-Dictionary zu verwenden. Und, wie Bj schon schrieb, natürlich eine Klasse. Dann sieht man auch viel leichter, welche Veränderlichen es im Programm gibt.

Aber mein wichtigster Kritikpunkt:

Code: Alles auswählen

font = ImageFont.truetype("/usr/share/fonts/truetype/msttcorefonts/Comic_Sans_MS.ttf",40)
Garr! HÄSSLICH! TÖTET ES! :wink:
http://en.wikipedia.org/wiki/Comic_Sans#Opposition
PS: Die angebotene Summe ist beachtlich.
DaZeller
User
Beiträge: 14
Registriert: Sonntag 8. Februar 2015, 21:05

Danke Üpyilon für deine Hinweise.

Mein größtes Problem im Moment ist jedoch, dass ich die Inhalte der Textboxen nicht ausgelesen bekomme.

Könnte mir dazu evtl. jemand sagen wie ich es Hinbekomme innerhalb einer Funktion eine GUI zu erstellen, dazu ein Button-Event mit dem ich den Tex einer Textbox abfragen kann?!?

Ich stehe sowas von auf dem Schlauch... :cry:

Das ist eine ältere Version des Codes, darin hat das Abrufen des Textes aus den Textboxen noch funktioniert.

Code: Alles auswählen

#!/usr/bin/python
# -*- coding: utf-8 -*-
##########################################################################################################
#
#	Script zum anordnen mehrerer Bilder in einem vorgegebenen Schema
#	Written by Michael Zeller zeller-michael(at)gmx.net 2015-02-05
#
##########################################################################################################

# Externe Module / librarys laden
from Tkinter import *
from os import *
from PIL import Image, ImageDraw, ImageFont, ImageTk
import time
import glob

# Projekt Einstellungen:
ImgPos1 = (15,15)	# Positionen der Bilder. Angaben in Pixel von der oberen linken Ecke des Hintergrundes bemessen
ImgPos2 = (15,796)
ImgPos3 = (350,796)
ImgPos4 = (700,796)
TextPos	= (1200, 400)
ImgSize1 = (1150, 768)	# Groessen auf die die Bilder skaliert werden sollen. Angaben in Pixel Breite,Hoehe
ImgSize2 = (617, 375)	# Nur zwei verschiedene bildergroessen, da die Bilder 2 bis 4 gleich gross sein sollen
SourceDir = "TestDir"	# Verzeichnis aus dem die Bilder eingelesen werden.
font = ImageFont.truetype("/usr/share/fonts/truetype/msttcorefonts/Comic_Sans_MS.ttf",40)
EingangsBilder = glob.glob("/home/michael/FotoBox/EingangsBilder/*.JPG")	# Achtung Case-Sensitive bei Dateiendung
for filename in EingangsBilder:
	print filename
Collagen = "/home/michael/FotoBox/Collagen/"
VerarbeiteteBilder = "/home/michael/FotoBox/VerarbeiteteBilder/"
Background = Image.open("Hintergrund_1.png")

# Variablen:
global Persons
global Dedication
global BackgroundDummy

# Aufbereitung der einzelnen Biler
# Öffnen der Bilder
Img1 = Image.open(EingangsBilder[0])	# grosses bild links Oben
Img2 = Image.open(EingangsBilder[1])	# kleines Bild unten links
Img3 = Image.open(EingangsBilder[2])	# kleines Bild unten mitte
Img4 = Image.open(EingangsBilder[3])	# kleines Bild unten rechts

# Resize
Img1 = Img1.resize(ImgSize1)
Img2 = Img2.resize(ImgSize2)
Img3 = Img3.resize(ImgSize2)
Img4 = Img4.resize(ImgSize2)

# Platzierung der Bilder auf dem Hintergrund
Background.paste(Img1, ImgPos1)
Background.paste(Img2, ImgPos2)
Background.paste(Img3, ImgPos3)
Background.paste(Img4, ImgPos4)

# Dateien wieder schließen
Img1.close()
Img2.close()
Img3.close()
Img4.close()

# Dateien aus dem Eingangs in den Ausgangsordner verschieben
for filename in EingangsBilder:
	EinBild = filename
	AusBild = filename.replace("EingangsBilder", "VerarbeiteteBilder")
	print EinBild
	print AusBild
#	rename(EinBild, AusBild)	#Nur zum Testen Auskommentiert, das das Verschieben der Bilder lästig wurde... ;)

##########################################################################################################

# Button Event "Preview":
def callbackPreview():
	global Background

	print "Button event Preview"
	BackgroundDummy = Background

	# Text auf dem Hintergund platzieren
	draw = ImageDraw.Draw(BackgroundDummy)
	draw.text(TextPos, TextBoxDedication.get("1.0",END), font=font)
	del draw

	BackgroundDummy = BackgroundDummy.resize(ImgSize1)
	photo = ImageTk.PhotoImage(BackgroundDummy)
	LabelPreview = Label(window, height=768, width=1150, background="#F10", foreground="#F10", image=photo)
	LabelPreview.image = photo # keep a reference!
	LabelPreview.grid(row=0, columnspan=3)
		

# Button Event "Complete":
def callbackComplete():
	global Background
	
	print "Button event Complete"

	# Text auf dem Hintergund platzieren
	draw = ImageDraw.Draw(Background)
	draw.text(TextPos, TextBoxDedication.get("1.0",END), font=font)
	del draw
	
	Background.save(time.strftime("%d.%m.%Y_%H:%M:%S") + "_" + Persons + ".jpg", "JPEG")

	window.destroy()	

##########################################################################################################
# GUI erzeugen
window=Tk()			# erzeugt ein window, in das widgets eingefuegt werden
window.title('Geburtstags-Fotoerinnerungen-Box')	# Titel, der oben im window gezeigt wird
#window.geometry('900x500')				# Breite mal Hoehe vom window, Einheit: Pixel
#window.geometry('1920x1080')				# Breite mal Hoehe vom window, Einheit: Pixel
window.resizable(width=None, height=None)
window.attributes("-fullscreen", True)			# Öffnet das Fenster im vollbildmodus
# Label zur anzeige des Bildes erzeugen
photo = ImageTk.PhotoImage(Background.resize(ImgSize1))
LabelPreview = Label(window, height=768, width=1150, background="#F10", foreground="#F10", image=photo)
LabelPreview.image = photo # keep a reference!
LabelPreview.grid(row=0, columnspan=3)
# Label Glückwünsche erzeugen
LabelDedication = Label(window, height=2, width=30, bd=1, font=("Comic_Sans_MS", 16))
LabelDedication.configure(text="Deine/Eure besten Wünsche \n an das Geburtstagskind:")
LabelDedication.grid(row=1, column=0)
# Textfeld erzeugen
TextBoxDedication = Text(window, height=10, width=30, font=("Comic_Sans_MS", 16))
TextBoxDedication.grid(row=2, column=0, rowspan=2)
TextBoxDedication.insert(END, "")
# Label Personen erzeugen
LabelPersons = Label(window, height=2, width=30, font=("Comic_Sans_MS", 16))
LabelPersons.configure(text="Wer ist alles auf dem Bild?:")
LabelPersons.grid(row=1, column=1)
# Textfeld erzeugen
TextBoxPersons = Text(window, height=10, width=30, font=("Comic_Sans_MS", 16), takefocus=TRUE)
TextBoxPersons.grid(row=2, column=1, rowspan=2)
TextBoxPersons.insert(END, "")
# Button preview erzeugen
ButtonPreview = Button(window, text="Vorschau", command=callbackPreview)
ButtonPreview.grid(row=2, column=2)
# Button complete erzeugen
ButtonComplete = Button(window, text="Go", command=callbackComplete)
ButtonComplete.grid(row=3, column=2)

print "2"

window.mainloop()

print "after window.mainloop"

# Endlosschleife
while True:
	time.sleep(1)
lackschuh
User
Beiträge: 281
Registriert: Dienstag 8. Mai 2012, 13:40

Abgesehen von den ganzen globalen Variablen und der nicht PEP8 konformen Schreibweise nützt dir bei einem GUI-Rahmenwerk die

Code: Alles auswählen

# Endlosschleife
while True:
        time.sleep(1)
auch nichts.
BlackJack

@lackschuh: Die GUI-Hauptschleife läuft in einem anderen Thread als die ``while``-Schleife mit dem `sleep()`. Das `GPIO`-Modul startet so wie es aussieht mindestens einen Thread wenn man eine Rückruffunktion an einen Pin mit Interrupt bindet.
Antworten