Wie binde ich Bilder ein?

Fragen zu Tkinter.
Antworten
saddoorbell
User
Beiträge: 1
Registriert: Dienstag 24. Mai 2022, 15:51

Hi,
ich habe jetzt mehrere Tage lang im Internet gesucht, verschiedene Lösungsversuche ausprobiert und bin immer noch zu keinem Ergebnis gekommen. Ich kann einfach nicht programmieren, verstehe nicht was die ganzen Tutorials von mir wollen oder wo meine Fehler liegen. Aber der Lehrer möchte leider trotzdem ein Endergebnis sehen. Also, hier mein Projekt:
Ein Kalender mit 30 Türchen. Also ein Fenster mit 30 (ich hab hier jetzt mal nur zwei reinkopiert) Buttons, welche jeweils ein neues Fenster öffnen, welches dann ein Bild zeigt. Die Buttons funktionieren alle einwandfrei, soweit habe ich es alleine geschafft. Aber jetzt kriege ich es einfach nicht hin, dass das neue Fenster ein Bild ein Bild zeigt. Falls mir das irgendwer erklären kann/möchte, dann bitte in absoluter Anfängersprache. Ich verstehe einfach nicht was ich hier mache..

Code: Alles auswählen

from tkinter import *
from tkinter.ttk import *


# Erzeugung des Fensters
tkFenster = Tk()
tkFenster.title("Junikalender 2022")
tkFenster.geometry("720x650")

# Label mit Überschrift 
labelUeberschriftKalenderHintergrund = Label(master=tkFenster,
                               text="",
                               background="white",
                               font=("calibri", 25))
labelUeberschriftKalenderHintergrund.place(x=10, y=6, width=700, height=630)
# Label mit Überschrift 
labelUeberschriftKalender = Label(master=tkFenster,
                               text="Junikalender 2022",
                               background="#B0EAEA",
                               font=("calibri", 25,))
labelUeberschriftKalender.place(x=18, y=14, width=680, height=70) 
 
# Erzeugung eines neuen Fensters (1.)
def openNewWindow():
     
    newWindow = Toplevel(tkFenster)
 
    newWindow.title("1.")
 
    newWindow.geometry("200x200")
 
    Label(newWindow,
          text ="1.").pack()


# Button zum Öffnen eines neuen Fensters (1.)
btn = Button(tkFenster,
             text ="1.",
             command = openNewWindow)
btn.pack(pady = 10)
btn.place(x = 20, y = 100)



# Erzeugung eines neuen Fensters (2.)
def openNewWindow():
     
    newWindow = Toplevel(tkFenster)
 
    newWindow.title("2.")
 
    newWindow.geometry("200x200")
 
    Label(newWindow,
          text ="2.").pack()
 
 
# Button zum Öffnen eines neuen Fensters (2.)
btn = Button(tkFenster,
             text ="2.",
             command = openNewWindow)
btn.pack(pady = 10)
btn.place(x = 170, y = 100)

# Aktivierung des Fensters
tkFenster.mainloop()
Benutzeravatar
peterpy
User
Beiträge: 188
Registriert: Donnerstag 7. März 2013, 11:35

Hallo saddoorbell,

wo soll ich anfangen?
Du weisst dass hier keine Hausaufgaben gelöst werden.
Wenn Du dein Projekt mit dem Kalender weiter verfolgen willst, kommst Du um Tutorials nicht herum.
Und im Netz Code suchen und zusammensetzen ist, meiner Meinung nach, auch nicht zielführend.
Nebenbei bemerkt, wenn Du von dir sagst, Du könntest nicht programmieren, ist dein Projekt schon recht anspruchsvoll.
Dein Projekt verlangt nach einer Klasse, also solltest Du dich auch über Python Klassen schlau machen..
Z.B. hier:https://docs.python.org/3.7/tutorial/index.html, https://docs.python.org/3/library/tkint ... -variables
Und zu Tkinterhttps://docs.python.org/3/library/tk.html

Was hier immer wieder gepredigt wird, als Zitat:
__blackjack__ hat geschrieben: Montag 18. April 2022, 14:04 Auf Modulebene gehört nur Code der Konstanten, Funktionen, und Klassen definiert. Das Hauptprogramm steht üblicherweise in einer Funktion die `main()` heisst.
Sternchen-Importe sind Böse™. Da holt man sich gerade bei `tkinter` fast 140 Namen ins Modul von denen nur ein kleiner Bruchteil verwendet wird. Auch Namen die gar nicht in `tkinter` definiert werden, sondern ihrerseits von woanders importiert werden. Das macht Programme unnötig unübersichtlicher und fehleranfälliger und es besteht die Gefahr von Namenskollisionen.

Namen werden in Python klein_mit_unterstrichen geschrieben. Ausnahmen sind Konstanten (KOMPLETT_GROSS) und Klassen (PascalCase).
https://pep8.org/.
Was für Bilder willst Du einbinden? Für die Formate .gif, .pgm, .ppm gibt's in Tkinter die Klasse Photoimage, für .xbm Image. Für andere Formate ist das Packet PIL zuständig.

