Python 如何在Tkinter应用程序上监听终端?

Python 如何在Tkinter应用程序上监听终端?,python,python-3.x,tkinter,tkinter-canvas,Python,Python 3.x,Tkinter,Tkinter Canvas,我有一个简单的图形程序,可以在遥控树莓的触摸屏上显示一些指令和触摸按钮 我没有直接执行,而是通过SSH连接来运行它,因此我在桌面应用程序日志中有 我希望在运行脚本的控制台上少一些交互,比如执行一些函数或更改一些变量的值 这可能吗 我不想在TKinter窗口内创建控制台,正如alessandro所问: 不确定我是否应该使用一个简短的子进程,如user1941008,但htis看起来太复杂了 我不喜欢为这个东西创建客户机/服务器设置或中间缓冲区,太复杂了,我将不得不重写这些东西以将日志发送到新程

我有一个简单的图形程序,可以在遥控树莓的触摸屏上显示一些指令和触摸按钮

我没有直接执行,而是通过SSH连接来运行它,因此我在桌面应用程序日志中有

我希望在运行脚本的控制台上少一些交互,比如执行一些函数或更改一些变量的值

这可能吗

我不想在TKinter窗口内创建控制台,正如alessandro所问:

不确定我是否应该使用一个简短的子进程,如user1941008,但htis看起来太复杂了

我不喜欢为这个东西创建客户机/服务器设置或中间缓冲区,太复杂了,我将不得不重写这些东西以将日志发送到新程序

我添加了我的代码的一个小版本:

#!/usr/bin/env python3
import tkinter as tk

class _tkapp(tk.Frame):
    def __init__(self, master=None):
        super().__init__(master)
        self.master = master
        self.pack()
        self.create_widgets()

    def create_widgets(self):

        self.redButton = tk.Button(self, text='Make me red', command=self.paintMeRed)
        self.redButton.pack(side='top')

        self.blueButton = tk.Button(self, text='Make me blue', command=self.paintMeBlue)
        self.blueButton.pack(side='top')

        self.quit = tk.Button(self, text='QUIT', fg='red', command=self.master.destroy)
        self.quit.pack(side='bottom')

    def paintMeRed(self):
        tk_root.configure(background='red')
        print('user click on RED')

    def paintMeBlue(self):
        tk_root.configure(background='blue')
        print('user click on BLUE')


tk_root = tk.Tk()
tk_root.geometry("200x120") 
tk_app = _tkapp(master=tk_root)
tk_app.mainloop()
这允许我在控制台上查看用户点击的内容,
我的目标是,也从控制台更改颜色

以下是您问题的答案。我的另一个(删除的)答案不适合你的问题

不幸的是,没有套接字您无法完成这项工作,但我在示例中添加了一些易于调整的方法(
init\u remote\u execution
listener
do\u remote\u call
cleanup
),您可以复制并粘贴到实际应用程序中。您只需调整
do\u remote\u call
方法:

#/usr/bin/env蟒蛇3
导入套接字
将tkinter作为tk导入
从队列导入队列
从线程导入线程
从uuid导入uuid1
UDP_HOST=“”
UDP_端口=5005
RECV_缓冲区=1020
等级_tkapp(传统框架):
def uuu init uuu(self,master=None):
超级()。\uuuu初始化\uuuuu(主)
self.master=master
self.pack()
self.create_widgets()
self.init\u远程执行()
self.master.protocol(“WM_DELETE_WINDOW”,self.cleanup)#退出时调用cleanup
def初始远程执行(自):
self.sock=socket.socket(socket.AF_INET,socket.sock_DGRAM)
self.sock.bind((UDP_主机、UDP_端口))
self.endmsg=str(uuid1())#用于停止线程的随机字符串
self.queue=queue()
self.treads_running=真
self.listener\u线程=线程(目标=self.listener)
self.worker\u线程=线程(目标=self.do\u远程调用)
self.listener_thread.start()
self.worker_thread.start()
def侦听器(自我):
打印(“听”)
self.treads_运行时:
数据,addr=self.sock.recvfrom(RECV\u缓冲区)
data=data.decode().strip()
打印(“从{addr}:{data}”。格式(addr=addr,data=data))
如果数据==self.endmsg:
self.treads_running=False
self.queue.put(数据)
self.sock.close()
def do_远程_呼叫(自):
self.treads_运行时:
data=self.queue.get()
如果数据==self.endmsg:
打印(“再见”)
elif数据==“单击红色”:
self.paintMeRed()
elif数据==“单击蓝色”:
self.paintMeBlue()
其他:
打印(“>>>未知命令”)
def清理(自):
打印(“清理”)
s=socket.socket(socket.AF_INET,socket.SOCK_DGRAM)
s、 发送到(self.endmsg.encode(),(“127.0.0.1”,UDP_端口))
self.listener_thread.join()
self.worker_thread.join()
self.master.destroy()
def创建_小部件(自):
self.redButton=tk.Button(self,text=“使我变红”,command=self.paintMeRed)
self.redButton.pack(side=“top”)
self.blueButton=tk.Button(self,text=“使我变蓝”,command=self.paintMeBlue)
self.blueButton.pack(side=“top”)
self.quit=tk.按钮(
self,text=“退出”,fg=“红色”,command=self.cleanup
)#呼叫清理!!!
self.quit.pack(side=“bottom”)
def喷漆(自):
tk_root.configure(background=“red”)
打印(“用户单击红色”)
def paintMeBlue(自):
tk_root.configure(background=“blue”)
打印(“用户点击蓝色”)
如果名称=“\uuuuu main\uuuuuuuu”:
tk_root=tk.tk()
tk_根几何(“200x120”)
tk\u应用程序=\u tkapp(主程序=tk\u根)
tk_app.mainloop()
在退出按钮上调用
cleanup
方法非常重要(否则线程将不会停止,应用程序将挂起)

现在,您可以通过向raspberry上的端口5005发送udp消息(单击蓝色)来“单击”使我变蓝按钮

使用raspberry上的工具netcat(您可能需要使用apt安装),您可以发送命令单击蓝色,如下所示:

echo "click BLUE" | nc -uw0 127.0.0.1 5005
使用python:

#!/usr/bin/env python3
import socket


sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
sock.sendto('click BLUE'.encode(), ('127.0.0.1', 5005)
sock.close()

从桌面上,您必须用树莓的ip地址切换“127.0.0.1”。

这里是一个更简单的版本,使用python中的
cmd
模块。此模块允许您为任何内容编写repl(读取-评估-打印循环)

#/usr/bin/env蟒蛇3
导入命令
导入操作系统
输入信号
将tkinter作为tk导入
从线程导入线程
等级_tkapp(传统框架):
def uuu init uuu(self,master=None):
超级()。\uuuu初始化\uuuuu(主)
self.master=master
self.pack()
self.create_widgets()
def创建_小部件(自):
self.redButton=tk.Button(self,text=“使我变红”,command=self.paintMeRed)
self.redButton.pack(side=“top”)
self.blueButton=tk.Button(self,text=“使我变蓝”,command=self.paintMeBlue)
self.blueButton.pack(side=“top”)
self.quit=tk.Button(self,text=“quit”,fg=“red”,command=self.master.destroy)
self.quit.pack(side=“bottom”)
def喷漆(自):
tk_root.configure(background=“red”)
打印(“用户单击红色”)
def paintMeBlue(自):
tk_root.configure(background=“blue”)
打印(“用户点击蓝色”)
类命令(cmd.cmd):
intro=“欢迎使用Tk应用程序的repl。键入帮助或?以列出命令。\n”
prompt=“”
定义初始化