Neue GUI-Seiten

Fragen zu Tkinter.
Antworten
Martino
User
Beiträge: 1
Registriert: Montag 27. März 2023, 07:24

Hallo,
Ich bin neu im Forum und in meinem hohen Pensionsalter habe ich noch eine Aufgabe gefasst, welche ich mit einem Raspi und Python lösen möchte.
Es handelt sich um ein Sortiergerät, welches ich mit einem Touchscreen
und einem GUI lösen möchte.
Um die einzelnen Sortiergrössen einzugeben, beabsichtige ich, jeweils diese
je auf einer Seite beim GUI einzugeben um damit eine bessere Übersicht
und eine korrekte Abfolge der Eingabe zu erstellen.
Nun mein Problem.
Eine erste Seite kann ich erstellen, jedoch ist mir nicht klar, wie ich die weiteren Seiten Programmieren kann. Wie ist es bei Python. Wird eine neues Skript erstellt und anschliessend entsprechen aufgerufen, oder wird die am Grundskript angehängt?
Auch ist mir die Programmierung nicht bekannt, da ich keine Literatur gefunden habe.
Jede Hilfe ist mir willkommen, besten Dank hierfür.

Hier mein bisher erstellte Skript.

import tkinter as tk
from pathlib import Path
from functools import partial
import json

SORTIERUNG = Path("sortier-einstellung.json")

def auswerte_nusssortierungen(nuss):      
    if SORTIERUNG.exists():        
        with SORTIERUNG.open() as input:
            stellungen = json.load(input)
        for key, value in stellungen.items():
            nuss[key].set(value)
   
def schreibe_datei(nuss):
    with SORTIERUNG.open("w") as output:
        json.dump({k: v.get() for k,v in nuss.items()}, output)

def gui():
    master = tk.Tk()
    nuss = {
         "#030303": tk.IntVar(),
 
    }
   
    master.title("MASTER      SORTIERUNG")
    master.geometry ("650x700+600+200")


    for row, (color, erka) in enumerate(nuss.items()):    # erste Spalte
       

        frame = tk.Frame(master, width=400, height=150, ) #Frame als Platzhalter vom oberen Rand
        frame.grid(row=1, column=0, padx=3, pady=3)

        frame = tk.Frame(master, width=400, height=150, background=color) #Frame links
        frame.grid(row=2, column=0, padx=3, pady=3)
        frame = tk.Frame(master, width=260, height=115, background="#ffffff") #Frame rechts mit Slider
        frame.grid(row=2, column=0, padx=3, pady=3)
        label = tk.Label(master, textvariable=erka,
            font="Verdana 47 bold italic", bg="#ffffff")#Grundfarbe Ziffer
        label.grid(row=2, column=0, pady=4, padx=4)

       
        frame = tk.Frame(master, width=5, height=150, background="Grey")# zweite Spalte Grundgroesse
        frame.grid(row=2, column=1, padx=3, pady=3)
       
       
        frame = tk.Frame(master, width=800, height=150, background=color)# dritte Spalte breite
        frame.grid(row=2, column=2, padx=4, pady=4)

        scale = tk.Scale(master, from_=0, to=100, bg=color, resolution=10,  #Slider
                  orient='horizontal', length=680, width=40, sliderlength=40,
                  showvalue=0, label="             Position 2",
                  font = "Verdana 30 bold italic", fg = "#ffff00",
                  variable=erka)
        scale.grid(row=2, column=2, padx=3, pady=3)


    frame = tk.Frame(master, width=400, height=150, ) #Frame Platzhalter nach Slider
    frame.grid(row=4, column=0, padx=3, pady=3)



    tk.Button(master, text='     OK und weiter         ',
              command=partial(schreibe_datei, nuss),
              bg="orange",bd=4).grid(columnspan=3, row=6)


   
    auswerte_nusssortierungen(nuss)
    tk.mainloop()

if __name__ == "__main__":
    gui()
_Scaui
User
Beiträge: 11
Registriert: Montag 17. April 2023, 19:47
Kontaktdaten:

@Martino: Ich verstehe dein Problem nicht so recht, aber vieleicht hilft dir folgende Seite:
https://www.pythontutorial.net/tkinter/tkraise/
juwido
User
Beiträge: 20
Registriert: Donnerstag 15. Dezember 2022, 13:41

Hallo, suchst Du eventuell tk.Toplevel(master)...?
Benutzeravatar
grubenfox
User
Beiträge: 433
Registriert: Freitag 2. Dezember 2022, 15:49

