简体   繁体   中英

Display live console output in tkinter label

I'm trying to figure out how to do that for a couple of days without success. As tolded in the tittle, is there any way to display the console output( specifically the prints in the code below) in some kind of textbox or label using tkinter?

I have a program that reads a .txt file and uses his data to pass some coordinates to a cloud, who is running a fleet management plataform in my company.

Any help is appreciated!

import json
import csv
import math
from math import sin, cos, sqrt, atan2, radians
import requests
from requests.auth import HTTPBasicAuth
import time
from tkinter import Tk, Label, Button, OptionMenu, Text, PhotoImage, StringVar
from functools import partial

begin = False
start = False
running = False
endTrip = False
running_counter = 0
payload_count = 0
num_lines = 0

headers = {
    'Content-Type': 'application/json',
    'Accept': 'text/plain',
}
payload_model = open('payload.json')
payload_file = json.load(payload_model)
file_name = ''
payload_model.close()

def btnStart_func(botao):
    global start
    start = not start
    lbl1['text'] = str(start)

def btnRunn_func(botao):
    global running
    running = not running
    lbl2['text'] = str(running)

def btnEnd_func(botao):
    global endTrip
    endTrip = not endTrip
    lbl3['text'] = str(endTrip)

def changeRoute():
    global file_name
    global num_lines
    file_name = var.get()
    print(file_name)
    try:
        with open(file_name) as fn:
            for line in fn:
                num_lines = num_lines+1
            fn.close()
            print(num_lines)
            num_lines = 0
    except IOError:
        print("file not found")


def beginSend():
    try:
        #'Global' to access the variables outside the function
        global file_name
        global payload_count
        global start
        global running
        global endTrip
        global running_counter
        with open(file_name) as csvfile:
            readCSV = csv.reader(csvfile, delimiter=',')
            for row in readCSV:
                payload_count = payload_count + 1
                if start == False:
                    print("Starting")
                    response = requests.post('SORRY, OMITED ',
                                             json=payload_file, headers=headers, auth=('user', 'password'))
                    print(str(response.status_code))
                    start = True
                elif running == False:
                    lat = row[2]
                    orient = row[3]
                    lon = row[4]
                    direction = row[5]
                    altitude = round(float(row[8]))
                    latdec = round(math.floor(float(lat) / 100) + (float(lat) % 100) / 60, 6)
                    if orient == 'S':
                        lat_decimal = latdec * -1
                    londec = round(math.floor(float(lon) / 100) + (float(lon) % 100) / 60, 6)
                    if direction == 'W':
                        lon_decimal = londec * -1
                    print(lat_decimal)
                    print(lon_decimal)

                    # Passing the coordinates to Json
                    payload_file['d']['message']['latitude'] = lat_decimal
                    payload_file['d']['message']['longitude'] = lon_decimal
                    payload_file['d']['message']['altitude'] = altitude

                    # Saving log files
                    payload_out_name = str(payload_count) + ' - payload_out.json'
                    payload_out = open(payload_out_name, 'w')
                    json.dump(payload_file, payload_out)
                    payload_out.close()
                    print("Running payload " + str(running_counter))
                    response = requests.post('SORRY, OMITED',
                                             json=payload_file, headers=headers, auth=('user', 'password'))
                    print(str(respose.status_code))
                    running_counter = running_counter + 1
                    if running_counter >= num_lines - 2:
                        running = True
                else:
                    if endTrip == False:
                        print("Entering END")
                        response = requests.post('SORRY, OMITED',
                                                 json=payload_file, headers=headers, auth=('user', 'password'))
                        print(str(response.headers))
                        print("END HEADER")
                        endTrip = True


    except IOError as e:
        print(e)


window = Tk()
text = Text(window)
text.tag_configure("BOLD")
window['bg']= 'gray'
bg_image_name = PhotoImage(file = 'SORRY, OMITED')
bg_label = Label(window, image=bg_image_name)
bg_label.place(x=0,y=0)


btn1 = Button(window, text='START', width= '20',font='Helvetica', fg='Blue')
btn1['command'] = partial(btnStart_func,btn1)
btn1.place(x=20,y=70)
btn2 = Button(window, text='RUNNING',width='20',font='Helvetica', fg='Blue')
btn2['command']= partial(btnRunn_func, btn2)
btn2.place(x=20,y=110)
btn3 = Button(window, text='END',width='20',font='Helvetica', fg='Blue')
btn3['command']= partial(btnEnd_func, btn3)
btn3.place(x=20,y=150)
btn5 = Button(window, text='CHANGE ROUTE',width='20',font='Helvetica', fg='Blue', command=changeRoute)
btn5.place(x=20,y=190)
btn4 = Button(window, text='BEGIN',width='20',font='Helvetica', fg='Blue', command=beginSend)
btn4.place(x=100,y=240)


OPTIONS = [
    'hopihari-guaruja.txt',
    'zooGuar-zooSP.txt',
    'picoJaragua-Interlagos.txt',
    'pqIbi-shopTatu.txt'
]

