Scharf Beobachtet

Tech Know How

Mit Python und Tkinter einfache Eingabe-Formulare erstellen

2022-01-16 10:51:55

Wer kennt es nicht – man hat eine Anforderung die zu klein, zu trivial für eine großangelegte Datenhaltung oder Erzeugung ist. Man benötigt für eine Anwendung beispielsweise einen bestimmten View ein paar strukturierte Daten.

Das können Teaser einer bestimmten Zusammenstellung oder aber auch einfach Konfigurationen sein. Schreibt man die von Hand in Json? Ja, zumeist wohl schon.

Was aber wenn der Scope sich so verschieben könnte, das man mittels Oberfläche der eingebenden Person viel Kontextwissen erspart, das diese sonst für eine Erweiterung benötigt hätte?

Dann kommt hier vielleicht ein Lösungsansatz: Python und Tkinter!

Die beiden in Verbindung bringen alles mit, um schnell und effektiv kleine Oberflächen zu erschaffen, deren Eingaben dann in Python verarbeitet werden können. Wie zu dem eingangs aufgezeigten Beispiel von strukturierten Daten. (Und das in unter 100 Zeilen Code, kompilierbar/lauffähig auf Windows, Mac und Linux.)

Denn: über eine vorgegebene Oberfläche lassen sich Flüchtigkeitsfehler stark reduzieren. Auch nachlaufende Tests gegen das Format oder eine sinn-/zweckmäßige Eingabe sind möglich.

Beispiel-Bild der GUI aus Tkinter
Beispiel-Bild der GUI aus Tkinter

Hier der Beispiel-Code, was es benötigt:

main.py

import json
import os
from tkinter import *
from functools import partial

from file_handler import FileHandler


class Form:
    form_title = 'Teaser creator'
    form_size = '400x150'
    blueprint_file = "./form_construction.json"
    blueprint = []

    def __init__(self):
        # window
        self.tkWindow = Tk()
        self.tkWindow.geometry(self.form_size)
        self.tkWindow.title(self.form_title)

        self.create()

    def load_blueprint(self):

        if not os.path.exists(self.blueprint_file):
            print("not found " + self.blueprint_file)
            exit(0)

        with open(self.blueprint_file, encoding='utf-8') as data_file:
            self.blueprint = json.loads(data_file.read())

    def save_form(self, submit_data):
        d = {}
        for n in submit_data:
            d[n] = submit_data[n].get()
        fh = FileHandler()
        fh.add_to_json_file(d)
        print("saved " + d['headline'])
        return

    def create(self):
        self.load_blueprint()
        row_counter = 0
        element_inputs = {}
        for element in self.blueprint:
            Label(self.tkWindow, text=element['label']).grid(row=row_counter, column=0)
            element_inputs[element['name']] = StringVar()
            Entry(self.tkWindow, textvariable=element_inputs[element['name']]).grid(row=row_counter, column=1)
            row_counter = row_counter + 1

        form_fields = partial(self.save_form, element_inputs)
        Button(self.tkWindow, text="Add", command=form_fields).grid(row=row_counter, column=0)

    def run(self):
        self.tkWindow.mainloop()


f = Form()
f.run()

file_handler.py – für lesen und schreiben von Dateien.

import json
import os


class FileHandler:
    json_file_name = "./list_of_teasers.json"

    def add_to_json_file(self, new_entry):
        lod = self.read_json_file()
        lod.append(new_entry)

        with open(self.json_file_name, 'w') as fout:
            json.dump(lod, fout)

    def read_json_file(self):
        lod = []
        if not os.path.isfile(self.json_file_name):
            return lod

        with open(self.json_file_name, encoding='utf-8') as data_file:
            data = json.loads(data_file.read())
            lod = data
        return lod

form_construction.json

[
  {
    "label": "Headline",
    "name": "headline"
  },
  {
    "label": "CTA",
    "name": "url"
  },
  {
    "label": "Bild",
    "name": "image_url"
  },
  {
    "label": "Video-Id",
    "name": "video_id"
  }
]

Wir haben hier nun eine Klasse für die Dateibehandlung, eine für den Formularaufbau und die „Bauanleitung“, die das Formular aufbaut.

Es werden hier im Beispiel Video Teaser angelegt. Die Teaser-Json wird erzeugt, sofern noch nicht vorhanden. Neue Elemente werden unten angehängt.

Ausgeführt wird das ganze dann mittels

python main.py

Man kann sowas aber auch mit der Python Erweiterung pyinstaller als ausführbare Binary/Executable Datei erstellen.

Dazu benötigt es ein paar Befehle auf Terminal-Ebene:

pip install pyinstaller
#installiert das Package

pyinstaller main.py --onefile -n SimpleJsonForm
#erstellt von der main.py ausgehend eine Binary mit dem Namen SimpleJSONForm

Das Ergebnis als JSON Array:

Gespeicherter JSON Array aus dem Tkinter Form
Gespeicherter JSON Array aus dem Tkinter Form
Zurück