Seite 1 von 1
Tkinter als Class - Bilder werden NICHT angezeigt
Verfasst: Samstag 5. November 2016, 20:51
von tomtombusiness
Anbei mein aktueller Code. Ansich funktioniert alles, jedoch seitdem ich es als Class gebaut habe werden mir die Bilder nicht mehr angezeigt
ich habe schon Google benutzt aber keine lösung gefunden
Code: Alles auswählen
try:
#~~ For Python 2.x
import Tkinter as tk
except ImportError:
#~~ For Python 3.x
import tkinter as tk
import os
relativPath = os.path.abspath('.')
class GUI(tk.Frame):
"""GUI Behandlung als Klasse"""
def __init__(self, parent, *args, **kwargs):
tk.Frame.__init__(self, parent, *args, **kwargs)
self.parent = parent
self.parent.geometry('800x480+0+0')
self.parent.fullscreen = True
print(relativPath + '\\images\\bluetooth_disconnected.gif')
###Oberes Panel
#Uhrzeit und Datum
lbDayTime = tk.Label(parent, text = 'Uhrzeit')
lbDayTime.place(x = 50, y = 0, height = 50)
#Bluetooth Symbol
imgBluetooth = tk.PhotoImage(file = relativPath + '\\images\\bluetooth_disconnected.gif')
lbBluetooth = tk.Label(parent, image = imgBluetooth)
lbBluetooth.place(x = 550, y = 0, width = 50, height = 50)
#Wlan Symbol
imgWlan = tk.PhotoImage(file = relativPath + '\\images\\wlan_disconnected.gif')
lbWlan = tk.Label(parent, image = imgWlan)
lbWlan.place(x = 650, y = 0, width = 50, height = 50)
#USB Symbol
imgUSB = tk.PhotoImage(file = relativPath + '\\images\\usb_disconnected.gif')
lbUSB = tk.Label(parent, image = imgUSB)
lbUSB.place(x = 750, y = 0, width = 50, height = 50)
###Hauptfenster
##Commandos
def RadioBT():
pass
def USBBT():
pass
def BluetoothAudioBT():
pass
def BluetoothBT():
pass
def NavigationBT():
pass
def EinstellungenBT():
pass
#Radio Button
btRadio = tk.Button(parent, text = 'Radio', command = RadioBT)
btRadio.place(x = 50, y = 125, width = 350, height = 75)
#USB Button
btUSB = tk.Button(parent, text = 'USB', command = USBBT)
btUSB.place(x = 50, y = 225, width = 300, height = 75)
#Bluetooth Audio Button
btBluetoothAudio = tk.Button(parent, text = 'Bluetooth Audio', command = BluetoothAudioBT)
btBluetoothAudio.place(x = 50, y = 325, width = 350, height = 75)
#Bluetooth Button
btBluetooth = tk.Button(parent, text = 'Bluetooth', command = BluetoothBT)
btBluetooth.place(x = 400, y = 125, width = 350, height = 75)
#Navigation Button
btNavigation = tk.Button(parent, text = 'Navigation', command = NavigationBT)
btNavigation.place(x = 450, y = 225, width = 300, height = 75)
#Einstellungen Button
btRadio = tk.Button(parent, text = 'Einstellungen', command = EinstellungenBT)
btRadio.place(x = 400, y = 325, width = 350, height = 75)
root = tk.Tk()
GUI(root)#.pack(side="top", fill="both", expand=True)
root.mainloop()
Re: Tkinter als Class - Bilder werden NICHT angezeigt
Verfasst: Samstag 5. November 2016, 21:21
von BlackJack
@tomtombusiness: Du hast das nicht wirklich als Klasse gebaut. Die hat ja nur eine `__init__()`-Methode. Damit ist das keine sinnvolle Klasse sondern einfach nur eine zu komplex geschriebene Funktion.
Die Namensschreibweise halten sich nicht an den
Style Guide for Python Code. Zudem sind diese abgekürzten Typpräfixe sehr unschön. Bei Schlüsselwordargumenten werden üblicherweise auch keine Leerzeichen um das ``=`` gesetzt.
`place()` sollte man nicht verwenden. Selbst wenn die GUI insgesamt eine feste Grösse hat, sollte man die Positionen und Grössen nicht per Hand ausrechnen und setzen.
Python weiss nichts darüber wie lange Bilder auf der Tk-Seite tatsählich benötigt werden. Wenn also die lokalen Namen für die `PhotoImage`-Objekte nach dem Ende der `__init__()`-Methode nicht mehr existieren, kann die automatische Speicherverwaltung von Python zuschlagen und die Bilddaten aus dem Speicher freigeben. Du musst also dafür sorgen, dass auf Python-Seite die Objekte erreichbar bleiben. Zum Beispiel in dem Du sie als Attribute an das `GUI`-Exemplar bindest.
Re: Tkinter als Class - Bilder werden NICHT angezeigt
Verfasst: Samstag 5. November 2016, 21:37
von tomtombusiness
die Bindung über self.xxxxx funktioniert auch nicht.
Ich bin auch kein python experte. eigendlich eher visual Basic.
Ich arbeite deswegen mit festen Positionen weil des einfacher für mich ist. weil die bildschirmgröße wird für immer fest bleiben.
Ansich baue ich mir das design immer erst mit vb vor und schreibe mir die Positionen raus. ist für mich einfacher.
Ich kam und die Idee mit der class weil ich zufällig mal darüber gelesen habe. das war aber dann auch alles.
Python habe ich sonst nur als kleines Scripting benutzt
Re: Tkinter als Class - Bilder werden NICHT angezeigt
Verfasst: Samstag 5. November 2016, 21:57
von Sirius3
@tomtombusiness: Du verwirfst die Bilder gleich wieder, weil Du die Instanz Deiner GUI-Klasse an keine Variable bindest. Warum erzeugst Du eigentlich ein Frame-Objekt, wenn Du es nicht nutzt?
Re: Tkinter als Class - Bilder werden NICHT angezeigt
Verfasst: Samstag 5. November 2016, 22:00
von tomtombusiness
ich verstehe es nicht.
Bitte um ausführlichere Hilfestellung