var = StringVar(window)
var.set(OPTIONS[0])

dropMenu = OptionMenu(window, var, *OPTIONS)
dropMenu.place(x=250, y=190)

menu = dropMenu.nametowidget(dropMenu.menuname)
menu.configure(font=('Impact', 20))

lbl1 = Label(window, text=str(start), font='Helvetica', fg='Blue')
lbl1.place(x=290,y=70)
lbl2 = Label(window, text=str(running), font='Helvetica', fg='Blue')
lbl2.place(x=290,y=110)
lbl3 = Label(window, text=str(endTrip), font='Helvetica', fg='Blue')
lbl3.place(x=290,y=150)
lbl4 = Label(window, text='HARDWARE SIMULATOR', font='Helvetica', fg='Black')
lbl4.place(x=70, y=25)



janela.geometry('400x400')
janela.title('HARDWARE SIMULATOR 1.0')
janela.mainloop()

@edit: Problem solved Ok, after two days working on it finnaly i found how to do. First of all i cutted my code in functions, as you can see in the code above, i had my main logic running in only one function, i divided that function into smaller functions, as you gonna see below. To display the result i'm using labels, i created a function that is called every time i need to update my labels(def attLabel()) If you try to run the code above, you will see that the GUI freezes when the loop occours, to fix this i'm using the Thread library, running my logic in one thread and my GUI in other makes me able to display live values in the labels. I know my code ins't clean and beatiful but it's doing what he should do, so...

import json
import csv
import math
from math import sin, cos, sqrt, atan2, radians
import requests
from requests.auth import HTTPBasicAuth
import time
from tkinter import Tk, Label, Button, OptionMenu, Text, PhotoImage, StringVar
import sys
from threading import Thread

begin = False
start = False
running = False
endTrip = False
running_counter = 0
payload_count = 0
num_lines = 0
lat_decimal = 0
lon_decimal = 0

headers = {
    'Content-Type': 'application/json',
    'Accept': 'text/plain',
}
payload_model = open('payload.json')
payload_file = json.load(payload_model)
file_name = ''
payload_model.close()

def attLabel(op):
    global lat_decimal
    global lon_decimal
    i=0
    if op == 'start':
        lbl5['text']= 'Start'
        lbl5.update_idletasks()
    elif op == 'run':
        lbl6['text'] = 'Latitude: ' + str(lat_decimal)
        lbl7['text'] = 'Longitude: ' + str(lon_decimal)
        lbl8['text'] = 'Running'
        lbl6.update_idletasks()
        lbl7.update_idletasks()
        lbl8.update_idletasks()
    elif op == 'end':
        lbl8['text']= 'Finished'
        lbl8.update_idletasks()


def resetBtn():
    global start, endTrip, running, running_counter, payload_count
    start = False
    endTrip= False
    running = False
    payload_count = 0
    running_counter = 0
    lbl5['text']='Output'
    lbl6['text']='Output'
    lbl7['text']='Output'
    lbl8['text']='Output'
    print(str(start)+' e '+str(endTrip)+' e '+str(running)+' e '+str(running_counter)+' e '+str(payload_count))


def changeRoute():
    global file_name
    global num_lines
    file_name = var.get()+'.txt'
    print(file_name)
    try:
        with open(file_name) as fn:
            for line in fn:
                num_lines = num_lines+1
            fn.close()
            print(num_lines)
            lbl5['text'] = 'Route with ' + str(num_lines) + ' points'
            num_lines = 0
    except IOError:
        print("ERRO! Arquivo não encontrado!")

def beginStart():
    i = 0
    try:
        #'Global' para poder acessar as variáveis globais
        global file_name
        global start
        global payload_file
        global headers
        if start == False:
            #resposta = requests.post('SORRY OMITED', json=payload_file, headers=headers, auth=('user','password'))
            #print(str(resposta.status_code))
            lbl5.update_idletasks()
            start = True
            janela.after(100, attLabel('start'))
            run_process=Thread(target= r_unning)
            run_process.start()
    except IOError as e:
        print(e)


