在 Urwid 中更改框架“页脚”的文本 - Python

问题描述 投票:0回答:0

以下是一个使用'urwid'框架的非常简单的文本编辑器。不确定我是否选择了最好的框架来做文本编辑器,但这就是我正在尝试的。

但是我该如何改变呢?我想更改它以在用户添加一些文本时添加“未保存”,我知道在哪里添加,但是如何更新页脚属性?

我在这里找到了关于如何更改页脚文本的示例(它在 self.footer 中设置)但是如何重绘小部件?我一直在努力理解这一点。也许我应该回去使用诅咒?

http://urwid.org/reference/widget.html#urwid.Frame

在初始化函数中设置页脚:

class EditDisplay:

def __init__(self, name):
        self.save_name = name
        self.saved = ""
        self.walker = LineWalker(name)
        self.listbox = urwid.ListBox(self.walker)
        self.footer_text = ('foot', [
            "jEditor    File: '",
            self.save_name,
            "'" ,
            self.saved,
            ('key', "F5"), " save  ",
            ('key', "F6"), " quit ",
            ('key', 'F7'), " delete "
            ])
        self.footer = urwid.AttrMap(urwid.Text(self.footer_text),
            "foot")
        self.view = urwid.Frame(urwid.AttrMap(self.listbox, 'body'),
            footer=self.footer)

完整文件:

“”“

text eidtor 

Usage:
edit.py <filename>

"""

import os
import sys
import urwid
import urwid.raw_display

# Globals

class LineWalker(urwid.ListWalker):
    """ListWalker-compatible class for lazily reading file contents."""

    def __init__(self, name):
        self.file = open(name)
        self.lines = []
        self.focus = 0

    def get_focus(self):
        return self._get_at_pos(self.focus)

    def set_focus(self, focus):
        self.focus = focus
        self._modified()

    def get_next(self, start_from):
        return self._get_at_pos(start_from + 1)

    def get_prev(self, start_from):
        return self._get_at_pos(start_from - 1)

    def read_next_line(self):
        """Read another line from the file."""

        next_line = self.file.readline()

        if not next_line or next_line[-1:] != '\n':
            # no newline on last line of file
            self.file = None
        else:
            # trim newline characters
            next_line = next_line[:-1]

        expanded = next_line.expandtabs()

        edit = urwid.Edit("", expanded, allow_tab=True)
        edit.set_edit_pos(0)
        edit.original_text = next_line
        self.lines.append(edit)

        return next_line


    def _get_at_pos(self, pos):
        """Return a widget for the line number passed."""

        if pos < 0:
            # line 0 is the start of the file, no more above
            return None, None

        if len(self.lines) > pos:
            # we have that line so return it
            return self.lines[pos], pos

        if self.file is None:
            # file is closed, so there are no more lines
            return None, None

        assert pos == len(self.lines), "out of order request?"

        self.read_next_line()

        return self.lines[-1], pos

    def split_focus(self):
        """Divide the focus edit widget at the cursor location."""

        focus = self.lines[self.focus]
        pos = focus.edit_pos
        edit = urwid.Edit("",focus.edit_text[pos:], allow_tab=True)
        edit.original_text = ""
        focus.set_edit_text(focus.edit_text[:pos])
        edit.set_edit_pos(0)
        self.lines.insert(self.focus+1, edit)

    def combine_focus_with_prev(self):
        """Combine the focus edit widget with the one above."""

        above, ignore = self.get_prev(self.focus)
        if above is None:
            # already at the top
            return

        focus = self.lines[self.focus]
        above.set_edit_pos(len(above.edit_text))
        above.set_edit_text(above.edit_text + focus.edit_text)
        del self.lines[self.focus]
        self.focus -= 1

    def combine_focus_with_next(self):
        """Combine the focus edit widget with the one below."""

        below, ignore = self.get_next(self.focus)
        if below is None:
            # already at bottom
            return

        focus = self.lines[self.focus]
        focus.set_edit_text(focus.edit_text + below.edit_text)
        del self.lines[self.focus+1]


class EditDisplay:
    palette = [
        ('body','default', 'default'),
        ('foot','dark gray', 'white', 'bold'),
        ('key','dark gray', 'white', 'underline'),
        ]

    footer_text = ('', [])

    def __init__(self, name):
        self.save_name = name
        self.saved = ""
        self.walker = LineWalker(name)
        self.listbox = urwid.ListBox(self.walker)
        self.footer_text = ('foot', [
            "jEditor    File: '",
            self.save_name,
            "'" ,
            self.saved,
            ('key', "F5"), " save  ",
            ('key', "F6"), " quit ",
            ('key', 'F7'), " delete "
            ])
        self.footer = urwid.AttrMap(urwid.Text(self.footer_text),
            "foot")
        self.view = urwid.Frame(urwid.AttrMap(self.listbox, 'body'),
            footer=self.footer)

    def main(self):
        self.loop = urwid.MainLoop(self.view, self.palette,
            unhandled_input=self.unhandled_keypress)
        self.loop.run()

    def unhandled_keypress(self, k):
        """Last resort for keypresses."""

        if (k != "f5" or k != "f6" or k != "f7" ):
            self.saved = " (unsaved) "
            # Want to change the footer text here
            self.text_widget.set_text('No number set')

        if k == "f5":
            self.saved = ""
            self.save_file()
        elif k == "f6":
            raise urwid.ExitMainLoop()
        elif k == "f7":
            os.remove(self.save_name)
        elif k == "delete":
            # delete at end of line
            self.walker.combine_focus_with_next()
        elif k == "backspace":
            # backspace at beginning of line
            self.walker.combine_focus_with_prev()
        elif k == "enter":
            # start new line
            self.walker.split_focus()
            # move the cursor to the new line and reset pref_col
            self.loop.process_input(["down", "home"])
        elif k == "right":
            w, pos = self.walker.get_focus()
            w, pos = self.walker.get_next(pos)
            if w:
                self.listbox.set_focus(pos, 'above')
                self.loop.process_input(["home"])
        elif k == "left":
            w, pos = self.walker.get_focus()
            w, pos = self.walker.get_prev(pos)
            if w:
                self.listbox.set_focus(pos, 'below')
                self.loop.process_input(["end"])
        else:
            return
        return True


    def save_file(self):
        """Write the file out to disk."""

        l = []
        walk = self.walker
        for edit in walk.lines:
            # collect the text already stored in edit widgets
            if edit.original_text.expandtabs() == edit.edit_text:
                l.append(edit.original_text)
            else:
                l.append(re_tab(edit.edit_text))

        # then the rest
        while walk.file is not None:
            l.append(walk.read_next_line())

        # write back to disk
        outfile = open(self.save_name, "w")

        prefix = ""
        for line in l:
            outfile.write(prefix + line)
            prefix = "\n"

def re_tab(s):
    """Return a tabbed string from an expanded one."""
    l = []
    p = 0
    for i in range(8, len(s), 8):
        if s[i-2:i] == "  ":
            # collapse two or more spaces into a tab
            l.append(s[p:i].rstrip() + "\t")
            p = i

    if p == 0:
        return s
    else:
        l.append(s[p:])
        return "".join(l)



def main():
    try:
        name = sys.argv[1]
        assert open(name, "a")
    except:
        sys.stderr.write(__doc__)
        return
    EditDisplay(name).main()


if __name__=="__main__":
    main()

在这里检查: http://urwid.org/reference/widget.html#urwid.Frame

有更新插件功能吗?

python command-line-interface urwid
© www.soinside.com 2019 - 2024. All rights reserved.