und bei PySimpleGui (https://www.pysimplegui.org/) gibt es auf dieser Seite https://www.pysimplegui.org/en/latest/cookbook/

irgendwo unten einen Eintrag: "Recipe Multiple Windows - read_all_windows"


Könnte der helfen?
Benutzeravatar
__blackjack__
User
Beiträge: 13122
Registriert: Samstag 2. Juni 2018, 10:21
Wohnort: 127.0.0.1
Kontaktdaten:

@Martino: Anmerkungen zum Quelltext: Man sollte keine kryptischen Abkürzungen als Namen verwenden. Wass soll `nuss` und `erka` bedeuten? Namen sollen dem Leser vermitteln was die Werte bedeuten, nicht zum rätseln zwingen.

Fenstergrösse & Position gibt man nicht fest vor. Das mag auf dem System wo es entwickelt wird funktionieren, aber auf anderen Systemen mit anderen Bildschirmgrössen, -auflösungen, und Einstellungen kann das falsch aussehen oder gar unbrauchbar sein. So sieht das bei mir beispielsweise aus, da verschwindet ein Grossteil der GUI weil rechts nicht alles ins Fenster passt:
Bild

Leere Frames mit absoluten Pixelgrössen, teilweise zusätzlich zu anderen Widgets, in Grid-Zellen zu platzieren, um die Grössen absolut festzulegen ist ebenfalls nicht sinnvoll. Die (sinnvollen) GUI-Elemente haben ja selbst eine Grösse, die bereits für ausreichend Platz im Layout sorgt.

Die ``for``-Schleife in der Hauptfunktion macht keinen Sinn bei einem Wörterbuch mit genau einem Schlüssel/Wert-Paar und mit mehr kommt die Schleife auch nicht klar, weil dann alles in die selben Grid-Zellen gesteckt würde.

In `auswerte_nusssortierungen()` wird nicht wirklich etwas ausgewertet sondern Werte aus einer Datei geladen. Das ist die Gegenfunktion von `schreibe_datei()`, worauf man durch den Namen nie kommen würde.

Falls die Datei nicht existiert, macht die Funktion einfach gar nichts. Das ist keine sinnvolle API wenn der Aufrufer so etwas nicht mitbekommen kann. Da sollte man einfach die Ausnahme auslösen lassen die beim öffnen einer nicht existierenden Datei kommt. Falls der Aufrufer das dann einfach ignorieren möchte, kann er das ja machen.

Beim öffnen von Textdateien sollte man immer explizit die Kodierung angeben. Das ist bei JSON-Dateien wichtig, weil die UTF-8 kodiert sein sollten. Immer. Beim Lesen kann man etwas offener sein, und die Datei im Binärmodus öffnen. Die Dekodierung übernimmt dann das `json`-Modul und kann UTF-*-Kodierungen selbstständig erkennen.

`input` ist der Name einer eingebauten Funktion, den sollte man nicht an eine Datei binden.

Zwischenstand (ungetestet):

Code: Alles auswählen

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

SORTIER_EINSTELLUNG_DATEI_PFAD = Path("sortier-einstellung.json")


def lese_datei(color_to_erka_var):
    with SORTIER_EINSTELLUNG_DATEI_PFAD.open("rb") as file:
        for color, erka_var in json.load(file).items():
            color_to_erka_var[color].set(erka_var)


def schreibe_datei(color_to_erka_var):
    with SORTIER_EINSTELLUNG_DATEI_PFAD.open("w", encoding="utf-8") as file:
        json.dump(
            {
                color: erka_var.get()
                for color, erka_var in color_to_erka_var.items()
            },
            file,
        )


def main():
    root = tk.Tk()
    color_to_erka_var = {"#030303": tk.IntVar()}

    root.title("MASTER SORTIERUNG")
    assert len(color_to_erka_var) == 1, "following loop doesn't work with more"
    for color, erka in color_to_erka_var.items():
        tk.Label(
            root,
            textvariable=erka,
            width=4,
            font="Verdana 47 bold italic",
            bg="white",
        ).grid(row=0, column=0, pady=4, padx=4)
        tk.Scale(
            root,
            from_=0,
            to=100,
            bg=color,
            resolution=10,
            orient=tk.HORIZONTAL,
            length=680,
            width=40,
            sliderlength=40,
            showvalue=False,
            label="Position 2",
            font="Verdana 30 bold italic",
            fg="yellow",
            variable=erka,
        ).grid(row=0, column=1, padx=3, pady=3)

    tk.Button(
        root,
        text="OK und weiter",
        command=partial(schreibe_datei, color_to_erka_var),
        bg="orange",
        bd=4,
    ).grid(columnspan=3, row=6)

    try:
        lese_datei(color_to_erka_var)
    except FileNotFoundError:
        pass  # Intentionally ignored.

    root.mainloop()


if __name__ == "__main__":
    main()
Mehrere ”Seiten” kann man entweder mit einem `tkinter.ttk.Notebook` erstellen, falls es okay ist, das man Reiter hat, mit denen der Benutzer zwischen den Seiten umschalten kann. Oder man bastelt sich selber etwas mit einem Grid-Layout, wo man mehrere Frames in die selbe Zelle steckt und mit `tkraise()` immer die gewünschte in den Vordergrund holt. Dazu hat _Scaui ja bereits einen Link gepostet.
„All religions are the same: religion is basically guilt, with different holidays.” — Cathy Ladman
Antworten