Home > database >  Circular import issue (class) - Tkinter Python
Circular import issue (class) - Tkinter Python

Time:01-03

After a couple of hours of trying to debug a circular import issue I'd like to ask for some assistance here.

Please note, after researching, I'm unable to find my specific issue that would help. Some issues I've found are based on Button()s inside the class. However, this is not the case. My goal here is to .get an input from a text_box and convert it into json format aka beautify. (similar to what can be done in api testing tools)

I have a working function in pointer.py that does the job. However, I thought I'd create a class in a different file to clean things up a bit.

#--------------------------------------beautify_data.py--------------------------------------------#
import json
from pointer import text_box, payload_field

class Beautifier:
    def __init__(self, beautiful_payload):
        self.new = beautiful_payload

    def beautifying(self):
        json_object = json.loads(self.new) 
        new_json = json.dumps(json_object, indent=4) 
        text_box.delete('1.0', "end")  # Deleting content in text box
        text_box.insert('1.0', new_json) # Inserting pretty printed data
        payload_field.set(new_json) # Setting another field with pp data
        return new_json

#--------------------------------------pointer.py--------------------------------------------#

from beautify_data import Beautifier

button_save_payload = ttk.Button(width=8, text="BEAUTIFY", command=lambda: [Beautifier(get_text_box)])
button_save_payload.place(x=1110, y=75)

text_box = Text(window, width=68, height=29, bg="black", font=("Helvetica", 17))
text_box.grid(row=0, column=0, sticky="nsew")
text_box.place(x=420, y=70)
get_text_box = text_box.get("1.0", END)

mytest = Beautifier(get_text_box)
new = mytest.beautifying()
print(new)

The error I'm receiving is:

ImportError: cannot import name 'Beautifier' from partially initialized module 'beautify_data' (most likely due to a circular import)

CodePudding user response:

Instead of importing data from pointer, the code in pointer needs to give access to the widgets to your Beautifier class. You can do this in many ways - you could pass the data to Beautifier.__init__, or pass it to beautifying. Or, you could create a function in pointer.py that updates its own widgets, and pass that as a callback.

Here's an example of the latter, passing a callback to Beautifier.__init__:

beautify_data.py

class Beautifier:
    def __init__(self, beautiful_payload, callback=None):
        self.new = beautiful_payload
        self.callback = callback

    def beautifying(self):
        json_object = json.loads(self.new) 
        new_json = json.dumps(json_object, indent=4) 
        if self.callback:
            self.callback(new_json)
        return new_json

pointer.py

def update_ui(new_json):
    text_box.delete('1.0', "end")
    text_box.insert('1.0', new_json)
    payload_field.set(new_json)
...
mytest = Beautifier(get_text_box, update_ui)
new = mytest.beautifying()
...

I recommend removing beautiful_payload from Beautifier.__init__ and instead pass it to beautifying. That way you can create one instance and then use it multiple times, instead of having to create a new instance each time you want use it.

beautify_data.py:

class Beautifier:
    def __init__(self, callback=None):
        self.callback = callback

    def beautifying(self, payload):
        json_object = json.loads(payload) 
        new_json = json.dumps(json_object, indent=4) 
        if self.callback:
            self.callback(new_json)
        return new_json

pointer.py

...
mytest = Beautifier(callback=update_ui)
get_text_box = text_box.get("1.0", END)
new = mytest.beautifying(get_text_box)
...

CodePudding user response:

It is better to update the widgets in pointer.py instead, so you don't need to import pointer.py inside beautify_data.py:

beautify_data.py
import json

class Beautifier:
    def beautifying(self, txt):
        try:
            json_object = json.loads(txt)
            new_json = json.dumps(json_object, indent=4) 
            return new_json
        except json.decoder.JSONDecodeError as ex:
            print(ex)
pointer.py
from tkinter import *
from tkinter import ttk
from beautify_data import Beautifier

def beautify_json():
    get_text_box = text_box.get("1.0", "end-1c")
    mytest = Beautifier()
    result = mytest.beautifying(get_text_box)
    if result:
        text_box.delete("1.0", END)
        text_box.insert(END, result)

window = Tk()

text_box = Text(window, width=68, height=29, fg="white", bg="black", insertbackground="white", font=("Helvetica", 17))
text_box.grid(row=0, column=0, sticky="nsew")

button_save_payload = ttk.Button(width=8, text="BEAUTIFY", command=beautify_json)
button_save_payload.grid(row=1, column=0, sticky="e")

window.mainloop()
  • Related