Re: Tkinter als Class - Bilder werden NICHT angezeigt
Verfasst: Samstag 5. November 2016, 22:46
von tomtombusiness
ich habs. Place ist in der art wohl nicht nutzbar.
nutze ich stattdessen pack oder grid funktioniert es einwandfrei.
Muss man auch erstmal drauf kommen.
Dennoch für weitere vorschläge und co bin ich gerne offen
Re: Tkinter als Class - Bilder werden NICHT angezeigt
Verfasst: Samstag 5. November 2016, 23:15
von tomtombusiness
Bäms alter ich habs gefunden!!!
Also das eigendliche Problem war der Layoutmanager. Ich habe immer grid und pack bzw pack und place versucht zu verbinden. Die Frame wurde mit pack initialisiert aber alles ander mit place dargestellt. Das funktioniert nicht.
Aktueller Code für andere Leutz
Code: Alles auswählen
try:
#~~ For Python 2.x
from Tkinter import *
except ImportError:
#~~ For Python 3.x
from tkinter import *
import os
relativPath = os.path.abspath('.')
class Application(Frame):
def __init__(self, master):
Frame.__init__(self, master)
frame = Frame(master)
#frame.pack()
#self.grid()
frame.place(x = 0, y = 0, width = 800, height = 480)
###Oberes Panel
#Uhrzeit und Datum
self.lbDayTime = Label(frame, text = 'Uhrzeit')
self.lbDayTime.place(x = 50, y = 0, height = 50)
#Bluetooth Symbol
self.imgBluetooth = PhotoImage(file = relativPath + '\\images\\bluetooth_disconnected.gif')
self.lbBluetooth = Label(frame, image = self.imgBluetooth)
self.lbBluetooth.place(x = 550, y = 0, width = 50, height = 50)
#Wlan Symbol
self.imgWlan = PhotoImage(file = relativPath + '\\images\\wlan_disconnected.gif')
self.lbWlan = Label(frame, image = self.imgWlan)
self.lbWlan.place(x = 650, y = 0, width = 50, height = 50)
#USB Symbol
self.imgUSB = PhotoImage(file = relativPath + '\\images\\usb_disconnected.gif')
self.lbUSB = Label(frame, image = self.imgUSB)
self.lbUSB.place(x = 750, y = 0, width = 50, height = 50)
###Hauptfenster
##Commandos
def RadioBT(self):
pass
def USBBT(self):
pass
def BluetoothAudioBT(self):
pass
def BluetoothBT(self):
pass
def NavigationBT(self):
pass
def EinstellungenBT(self):
pass
#Radio Button
self.btRadio = Button(frame, text = 'Radio', command = RadioBT)
self.btRadio.place(x = 50, y = 125, width = 350, height = 75)
#USB Button
self.btUSB = Button(frame, text = 'USB', command = USBBT)
self.btUSB.place(x = 50, y = 225, width = 300, height = 75)
#Bluetooth Audio Button
self.btBluetoothAudio = Button(frame, text = 'Bluetooth Audio', command = BluetoothAudioBT)
self.btBluetoothAudio.place(x = 50, y = 325, width = 350, height = 75)
#Bluetooth Button
self.btBluetooth = Button(frame, text = 'Bluetooth', command = BluetoothBT)
self.btBluetooth.place(x = 400, y = 125, width = 350, height = 75)
#Navigation Button
self.btNavigation = Button(frame, text = 'Navigation', command = NavigationBT)
self.btNavigation.place(x = 450, y = 225, width = 300, height = 75)
#Einstellungen Button
self.btRadio = Button(frame, text = 'Einstellungen', command = EinstellungenBT)
self.btRadio.place(x = 400, y = 325, width = 350, height = 75)
root = Tk()
root.geometry('800x480+0+0')
root.fullscreen = True
app = Application(root)#.pack(side="top", fill="both", expand=True)
root.mainloop()
Re: Tkinter als Class - Bilder werden NICHT angezeigt
Verfasst: Sonntag 6. November 2016, 12:03
von wuf
Hi tomtombusiness
Hier noch eine Prototyp-Variante zum experimentieren:
Code: Alles auswählen
#!/usr/bin/env python
# -*- coding: utf-8 -*-
import os
from functools import partial
try:
# Tkinter for Python 2.xx
import Tkinter as tk
except ImportError:
# Tkinter for Python 3.xx
import tkinter as tk
APP_TITLE = "Application"
APP_XPOS = 0
APP_YPOS = 0
APP_WIDTH = 800
APP_HEIGHT = 480
INDICATOR_IMAGES = [
'bluetooth_disconnected.gif'
'wlan_disconnected.gif'
'usb_disconnected.gif']
BUTTONS = [
['Radio', 'Bluetooth'],
['USB', 'Navigation'],
['Bluetooth Audio', 'Einstellungen']]
BUTTON_HEIGHT = 5 #Characters
BUTTON_WIDTH = 20 #Characters
PATH_FOR_IMAGES = os.path.join(os.path.abspath('.'), 'images') + os.sep
class Application(tk.Frame):
def __init__(self, master):
self.master = master
self.master.protocol("WM_DELETE_WINDOW", self.close)
tk.Frame.__init__(self, master)
self.indicator_images = list()
self.indicators = list()
self.header_frame = tk.Frame(self)
self.header_frame.pack(fill='x', pady=4)
self.label_day_time = tk.Label(self.header_frame, text='Uhrzeit')
self.label_day_time.pack(side='left')
# Indicators:
self.indicator_frame = tk.Frame(self.header_frame)
self.indicator_frame.pack(side='right')
for image_name in INDICATOR_IMAGES:
image = tk.PhotoImage(file=PATH_FOR_IMAGES + image_name)
self.indicator_images.append(image)
self.label = tk.Label(self.indicator_frame,image=image)
self.label.pack(side='left')
self.indicators.append(self.label)
# Buttons:
self.frame_button_array = tk.Frame(self)
self.frame_button_array.pack()
for row, button_pair in enumerate(BUTTONS):
for column, button_name in enumerate(button_pair):
tk.Button(self.frame_button_array, text=button_name,
height=BUTTON_HEIGHT, width=BUTTON_WIDTH,
command=partial(self.button_callback, button_name)).grid(
column=column, row=row)
self.flash_indicator(0)
def flash_indicator(self, indicator_index, flash_state='disabled'):
self.indicators[indicator_index]['state'] = flash_state
flash_state = 'normal' if flash_state == 'disabled' else 'disabled'
print(flash_state)
self.after(500, self.flash_indicator, indicator_index, flash_state)
def button_callback(self, button_name):
print(button_name)
def close(self):
print("Application-Shutdown")
self.master.destroy()
def main():
app_win = tk.Tk()
app_win.title(APP_TITLE)
app_win.geometry("+{}+{}".format(APP_XPOS, APP_YPOS))
app_win.geometry("{}x{}".format(APP_WIDTH, APP_HEIGHT))
app = Application(app_win).pack(expand=True, anchor='nw', padx=10, pady=6)
app_win.mainloop()
if __name__ == '__main__':
main()
Gruss wuf

