Search code examples
pythonjsonuser-interfacetkintertkinter-text

How to format the display of JSON data in a tkinter.Text widget?


I have created a Python GUI that allows the user to create and save text files (technically a journal). Within the workspace (VS Code), I have created a JSON file of simple key/value pairs (technically a dictionary); "word": "definition".

I want the user to be able to click a button that opens a window with a tk.Text widget which contains the JSON data in a clear, readable, and alphabetical list form, but the data prints out as a multiline string separated by single quotes without any spaces or newlines inside the Text widget.

My desired outcome is a "read-only" list of key/value pairs, one per line, without all of the JSON syntax (double quotes, commas, and curly brackets). I cannot find any solution to achieve this specific preference, and I'm still learning the capabilities of JSON data within a Python program. If there is a more suitable or configurable method, I am open to suggestions, but I hope there is a simple configuration to the Python syntax that dictates how the data prints in the Text widget.

Thank you for any insights given. I do not think the code would be relevant to address this but if needed, I can add it.


Solution

  • I'd make use of the builtin json module, and use the dump method of a loaded json file, or dumps with a string like in this example:

    import json
    print(json.dumps({'4': 5, '6': 7}, sort_keys=True, indent=4))
    

    resulting in

    {
        "4": 5,
        "6": 7
    }
    

    https://docs.python.org/3/library/json.html

    So instead of printing it directly, you can pass it through json.dumps and then add the result to your text widget:

    import tkinter as tk
    import json
    
    app = tk.Tk()
    
    text = tk.Text(app)
    
    text.pack()
    
    json_val = json.loads('{"a": 5, "b": 7}')
    
    for k in json_val:
        text.insert(tk.END, '{} = {}\n'.format(k,json_val[k]))
    text.config(state = tk.DISABLED)
    app.mainloop()
    

    The above code produces this:

    enter image description here