前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >实现类似于top一样的效果用于数据展示

实现类似于top一样的效果用于数据展示

原创
作者头像
Michel_Rolle
发布2024-01-19 21:45:15
2.2K0
发布2024-01-19 21:45:15
举报
文章被收录于专栏:Python技术专栏

实现类似于top一样的效果用于数据展示

因为有这样的需求

  1. 想要在terminal里不断刷新一些数据,就类似于输入top命令一样
  2. 但是又不想刷新的这种数据以print的方式输出

大概有这样一些要求。表头固定,然后表头以下的行数据一直不停的刷新。可以实现指定键退出等

发现了一个Python的 curses模块 来实现这个效果

初步代码

代码语言:javascript
复制
import curses
import time

def main(stdscr):
    # 禁止光标显示
    curses.curs_set(0)

    # 获取终端窗口的大小
    max_y, max_x = stdscr.getmaxyx()

    # 打印固定的文本
    stdscr.addstr(0, 0, "Fixed text that will not change")

    # 无限循环,不断刷新终端窗口
    while True:
        # 获取当前时间,并将其格式化为字符串
        time_str = time.strftime("%Y-%m-%d %H:%M:%S", time.localtime())

        # 清除终端窗口
        stdscr.clear()

        # 打印固定的文本
        stdscr.addstr(0, 0, "Fixed text that will not change")

        # 打印变化的文本
        stdscr.addstr(1, 0, "Current time is: {}".format(time_str))

        # 刷新终端窗口
        stdscr.refresh()

        # 等待一段时间
        time.sleep(1)

# 运行程序
curses.wrapper(main)

该程序在屏幕上打印出固定的文本Fixed text that will not change,并在下一行打印出当前时间,然后不断刷新屏幕,每秒钟更新一次当前时间。在刷新屏幕时,固定的文本不会变化,而变化的文本会更新。这个效果就和输入top命令后一样了。

addstr()是curses模块中用于向终端窗口添加字符串的函数。它的语法如下:

代码语言:javascript
复制
addstr(y, x, str, attrs)

其中,y和x分别表示字符串的行号和列号,从0开始计数,即左上角的坐标为(0, 0)。str表示要添加的字符串,可以是任意长度的字符串。attrs是可选参数,用于设置文本的属性,比如颜色、加粗、下划线等。如果不指定该参数,则默认使用终端窗口的当前属性。

addstr()函数的返回值是一个整数,表示添加的字符串的长度。

在curses模块中还有许多其他的函数,用于控制光标位置、清空终端窗口、设置颜色等。具体用法可以参考curses模块的文档。

制作类似于表格一样的

代码语言:javascript
复制
import curses
import time

def main(stdscr):
    # 禁止光标显示
    curses.curs_set(0)

    # 获取终端窗口的大小
    max_y, max_x = stdscr.getmaxyx()

    # 表格的列数
    num_cols = 3

    # 表格中每列的宽度
    col_width = max_x // num_cols

    # 表头
    header = ["Name", "Age", "Score"]

    # 表格数据
    data = [
        ["Alice", "20", "90"],
        ["Bob", "22", "85"],
        ["Charlie", "21", "95"],
    ]

    # 无限循环,不断刷新终端窗口
    while True:
        # 获取当前时间,并将其格式化为字符串
        time_str = time.strftime("%Y-%m-%d %H:%M:%S", time.localtime())

        # 清除终端窗口
        stdscr.clear()

        # 打印固定的文本
        stdscr.addstr(0, 0, "Fixed text that will not change")

        # 打印表头
        for i, col_name in enumerate(header):
            stdscr.addstr(2, i * col_width, col_name.center(col_width))

        # 打印表格数据
        for row_num, row_data in enumerate(data):
            for col_num, cell_data in enumerate(row_data):
                stdscr.addstr(
                    row_num + 3,
                    col_num * col_width,
                    cell_data.center(col_width)
                )

        # 打印变化的文本
        stdscr.addstr(8, 0, "Current time is: {}".format(time_str))

        # 刷新终端窗口
        stdscr.refresh()

        # 等待一段时间
        time.sleep(1)

# 运行程序
curses.wrapper(main)

在这个代码中,定义了一个表格,包括表头和表格数据。使用addstr()函数打印出表格,并将其固定在终端窗口的上方。随后,不断更新表格数据,并将其打印在表格下方。其他部分和之前的示例程序相同。

在打印表格时,使用center()函数对字符串进行居中对齐。center()函数的语法如下:

代码语言:javascript
复制
center(width, fillchar)

其中,width表示要居中对齐的宽度,fillchar是可选参数,用于指定填充字符。如果不指定该参数,则默认使用空格。

需要注意的是,这个示例程序中的表格只适用于终端窗口的大小,如果终端窗口太小,表格就会超出终端窗口。如果需要适应不同大小的终端窗口,需要动态计算表格的列宽和行高。

也可加入 指定键 用来退出

代码语言:javascript
复制
key = self.stdscr.getch()
      if key == ord('q'):  # 如果用户按下 'q' 键
          break  # 退出循环

完整代码

代码语言:javascript
复制
import curses
import os, sys

BASE_DIR = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
sys.path.append(BASE_DIR)


class StdScr:
    def __init__(self, stdscr):
        self.stdscr = stdscr
        """
        """

    def run(self):
        # 禁止光标显示
        curses.curs_set(0)

        # 获取终端窗口的大小
        max_y, max_x = self.stdscr.getmaxyx()

        # 表头
        header = ["Alice", "20", "90"]

        # 表格的列数
        num_cols = len(header)

        # 表格中每列的宽度
        col_width = max_x // num_cols

        # 表格数据
        data = [
           ["Alice", "20", "90"]
        ]


        # 无限循环,不断刷新终端窗口
        while True:

            # 获取当前时间,并将其格式化为字符串
            time_str = time.strftime("%Y-%m-%d %H:%M:%S", time.localtime())

            # 清除终端窗口
            self.stdscr.clear()

            # 打印固定的文本
            self.stdscr.addstr(0, 0, "Fixed text that will not change")


            # 打印表头
            for i, col_name in enumerate(header):
                self.stdscr.addstr(2, i * col_width, col_name.center(col_width))

            # 打印表格数据
            for row_num, row_data in enumerate(data):
                for col_num, cell_data in enumerate(row_data):
                    self.stdscr.addstr(
                        row_num + 3,
                        col_num * col_width,
                        str(cell_data).center(col_width)
                    )

            # 打印变化的文本
            self.stdscr.addstr(8, 0, "Current time is: {}".format(time_str))

            # 刷新终端窗口
            self.stdscr.refresh()

            # 等待一段时间
            time.sleep(3)
            # 可以使用 stdscr.getch() 来获取输入
            key = self.stdscr.getch()
            if key == ord('q'):  # 如果用户按下 'q' 键
                break  # 退出循环
        curses.endwin()


def main(stdscr):
    my_app = StdScr(stdscr)
    my_app.run()


if __name__ == '__main__':
    curses.wrapper(main)

我正在参与2024腾讯技术创作特训营第五期有奖征文,快来和我瓜分大奖!

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 实现类似于top一样的效果用于数据展示
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档