python-3.x - 如何从活动 tcp 会话接收文本来更新 tk.label
问题描述
我正在尝试从作为服务器工作的活动 tcp 会话更新 tk.label 中的文本。所以脚本实际上是在等待(服务器)通过 tcp 连接从客户端接收一些文本。
import re
import socketserver
import socket
import subprocess
import tkinter as tk
import time
line = ""
class Info:
def __init__(self, master):
self.label=tk.Label(master)
self.label.grid(row=0, column=0)
self.label.configure(text='Ready to roll...')
self.count = 0
if self.count == 0: self.first_label()
else: self.update_label()
def first_label(self):
self.label.configure(text=line_info)
self.label.after(5000, self.update_label)
self.count += 1
def update_label(self):
self.label.configure(text = line_info)
self.label.after(5000, self.update_label) # call this method again in 1,000 milliseconds
self.count += 1
with socketserver.TCPServer((host, port), MyTCPHandler) as server:
print("{}:{} - READY".format(host, port))
# Activate the server; this will keep running until you
# interrupt the program with Ctrl-C
server.serve_forever()
class MyTCPHandler(socketserver.BaseRequestHandler):
def handle(self):
# self.request is the TCP socket connected to the client
self.data = self.request.recv(1024).strip()
data = self.data.decode('utf-8')
# Do string manipulation to find cpu/gpu and co.
line_info = "{} {} {} {} {} {} {}".format(timestamp, tcpu, tgpu, cpu, core, volt, gpu)
print(line_info)
# just send back the same data, but upper-cased
self.request.sendall(bytes("OK", "utf-8"))
if __name__ == "__main__":
host_name = socket.gethostname()
bashCmd = "hostname -I | awk -F\" \" '{print $1}'"
data = subprocess.check_output(["bash", "-c", bashCmd]).strip()
server_ip = data.decode('utf-8')
host, port = server_ip, 9999
line_info = "Updating..."
root = tk.Tk()
Info(root)
root.mainloop()
这个 server.py 脚本正在等待通过 tcp 从客户端接收一些文本,例如:
10/12/2020 10:50:01 [192.168.1.124] CPU=54.61C GPU=55.10C CPU=700GHz Core=400MHz Core=1.35V GPU=300MHz OK
10/12/2020 10:50:12 [192.168.1.124] CPU=54.61C GPU=55.10C CPU=700GHz Core=400MHz Core=1.35V GPU=300MHz OK
10/12/2020 10:50:23 [192.168.1.124] CPU=54.61C GPU=55.10C CPU=700GHz Core=400MHz Core=1.35V GPU=300MHz OK
我的目标是获取通过 tcp 连接接收到的文本并将其作为将滚动的标签文本查看到 tk-window 中。尽管 tcp 连接和文本从客户端接收到服务器并且 tk 窗口已初始化,但它永远不会使用每 20 秒来自客户端的新信息(变量 line_info)进行更新。为了检查,我只是在字符串操作后将 line_info 打印到标准输出。
如何更新 tk.label 中的文本?
解决方案
你最好使用线程来运行update_label()
,这样它就不会阻塞应用程序:
import socketserver
import socket
import subprocess
import tkinter as tk
import threading
class Info:
def __init__(self, master):
self.label=tk.Label(master, textvariable=line_info)
self.label.grid(row=0, column=0)
threading.Thread(target=self.update_label, daemon=True).start()
def update_label(self):
line_info.set('Ready to roll...')
with socketserver.TCPServer((host, port), MyTCPHandler) as server:
print("{}:{} - READY".format(host, port))
server.serve_forever()
class MyTCPHandler(socketserver.BaseRequestHandler):
def handle(self):
try:
# self.request is the TCP socket connected to the client
self.data = self.request.recv(1024).strip()
data = self.data.decode('utf-8')
# Do string manipulation to find cpu/gpu and co.
line_info.set("{} {} {} {} {} {} {}".format(timestamp, tcpu, tgpu, cpu, core, volt, gpu))
print(line_info.get())
# just send back the same data, but upper-cased
self.request.sendall(bytes("OK", "utf-8"))
except Exception as e:
print(e)
if __name__ == "__main__":
host_name = socket.gethostname()
bashCmd = "hostname -I | awk -F\" \" '{print $1}'"
data = subprocess.check_output(["bash", "-c", bashCmd]).strip()
server_ip = data.decode('utf-8')
host, port = server_ip, 9999
root = tk.Tk()
line_info = tk.StringVar()
Info(root)
root.mainloop()
请注意,我已更改line_info
为StringVar()
.
推荐阅读
- java - 如何对 Java springboot 中的日志记录进行单元测试
- sql - 如何从日期列返回特定日期名称的数据
- javascript - 将 XML 响应转换为有用的数据
- ethereum - 以太坊区块头:recipientsRoot 的目的是什么?
- flutter - Flutter Textformfield如何在焦点丢失时调用onSubmitted或onEditingComplete
- java - 如何使用 youtube data api v3 登录
- javascript - 我想要输入文本/javascript,但它因“图像/gif”而失败
- pine-script - 松树:将系列整数转换为整数
- python - 如何通过名称找出正在运行的 python 脚本的 psid?
- python - Protobuf 将 int64 数据类型编码为 json 映射中的字符串