首页 文章

如何将stdin / out / error(Paramiko SSH)路由到没有类的Tkinter文本框?

提问于
浏览
0

我正在使用Parmiko调用ssh shell,我想将所有输入/输出定向到Text小部件 . 我找到this solution

class IORedirector(object):
    '''A general class for redirecting I/O to this Text widget.'''
    def __init__(self,text_area):
        self.text_area = text_area

class StdoutRedirector(IORedirector):
    '''A class for redirecting stdout to this Text widget.'''
    def write(self,str):
        self.text_area.write(str,False)

# In your Tkinter Widget
sys.stdout = StdoutRedirector( self )

问题是我不熟悉足以使这项工作的课程(无论它多么简单),遗憾的是时间不在我身边 . 话虽这么说,没有类定义,最简单的方法是什么?该类是否可以转换为通用函数并调用它来执行重定向?

谢谢你的帮助 .

编辑:经过进一步的实验,我改变了

self.text_area.write(str,False)

self.text_area.insert(END,str)

现在,这可用作打印语句现在出现在文本框中 . 现在我的问题是当我调用interactive.interactive_shell(chan)时,程序崩溃了

AttributeError: 'StdoutRedirector' object has no attribute 'flush'

有这个想法吗?

编辑2:我会继续挖掘 . 现在已经找到this.我已经添加了一个无操作的flush,因此得到:

AttributeError: 'NoneType' object has no attribute 'settimeout'

我觉得这将是一个地洞 . 来自 now? 的任何想法

编辑3:我将追逐到最后 . 需要添加(自我)参数,如def flush(self) .

我不知道这是怎么回事,所以回到一个简单的解决方案,将Paramiko交互式shell路由到带有输入和输出的文本框会很棒 .

1 回答

  • 0

    Python是一种使用方法操作类实例的语言 . 其中一些是隐藏的 . 例如, type(a).__add__(a,b)a.__add__(b) 被称为 a + b . 但是,如果不了解类,实例和实例方法,则无法远远超出基础 . 正如您所发现的那样,将打印输出发送到tk文本小部件超出了基础 .

    您还发现,sys.stdout替换的确切要求取决于使用它的代码 . 如果没有paramiko为您提供sys.stdout实际需要的详细规范,您可以编写完整的替换程序,也可以在获得异常时编程部分替换 .

    例如,IDLE具有以下代码,当前位于idlelib.PyShell中 .

    class PseudoFile(io.TextIOBase):
    
        def __init__(self, shell, tags, encoding=None):
            self.shell = shell
            self.tags = tags
            self._encoding = encoding
    
        @property
        def encoding(self):
            return self._encoding
    
        @property
        def name(self):
            return '<%s>' % self.tags
    
        def isatty(self):
            return True
    
    
    class PseudoOutputFile(PseudoFile):
    
        def writable(self):
            return True
    
        def write(self, s):
            if self.closed:
                raise ValueError("write to closed file")
            if type(s) is not str:
                if not isinstance(s, str):
                    raise TypeError('must be str, not ' + type(s).__name__)
                # See issue #19481
                s = str.__str__(s)
            return self.shell.write(s, self.tags)
    

    shell.write方法有一个 text.insert('insert', s, tags) 调用 . 没有刷新调用,因为写入stdout的IDLE代码知道write会立即插入文本并且不需要刷新 . 其他未使用和不需要的属性和方法也缺失 .

    3.x i / o流的规范在io module doc中 . 您应该查看类IOBase和TextIOBase(以及可能的TextIOWrapper) . 例如,IOBase flush 条目说"Flush the write buffers of the stream if applicable. This does nothing for read-only and non-blocking streams."文本小部件插入是非阻塞的,不需要返回,因此 def flush(self): pass 就足够了 .

相关问题