Gruss Peter
Benutzeravatar
__blackjack__
User
Beiträge: 13003
Registriert: Samstag 2. Juni 2018, 10:21
Wohnort: 127.0.0.1
Kontaktdaten:

@saddoorbell: Ergänzend zu peterpy: seit Tk 8.6 sollte `PhotoImage` auch PNG können/kennen.

Von `geometry()`-Aufrufen und `place()` solltest Du auch die Finger lassen. Widgets ordnet man mit `pack()` oder `grid()` an, dann ergibt sich die Fenstergrösse automatisch aus dem Inhalt der im Fenster angezeigt wird und man bekommt keine Problem mit unterschiedlichen Bildschirmgrössen/-auflösungen/-Einstellungen.

Man schreibt oder kopiert auch nicht fast den gleichen Code 30 mal. Im Gegenteil: man vermeidet beim Programmieren bewusst das wiederholen von Code und Daten. Dafür gibt es Schleifen und/oder die Möglichkeit Funktionen/Methoden zu parametrisieren. Warum man keinen Code oder Daten wiederholen sollte, kann man an Deinem Beispiel schon sehen: Nach `pack()` noch `place()` macht keinen Sinn. Das müsste man jetzt 30 mal aus dem Code entfernen wenn man das 30 mal kopiert hat. Das macht unnötig Arbeit und ist fehleranfällig, weil man bei 30 Änderungen auch 30 mal die ”Chance” hat etwas falsch zu machen.

Namen sollten keine kryptischen Abkürzungen enthalten, oder gar nur daraus bestehen. Wenn man `button` meint, sollte man nicht nur `btn` schreiben. Und man sollte mehrere Worte in einem Namen auch in der richtigen Reihenfolge schreiben, weil das sonst nicht so flüssig lesbar ist, und in vielen Fällen auch die Bedeutung verändert.
`label_ueberschrift_kalender` ist beispielsweise falsch herum. Das ist ein `kalenderueberschrift_label`.

Kommentare sollen dem Leser einen Mehrwert über den Code geben. Faustregel: Kommentare beschreiben nicht *was* der Code macht, denn das steht da bereits als Code, sondern warum er das macht. Sofern das nicht offensichtlich ist. Offensichtlich ist in aller Regel auch was in der Dokumentation von Python und den verwendeten Bibliotheken steht.
“Most people find the concept of programming obvious, but the doing impossible.” — Alan J. Perlis
Benutzeravatar
__blackjack__
User
Beiträge: 13003
Registriert: Samstag 2. Juni 2018, 10:21
Wohnort: 127.0.0.1
Kontaktdaten:

Lösung die `babel` für Monatsnamen und (abgekürzte) Tagesnamen verwendet:

Code: Alles auswählen

#!/usr/bin/env python3
import tkinter as tk
from calendar import monthcalendar
from functools import partial
from pathlib import Path

import babel

SELF_PATH = Path(__file__).parent

YEAR, MONTH = 2022, 6

WEEKDAY_TEXT_COLOR = "black"
SUNDAY_TEXT_COLOR = "red"


def get_color_for_day_index(index):
    if not 0 <= index <= 6:
        raise ValueError(f"index {index!r} out of range")

    return SUNDAY_TEXT_COLOR if index == 6 else WEEKDAY_TEXT_COLOR


def create_day_window(day):
    window = tk.Toplevel()
    title_text = f"{day}."
    window.title(title_text)
    tk.Label(window, text=title_text).pack()
    #
    # TODO Load an image dependend on the value of `day`.
    #
    image = tk.PhotoImage(file=SELF_PATH / "test.png")
    window.image = image  # Neccessary too keep a reference to the image.
    tk.Label(window, image=image).pack()
    return window


def create_main_window(year, month):
    root = tk.Tk()
    locale = babel.Locale("de_DE")
    month_name = locale.months["stand-alone"]["wide"][month]
    title_text = f"{month_name}kalender {year}"
    root.title(title_text)
    tk.Label(root, text=title_text, background="#B0EAEA").pack(fill=tk.X)

    days_frame = tk.Frame(root)

    day_names = locale.days["stand-alone"]["abbreviated"]
    for i in range(7):
        tk.Label(
            days_frame,
            text=day_names[i],
            foreground=get_color_for_day_index(i),
        ).grid(row=0, column=i)

    for row_index, week in enumerate(monthcalendar(year, month), 1):
        for column_index, day in enumerate(week):
            if day:
                tk.Button(
                    days_frame,
                    text=day,
                    foreground=get_color_for_day_index(column_index),
                    command=partial(create_day_window, day),
                ).grid(row=row_index, column=column_index, sticky=tk.NSEW)

    days_frame.pack()

    return root


def main():
    window = create_main_window(YEAR, MONTH)
    window.mainloop()


if __name__ == "__main__":
    main()
Bild
“Most people find the concept of programming obvious, but the doing impossible.” — Alan J. Perlis
Antworten