Я пытаюсь понять, как это сделать в течение нескольких дней без успеха. Как сказано в заголовке, есть ли способ отобразить вывод консоли (в частности, отпечатки в приведенном ниже коде) в каком-то текстовом поле или метке с помощью tkinter?
У меня есть программа, которая читает файл .txt и использует его данные для передачи некоторых координат в облако, которое использует платформу управления автопарком в моей компании.
Любая помощь приветствуется!
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: Проблема решена. Хорошо, после двух дней работы над ней я, наконец, нашел, как это сделать. Прежде всего, я разделил свой код на функции, как вы можете видеть в приведенном выше коде, моя основная логика работала только в одной функции, я разделил эту функцию на более мелкие функции, как вы увидите ниже. Чтобы отобразить результат, я использую метки, я создал функцию, которая вызывается каждый раз, когда мне нужно обновить метки (def attLabel()). Если вы попытаетесь запустить приведенный выше код, вы увидите, что графический интерфейс зависает, когда цикл происходит, чтобы исправить это, я использую библиотеку потоков, выполняя свою логику в одном потоке, а мой графический интерфейс в другом, что позволяет мне отображать текущие значения в метках. Я знаю, что мой код не чистый и красивый, но он делает то, что должен делать он, так что...
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()
Спасибо за помощь!