【问题标题】:How to add scrolling in a textbox in curses?如何在curses的文本框中添加滚动?
【发布时间】:2021-11-29 05:33:36
【问题描述】:

目前,当我们到达文本框区域的末尾时,我们只是移动到框外的下一行。如何实现滚动,以便当我们到达末尾并尝试移动到下一行时,顶行消失并且整个文本正文向上移动?

例如:

+-------+
|hello1 |
|hello2 |
|hello3 |
|hello4 |
|hello5 |
+-------+

回车后:-

+-------+
|hello2 |
|hello3 |
|hello4 |
|hello5 |
|       |
+-------+

这是代码,我知道 curses 的文本板,但这不是我需要的。

import curses
from curses import textpad
import time

class notepad:
    def __init__(self, stdscr, topleft, bottomright, starttext = ""):
        self.topleft = topleft
        self.bottomright = bottomright
        self.stdscr = stdscr
        self.text = starttext
        self.curspos = 0

    def box(self):
        curses.textpad.rectangle(self.stdscr, self.topleft[0], self.topleft[1], self.bottomright[0], self.bottomright[1])

    def get_input(self, key):

        if not key == -1:

            if key == curses.KEY_LEFT:
                self.curspos -= 1

            elif key == curses.KEY_RIGHT:
                if self.curspos < len(self.text):
                    self.curspos += 1

            elif key == curses.KEY_UP:
                self.curspos -= self.width

            elif key == curses.KEY_DOWN:
                if self.curspos//self.width < len(self.text)//self.width:
                    self.curspos += self.width - (self.curspos%self.width - len(self.text)%self.width)

            elif key == curses.KEY_BACKSPACE:
                self.text = self.text[:self.curspos][:-1] + self.text[self.curspos:]
                self.curspos -= 1

            elif key == curses.KEY_ENTER or key == 10 or key == 13:
                self.text = self.text[:self.curspos] + " "*(self.width - (len(self.text[:self.curspos])%self.width)) + self.text[self.curspos:]
                self.curspos += 1
                self.curspos += self.width - (self.curspos%self.width - len(self.text)%self.width)

            else:
                self.text = self.text[:self.curspos] + chr(key) + self.text[self.curspos:]
                self.curspos += 1

    def display(self):
        self.width = (self.bottomright[1]-1) - (self.topleft[1]+1)

        if self.curspos < 0:
            self.curspos = 0


        #disply text
        for i in range(len(self.text)):
            self.stdscr.addstr( self.topleft[0]+1 + (i//self.width) , 
                                self.topleft[1]+1 +i%self.width  , 
                                self.text[i]
                                )
            
        #display fake cursor
        if self.curspos < len(self.text):
            self.stdscr.addstr(self.topleft[0]+1 + (self.curspos//self.width) , self.topleft[1]+1 + self.curspos%self.width, self.text[self.curspos], curses.A_REVERSE)
        else:
            self.stdscr.addstr(self.topleft[0]+1 + (self.curspos//self.width) , self.topleft[1]+1 + self.curspos%self.width, " ", curses.A_REVERSE)
        
def main():
    run = True
    stdscr = curses.initscr()
    stdscr.nodelay(True)
    stdscr.keypad(True)
    curses.curs_set(False)
    curses.start_color()
    curses.noecho()
    curses.cbreak()

    notepad1 = notepad(stdscr, [0,0], [20, 30])

    try:
        while run:
            start = time.time()

            stdscr.erase()

            key = stdscr.getch()

            notepad1.box()
            notepad1.get_input(key)
            notepad1.display()

            stdscr.refresh()


            time.sleep(max(0.05 - (time.time() - start), 0))
    finally:
        curses.echo()
        curses.nocbreak()
        curses.curs_set(True)
        stdscr.keypad(False)
        stdscr.nodelay(False)
        curses.endwin()

main()

【问题讨论】:

  • 你能不能简单地说:self.text = self.text[self.width:] 放弃顶行?
  • 这将删除我想要保留的第一行的内容
  • 由应用程序来管理滚动。作为一种快捷方式,curses 提供了 pad 功能,它是 python curses 接口的一部分。
  • 然后您将需要跟踪文本的起始偏移量并适应显示例程。

标签: python curses python-curses


【解决方案1】:

由于您评论说您想保留文本但将其滚动到屏幕外,因此您需要在 init 中使用类似的内容:

self.scroll_lines = 0

然后当你想向下滚动一行时,只需使用:

 self.scroll_lines += 1

你的显示功能看起来像这样:

 #disply text
 text_offset = self.scroll_lines*self.width
 for i in range(text_offset, len(self.text)):
        self.stdscr.addstr( self.topleft[0]+1 + (i//self.width-self.scroll_lines) , 
                            self.topleft[1]+1 +i%self.width  , 
                            self.text[i]
                            )

我将把它作为练习留给你正确放置光标。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2010-10-10
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-08-20
    相关资源
    最近更新 更多