问题描述
限时送ChatGPT账号..可以编写一个简单的python脚本将xterm
嵌入到tk
框架中:
One can write a simple python script to embed an xterm
into a tk
frame:
from Tkinter import *
import subprocess
root = Tk()
termf = Frame(root, height=800, width=1000)
termf.pack(fill=BOTH, expand=YES)
wid = termf.winfo_id()
窗口建立后
proc = subprocess.Popen('xterm -into %d -sb ' % wid,shell=True)
root.mainloop()
在我的电脑上它看起来像即使在调整框架大小(通过拖动角)时,如何使嵌入的 xterm 动态调整为 termf
框架的大小?
On my computer it looks like
How can I make the embedded xterm be dynamically sized to the size of the termf
frame even when resizing the frame(by dragging the corner)?
回复@tinmarino
推荐答案
@EthanField 解决方案的实施.3个功能:
主要创建 gui、xterm 并堵塞管道on_resize 在包含终端的帧被调整大小时被调用get_xterm_pts 正在解析 pts 的输出以将 stdin 提供给 xtermimport tkinter as tk
import subprocess as sp
from re import match
from threading import Thread
from queue import Queue
def main():
# Init
root = tk.Tk()
queue = Queue()
# Pack main frame
termf = tk.Frame(root, width=800, height=800)
termf.pack(fill=tk.BOTH, expand=tk.YES, padx=0, pady=0)
wid = termf.winfo_id()
# Allow window resize
sp.Popen("""echo '*VT100.allowWindowOps: true' | xrdb -merge""", shell=True)
# Craft command
cmd = (
# Create into me
f'xterm -into {wid} -geometry 100x50 '
# Log to stdout
r'-sb -l -lc -lf /dev/stdout '
# Launch `ps` command: output, tty, = for remove header
"""-e /bin/bash -c "ps -o tt=;bash" """
r'| tee'
)
print('Launching:', cmd)
# Spawn Xterm
process = sp.Popen(
cmd, shell=True, stdout=sp.PIPE, stderr=sp.PIPE)
print('Xterm pid:', process.pid)
# Get pts
thread = Thread(target=lambda: get_xterm_pts(termf, process, queue))
thread.start()
# Set resize callback
termf.bind("<Configure>", lambda event: on_resize(event, queue))
# Start
root.mainloop()
def on_resize(event, queue):
"""On resize: send escape sequence to pts"""
# Magic && Check
magic_x, magic_y = 6.1, 13
print('Resize (w, h):', event.width, event.height)
if not queue.queue: return
# Calculate
width = int(event.width / magic_x)
height = int(event.height / magic_y)
print('To (lin,col):', height, width)
ctl = f"\u001b[8;{height};{width}t"
# Send to pts
with open(queue.queue[0], 'w') as f:
f.write(ctl)
def get_xterm_pts(parent, process, queue):
"""Retrieve pts(`process`) -> `queue`"""
while True:
out = process.stdout.readline().decode()
print('Xterm out' + out)
match_pts = match(r'pts/\d+', out)
if match_pts:
pts = '/dev/' + match_pts.group(0)
print('-----------> pts:', pts)
queue.put(pts)
break
if out == b'' and process.poll() is not None:
break
# Resize now
fake_event = tk.Event()
fake_event.width = parent.winfo_width()
fake_event.height = parent.winfo_height()
on_resize(fake_event, queue)
if __name__ == '__main__':
main()
在新线程中搜索新 shell 的 pts 似乎很多,但我们想要交互式 shell 的 pts 而不是产生它的 sh
.我实际上尝试了 pip -> pts 和一些 Popen ps,但它的弹性较差.
The search of the pts of the new shell in a new thread seems a lot, but we want the pts of the interactive shell and not the sh
which spawn it. I actually tried pip -> pts with some Popen ps, and it was less resilient.
11844 pts/1 00:00:00 sh <- pid returned to Popen
11847 pts/1 00:00:00 xterm <- then ...
11848 pts/1 00:00:00 tee <- that is how a pipe work, first plug, then spawn (apparently) (seems logical)
11854 pts/35 00:00:00 bash <- then favorite shell is Michel
这篇关于tk 嵌入的 xterm 的大小如何是动态的?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!
更多推荐
[db:关键词]
发布评论