Search code examples
pythontkintertkinter-text

Python Tkinter text insert from another module


I'm using python for my little project and for fun I made my program one single file and it's kinda large and messy right now so I decide try to devide several files and import it. It's ok to work but the problem is I have no idea how to use text.insert func

gui_test.py

from tkinter import *
import threading
from test import test_fun


def t_test():
    t0 = threading.Thread(target=test_fun)
    t0.start()


if __name__ == "__main__":

    root = Tk()
    root.title(f"test_gui")
    root.geometry("355x280")

    txt = Text(root, width=50, height=10, wrap=WORD)  # log
    txt.place(x=0, y=20)
    txt.config(state=NORMAL)

    btn1 = Button(root, text="test_button", command=t_test)
    btn1.place(x=5, y=160)

    root.mainloop()

test.py

import time

def test_fun():
    sec = 0
    while True:
        txt.insert(END, f"{sec}\n")
        sec += 1
        time.sleep(1)

How can I send some text and show on gui_test.py?

Looking for easiest way

Solved

gui_test.py

from tkinter import *
import threading
from test import test_fun

def t_test():
    t0 = threading.Thread(target=test_fun, args=(root,), daemon=False)
    t0.start()


if __name__ == "__main__":

    root = Tk()
    root.title(f"test_gui")
    root.geometry("355x280")

    root.txt = Text(root, width=50, height=10, wrap=WORD)  # log
    root.txt.place(x=0, y=20)
    root.txt.config(state=NORMAL)

    btn1 = Button(root, text="test_button", command=t_test)
    btn1.place(x=5, y=160)

    root.mainloop()

test.py

import time
from tkinter import *


def test_fun(widget):
    sec = 0
    while True:
        widget.txt.insert(END, f"{sec}\n")
        widget.txt.update()
        widget.txt.see(END)
        sec += 1
        time.sleep(1)

Solution

  • You need to pass the Tk() object to the function if you want the function to be able to change anything in it:

    def test_fun(widget):
        sec = 0
        while True:
            widget.txt.insert(END, f"{sec}\n")
            widget.txt.update()
            sec += 1
            time.sleep(1)
    

    And then you need to make the Text box a part of the widget:

        root.txt = Text(root, width=50, height=10, wrap=WORD)  # log
        root.txt.place(x=0, y=20)
        root.txt.config(state=NORMAL)
    

    Now, you can call the function by writing test_fun(root) and it will start filling the window. (unfortunately, I'm not familiar with threading. But a lambda-function passing root should be feasible)