Tortengrafik verbergen

Fragen zu Tkinter.
Antworten
Benutzeravatar
Cybernuschel
User
Beiträge: 12
Registriert: Donnerstag 12. Mai 2022, 13:39

Hallo Allerseits,

ich habe da ein kleines Problem. In dem folgenden Code wird eine einfache Tortengrafik mit zwei Farben erstellt. Ich möchte die Torte in bestimmten Fällen unsichtbar machen, später soll sie wieder erscheinen. Kann mir da jemand auf die Sprünge helfen?

Vielen Dank

Gruß Cybernuschel

Code: Alles auswählen

import tkinter as tk

# Werte für die Tortengrafik
values = [30, 70]  # Anteile in Prozent
colors = ["red", "green"]  # Farben

# Tortengrafik zeichnen
def draw_pie_chart(canvas, data, colors, center, radius):
    start_angle = 0
    for i, value in enumerate(data):
        extent = 360 * (value / 100)
        canvas.create_arc(
            center[0] - radius, center[1] - radius,
            center[0] + radius, center[1] + radius,
            start=start_angle, extent=extent,
            fill=colors[i]
        )
        start_angle += extent

# Hauptfenster erstellen

root = tk.Tk()
root.title('Torte')
canvas = tk.Canvas(root, width = 600, height = 330, bg ="#F0FFFF")
canvas.grid()

# Tortengrafik anzeigen
draw_pie_chart(canvas, values, colors, (150, 200), 100) # Position x, Position y, Durchmesser

root.mainloop()
SpaceX ist das Lieblingsspielzeug von Elon Musk!
Python ist das Lieblingsspielzeug von mir!
Beides ist gleich spannend!
Benutzeravatar
DeaD_EyE
User
Beiträge: 1273
Registriert: Sonntag 19. September 2010, 13:45
Wohnort: Hagen
Kontaktdaten:

Leider hat tkinter kein show/hide, also muss man sich das selbst programmieren.
Jedenfalls ist diese Methode nicht so schön, weil alle vorherigen Widgets nachrücken, wenn das Canvas widget ausgeblendet wird.

Hier mal ein Beispiel:

Code: Alles auswählen

import tkinter as tk


def draw_pie_chart(
    root: tk.Tk,
    data: list[int],
    colors: list[str],
    center: tuple[int, int],
    radius: int,
) -> tk.Canvas:
    canvas = tk.Canvas(root, width=600, height=330, bg="#F0FFFF")

    start_angle = 0.0

    for i, value in enumerate(data):
        extent = 360 * (value / 100)
        canvas.create_arc(
            center[0] - radius,
            center[1] - radius,
            center[0] + radius,
            center[1] + radius,
            start=start_angle,
            extent=extent,
            fill=colors[i],
        )
        start_angle += extent

    return canvas


def toggle_visible(widget: tk.Widget):
    active = True
    info = widget.grid_info()

    def inner():
        nonlocal active

        if active:
            active = False
            widget.grid_forget()
        else:
            active = True
            widget.grid(**info)

    return inner


def main() -> None:
    values = [30, 70]
    colors = ["red", "green"]

    root = tk.Tk()
    root.title("Torte")
    canvas = draw_pie_chart(root, values, colors, center=(150, 200), radius=100)
    canvas.grid(row=1, column=1, columnspan=2)

    tk.Button(root, text="Toggle", command=toggle_visible(canvas)).grid(row=2, column=1)
    tk.Button(root, text="Exit", command=root.destroy).grid(row=2, column=2)

    root.mainloop()


if __name__ == "__main__":
    main()

sourceserver.info - sourceserver.info/wiki/ - ausgestorbener Support für HL2-Server
Benutzeravatar
__blackjack__
User
Beiträge: 14178
Registriert: Samstag 2. Juni 2018, 10:21
Wohnort: 127.0.0.1
Kontaktdaten:

@Cybernuschel: Was genau meinst Du denn damit das die Torte unsichtbar werden soll? DeaD_EyE hat gezeigt wie man den gesamten `Canvas` aus der GUI nehmen und wieder einfügen kann. Man kann aber auch Objekte auf dem Canvas verstecken und wieder sichtbar machen. Damit man das nicht für jedes Tortenstück einzeln machen muss, kann man Objekten auf dem Canvas auch ein gemeinsames „tag“ geben und die dann darüber ansprechen.

Der Index `i` wird übrigens nicht wirklich gebraucht, denn was man da ja eigentlich will, ist parallel über die beiden Sequenzen iterieren. Dafür gibt es die `zip()`-Funktion.

Code: Alles auswählen

#!/usr/bin/env python3
import tkinter as tk


def draw_pie_chart(canvas, data, colors, center, radius, tag):
    x, y = center
    start_angle = 0
    for value, color in enumerate(data, colors):
        extent = 360 * (value / 100)
        canvas.create_arc(
            x - radius,
            y - radius,
            x + radius,
            y + radius,
            start=start_angle,
            extent=extent,
            fill=color,
            tag=tag,
        )
        start_angle += extent


class MainWindow(tk.Tk):
    CHART_TAG = "chart"

    def __init__(self, values, colors):
        tk.Tk.__init__(self)
        self.is_chart_visible = True
        self.title("Torte")
        self.canvas = tk.Canvas(self, width=600, height=330, bg="#F0FFFF")
        self.canvas.pack()
        draw_pie_chart(
            self.canvas, values, colors, (150, 200), 100, self.CHART_TAG
        )
        tk.Button(self, text="Toggle", command=self.toggle_chart).pack()

    def toggle_chart(self):
        self.is_chart_visible = not self.is_chart_visible
        self.canvas.itemconfigure(
            self.CHART_TAG,
            state=tk.NORMAL if self.is_chart_visible else tk.HIDDEN,
        )


def main():
    values = [30, 70]  # Anteile in Prozent.
    assert sum(values) == 100
    colors = ["red", "green"]
    window = MainWindow(values, colors)
    window.mainloop()


if __name__ == "__main__":
    main()
“Every thinking person fears nuclear war and every technological nation plans for it. Everyone knows
it's madness, and every country has an excuse.” — Carl Sagan, Cosmos, Episode 13: Who Speaks for Earth?
Benutzeravatar
Cybernuschel
User
Beiträge: 12
Registriert: Donnerstag 12. Mai 2022, 13:39

Erstmal vielen Dank für die beiden schnellen Antworten, ich wollte die gesamte Torte am Ort lassen jedoch verbergen und später wieder sichtbar machen.
Übrigens __blackjack__User dein Code verursacht bei mir leider einen Fehler.
Auf jeden sehe ich ein klein wenig klarer, habe das Problem aber noch nicht gelöst. Ich hatte tatsächlich gehofft, dass es so etwas wie ein show/hide gibt.
Vielleicht verdecke ich auch die ganze Torte durch ein Viereck.
SpaceX ist das Lieblingsspielzeug von Elon Musk!
Python ist das Lieblingsspielzeug von mir!
Beides ist gleich spannend!
Sirius3
User
Beiträge: 18307
Registriert: Sonntag 21. Oktober 2012, 17:20

Wenn Du bei einem Fehler nicht weiter kommst, bitte poste hier die komplette Fehlermeldung und den dazugehörigen Code.
In Deinem Fall hat __blackjack__ `enumerate` mit `zip` verwechselt, was ein einfach zu behebender Fehler ist.
Ansonsten tut der Code exakt das, was Du möchtest.
Antworten