Reputation: 45
Bit of a beginner here :)
So for the past couple of days I've been working on a relatively simple web scraper, but with a special goal in mind. Namely, I wanted to get better with tkinter.
So, I've made a devlog window, which is simply going to be a separate console kind of thing. But the problem is that I want to insert text "live" in to the devlog window, and the text comes from a different script in a different thread. How could I implement this feature? This devlog window is ALSO run in a thread, as well as 3 other scripts along side it. This is the code I have so far:
import Manager as AM
import tkinter as tk
from time import sleep # For some simple timing algorithms
Width = 700
Height = 500
FrameGeometry = str(Width) + "x" + str(Height)
# COLORS
LightGrey = "#D9D9D9"
DarkGrey = "#AAAAAA"
# Global variables.
ThreadsList = list()
def CreateDevLogWindow():
global Width
global Height
ThreadTemp_ = str(AM.FileManager(ReadData=2))
devlog = tk.Tk() # Secondary Devlog Interface.
FrameInfo = tk.Frame(master=devlog)
FrameText = tk.Frame(master=devlog)
ThreadText = tk.Label(master=FrameInfo, text="Total Threads: " + ThreadTemp_, bg="white")
ThreadTextActive = tk.Label(master=FrameInfo, text="Active Threads: " + ThreadTemp_, bg="white")
InfoText = tk.Text(FrameText, border=1, highlightthickness=1)
devlog.title("Devlog: YourOptimalScrapper")
devlog.geometry(str(Width) + "x" + str(Height))
devlog.config(bg="white")
FrameInfo.config(bg="white")
FrameText.config(bg="white", padx=5, pady=5)
FrameInfo.pack(side=tk.TOP, fill=tk.BOTH)
FrameText.pack(side=tk.BOTTOM, expand=True, fill=tk.BOTH)
ThreadText.grid(row=0)
ThreadTextActive.grid(row=1)
InfoText.pack(expand=True, fill=tk.BOTH)
while True:
if ThreadTemp_ != AM.FileManager(ReadData=2):
ThreadTemp_ = str(AM.FileManager(ReadData=2))
ThreadText.config(text="Total Threads: " + ThreadTemp_)
ThreadTextActive.config(text="Active Threads: " + ThreadTemp_)
devlog.update()
Any and all help is appreciated, and NOTE: There is more code under this, but I don't think its particularly necessary :)
Upvotes: 1
Views: 1809
Reputation: 159
First of all you can insert text in your TextBox with just a few lines.
def update_textbox(textbox, data):
textbox.config(state=tk.NORMAL) # unlock the textbox
textbox.insert(tk.END, "\n"+str(data)) # add newline and append the data
textbox.config(state=tk.DISABLED) # lock back the textbox to readonly
textbox.see(tk.END) # scroll to the bottom to see the last line
With that if your script is in a different thread, then you can create a file that will be the "carrier" of your data.
Whenever you need to write data to the textbox, simply write data to the file with your text in any thread and update the while loop in the above code to read this file and update the textbox if the file isn't empty.
EDIT: You don't need to call this function outside of this thread. Just check in your while loop whether new data has to be added to the log
...
while True:
with open("carrier.txt", 'r') as f:
content = f.read() # read carrier data
if content: # if file isn't empty
update_textbox(InfoText, content) # update the textbox with the data in the file
open("carrier.txt", 'w').close() # clear the file to prevent reading the data twice
if ThreadTemp_ != AM.FileManager(ReadData=2):
ThreadTemp_ = str(AM.FileManager(ReadData=2))
ThreadText.config(text="Total Threads: " + ThreadTemp_)
ThreadTextActive.config(text="Active Threads: " + ThreadTemp_)
devlog.update()
And in your other thread
def update_log(data):
with open("carrier.txt", 'a') as f: # append to the file
f.write(str(data))
Upvotes: 3