Re: Tkinter als Class - Bilder werden NICHT angezeigt
Verfasst: Sonntag 6. November 2016, 15:53
von Sirius3
@wuf: bei INDICATOR_IMAGES fehlen ein paar Kommas. Der PATH_FOR_IMAGES will wahrscheinlich relativ zur Programmdatei und nicht zum aktuellen Pfad sein. Pfade sollten immer mit os.path.join zusammengesetzt werden. Nicht alles muß an Attribute gebunden werden, vor allem nicht ein einer for-Schleife.
Code: Alles auswählen
INDICATOR_IMAGES = [
'bluetooth_disconnected.gif',
'wlan_disconnected.gif',
'usb_disconnected.gif',
]
PATH_FOR_IMAGES = os.path.abspath(os.path.join(os.path.dirname(__file__), 'images'))
[...]
for image_name in INDICATOR_IMAGES:
image = tk.PhotoImage(file=os.path.join(PATH_FOR_IMAGES, image_name))
self.indicator_images.append(image)
label = tk.Label(self.indicator_frame,image=image)
label.pack(side='left')
self.indicators.append(label)
[...]
Re: Tkinter als Class - Bilder werden NICHT angezeigt
Verfasst: Sonntag 6. November 2016, 16:56
von tomtombusiness
alter
Also vielen dank für die Unterstützung. werde es mir geauer anschauen was genau passiert ist.
Re: Tkinter als Class - Bilder werden NICHT angezeigt
Verfasst: Sonntag 6. November 2016, 17:44
von wuf
Hi Sirius3
Besten Dank für deine Hinweise. Die Kommas gingen beim Austausch meiner Bilddateinamen durch die von tomtombusiness verloren. Der Hinweis betreffs dem Pfad
PATH_FOR_IMAGES verwirrte mich ein wenig. Aber das genauere hinschauen und ausprobieren brachte die Entwirrung. Das mit den Attribute ist auch klar. Habe deine Vorschläge in mein Skript übernommen.
Gruss wuf
