首页 > 解决方案 > 如何使用 GUI 小部件通过子进程的 Popen 捕获 input() 请求并将其返回以继续该过程,重复直到结束?

问题描述

我使用 wxPython 作为我的 GUI,使用 NVDA 作为我的屏幕阅读器,带有可刷新的盲文显示器。NVDA 目前不支持正确读取 tkinter 包。

我的目标:在将输出流设为多行时,只读 TextCtrl;捕获对 input() 进程的请求,并将 input(prompt) --> TextEntry() 转换为默认对话框标题、提示输入消息和一个空的 TextCtl 等待我的单行字符串,点击 Enter the string I 后返回输入到输入流并继续接受输出到原始输出 TextCtrl。

我的目标是用这种形式代替我对有限类型的命令行程序使用终端的需要,这些程序只需要我的一行输入,因为我逐行跟踪输出直到过程结束。

现在,我的程序是这样编码的:

import os, subprocess

import wx


class PyOutputFrame(wx.Frame):
    
    def __init__(self, title="Program Output"):
        
        wx.Frame.__init__(self, None, title=title)
        
        menubar = wx.MenuBar()
        actionmenu = wx.Menu()
        chdirmenuitem = actionmenu.Append(wx.ID_ANY, 'Change Current Dir')
        menubar.Append(actionmenu, '&Action')
        self.Bind(wx.EVT_MENU, self.OnChange, chdirmenuitem)
        self.SetMenuBar(menubar)
        
        panel = wx.Panel(self)
        self.entxt = wx.TextCtrl(panel, style=wx.TE_PROCESS_ENTER)
        self.entxt.Bind(wx.EVT_TEXT_ENTER, self.OnEnter)
        self.outxt = wx.TextCtrl(panel, style=wx.TE_MULTILINE|
                                              wx.TE_READONLY|
                                              wx.TE_BESTWRAP)
        
        sizer = wx.BoxSizer(wx.VERTICAL)
        sizer.Add(self.entxt, 0, wx.EXPAND)
        sizer.Add(self.outxt, 1, wx.EXPAND)
        panel.SetSizer(sizer)
        
    def OnEnter(self, event):
        
        self.outxt.Clear()
        cmd = self.entxt.GetValue()
        proc = subprocess.run(cmd,
                              stdout=subprocess.PIPE,
                              stderr=subprocess.STDOUT,
                              shell=True)
        self.outxt.WriteText(proc.stdout.decode())
        self.outxt.SetInsertionPoint(0)
        self.outxt.SetFocus()
        
    def OnChange(self, event):
        
        dlg = wx.DirDialog(self, style=wx.DD_CHANGE_DIR)
        dlg.ShowModal()

if __name__ == '__main__':
    app = wx.App()
    frm = PyOutputFrame()
    frm.Show()
    app.MainLoop()

这需要一个新代码:

1:当进程开始时,如果输出不需要inpuq,直接打印输出TextCtrl,逐行2:当输出行需要我输入时,自动或者1)创建弹出消息框,提示为消息和单行输入框输入我的输入,然后按 ENTER 将其发送到进程或 2)展开我的原始输入 TextCtrl,最初用于启动进程(例如“py echoname.py”)以在必要时随时接受多行输入该过程需要输入,不使用弹出对话框 3:该输入被转换为输出,如果有的话,除了它的提示输出 4:如果还有,重复 2 和 3 5:用任何输出的剩余部分完成该过程

测试脚本读取和输入:

print('Hi')
while True:
    ans = input('Tell me your name: ')
    if ans == 'q': break
    print(f'Yo {ans.title()}!')
print('Bye!')

大局观:我使用盲文显示器来阅读文本,我的目标是从使用命令行程序的终端转向这种类型的 GUI 界面,因为我的注意力将转移到多行输出的顶部而不是需要爬通过盲文显示器逐行显示在终端顶部。终端机更适合视力正常的用户,而不是盲文显示器用户。谢谢你。

标签: pythonsubprocesswxpython

解决方案


推荐阅读