def r_unning():
    global file_name
    global payload_count
    global start
    global running
    global endTrip
    global running_counter
    global lat_decimal
    global lon_decimal
    global payload_file
    global headers
    num_lines = 0

    try:
        with open(file_name) as fn:
            for line in fn:
                num_lines = num_lines + 1
            fn.close()
            print(num_lines)
    except IOError as e:
        print(e)
    with open(file_name) as csvfile:
        readCSV = csv.reader(csvfile, delimiter=',')
        for row in readCSV:
            if running == False:
                lat = row[2]
                orient = row[3]
                lon = row[4]
                direction = row[5]
                altitude = round(float(row[8]))
                latdec = round(math.floor(float(lat) / 100) + (float(lat) % 100) / 60, 6)
                if orient == 'S':
                    lat_decimal = latdec * -1
                londec = round(math.floor(float(lon) / 100) + (float(lon) % 100) / 60, 6)
                if direction == 'W':
                    lon_decimal = londec * -1
                print(lat_decimal)
                print(lon_decimal)
                # print(str(resposta.status_code))

                # Passando as coordenadas em decimal para o json enviado
                payload_file['d']['message']['latitude'] = lat_decimal
                payload_file['d']['message']['longitude'] = lon_decimal
                payload_file['d']['message']['altitude'] = altitude

                # Preparando arquivo para enviar
                payload_out_name = str(payload_count) + ' - payload_out.json'
                payload_out = open(payload_out_name, 'w')
                json.dump(payload_file, payload_out)
                payload_out.close()
                print("Payload de running " + str(running_counter))
                # resposta = requests.post(SORRY OMITED', json=payload_file, headers=headers, auth=('user','password'))
                running_counter = running_counter + 1
                janela.after(100, attLabel('run'))
                janela.update_idletasks()
                if running_counter >= num_lines - 2:
                    running = True
                    janela.after(100, end)




def end():
    global endTrip
    if endTrip == False:
        print("Entrando no END")
        lbl8.configure(text='Terminated')
       # resposta = requests.post('SORRY OMITED', json=payload_file, headers=headers, auth=('user','password'))
       # print(str(resposta.headers))
        print("HEADER DO END")
        endTrip = True
        janela.after(500, attLabel('end'))



janela = Tk()
text = Text(janela)
text.tag_configure("BOLD")
janela['bg']= 'gray'
bg_image_name = PhotoImage(file = 'SORRY OMITED.png')
bg_label = Label(janela, image=bg_image_name)
bg_label.place(x=0,y=0)


#btn1 = Button(janela, text='START', width= '20',font='Helvetica', fg='Blue')
#btn1['command'] = partial(btnStart_func,btn1)
#btn1.place(x=20,y=63)
#btn2 = Button(janela, text='RUNNING',width='20',font='Helvetica', fg='Blue')
#btn2['command']= partial(btnRunn_func, btn2)
#btn2.place(x=20,y=103)
#btn3 = Button(janela, text='END',width='20',font='Helvetica', fg='Blue')
#btn3['command']= partial(btnEnd_func, btn3)
#btn3.place(x=20,y=143)
btn5 = Button(janela, text='Select Route',width='10',font='Helvetica', fg='white',bg='black', command=changeRoute)
btn5.place(x=22,y=78)
btn4 = Button(janela, text='Begin',width='10',font='Helvetica', fg='white',bg='black', command=beginStart)
btn4.place(x=22,y=173)
btn6 = Button(janela, text= 'Reset', width = '10', font='Helvetica', fg='white',bg = 'black', command=resetBtn)
btn6.place(x=295,y=173)



OPTIONS = [
    'hopihari-guaruja',
    'zooGuar-zooSP',
    'picoJaragua-Interlagos',
    'pqIbi-shopTatu'
]

var = StringVar(janela)
var.set(OPTIONS[0])

dropMenu = OptionMenu(janela, var, *OPTIONS)
dropMenu.place(x=270, y=78)
menu = dropMenu.nametowidget(dropMenu.menuname)
menu.configure(font=('Impact', 10), fg='white',bg='black')

#lbl1 = Label(janela, text=str(start), font='Helvetica', fg='Blue')
#lbl1.place(x=290,y=63)
#lbl2 = Label(janela, text=str(running), font='Helvetica', fg='Blue')
#lbl2.place(x=290,y=103)
lbl3 = Label(janela, text='Output', font='Helvetica', fg='white',bg='black')
lbl3.place(x=180,y=183)
lbl4 = Label(janela, text='SORRY OMITED', font='Helvetica', fg='white',bg='black')
lbl4.place(x=70, y=25)
lbl5 = Label(janela, text='SAIDA', font='Helvetica', fg='white',bg='black')
lbl5.place(x=180, y=223)
lbl6 = Label(janela, text='SAIDA', font='Helvetica', fg='white',bg='black')
lbl6.place(x=180, y=263)
lbl7 = Label(janela, text='SAIDA', font='Helvetica', fg='white',bg='black')
lbl7.place(x=180, y=303)
lbl8 = Label(janela, text='SAIDA', font='Helvetica', fg='white',bg='black')
lbl8.place(x=180, y=343)


janela.geometry('400x400')
janela.title('HARDWARE SIMULATOR 1.0')
janela.mainloop()

Thanks for the help folks!

The solution i found is: Create threads to run your functions outside the mainloop() The problem happens when we have any kind of loop going inside de mainloop() thread. i used that function to solve my problem

Define your own name, mine is endTrue

def endTrue():
    global flag
    send_process = Thread(target=begin)
    send_process.start()
    flag = False

variable to control the loop inside the new thread

global flag

target = function you want to execute in a side thread

send_process = Thread(target=begin)

start the new thread

 send_process.start()

variable used to control the loop

flag = False

Hope this help someone in the future, gl and hf!

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM