跳至主要內容
  • Hostloc 空間訪問刷分
  • 售賣場
  • 廣告位
  • 賣站?

4563博客

全新的繁體中文 WordPress 網站
  • 首頁
  • 分享一个 Python 命令行下列表选择
未分類
21 11 月 2020

分享一个 Python 命令行下列表选择

分享一个 Python 命令行下列表选择

資深大佬 : lswang 3

可以通过上下键 + Enter 来选择,Ctrl+C 取消

[注意] 只能支持 linux + macos

超过 20 个数据,会出现 ==== ^ ==== 和 ==== v ==== 提示还有额外数据

# -*- coding: utf-8 -*- import sys import termios import tty   left = u'u001b[1000D' right = u'u001b[1000C' clear_line = u'u001b[2K' up = u'u001b[1A' down = u'u001b[1B' clear_to_bottom = u'u001b[J'  MAX_SHOW_COUNT = 20  class CommandSingleSelector:     selectors = None     cur_index = 0     cursor_index = -1     header_word = None     is_cancel = False     top_index = 0     bottom_index = 0      def __init__(self, selectors, header_word):         self.selectors = selectors         if len(selectors) > MAX_SHOW_COUNT:             self.bottom_index = MAX_SHOW_COUNT         else:             self.bottom_index = len(selectors) - 1          self.header_word = header_word      def up(self):         if self.cur_index > 0:             self.cur_index = self.cur_index - 1             if self.cur_index < self.top_index:                 self.top_index = self.top_index - 1                 self.bottom_index = self.bottom_index - 1             self.print_multi_line()      def down(self):         if self.cur_index < len(self.selectors) - 1:             self.cur_index = self.cur_index + 1             if self.cur_index > self.bottom_index:                 self.top_index = self.top_index + 1                 self.bottom_index = self.bottom_index + 1             self.print_multi_line()      def exit(self):         self.clear_multi_line()      def get_selector(self):         sys.stdout.write(self.header_word + 'n')         self.print_multi_line()         is_multi_first = False         is_multi_second = False          while True:             fd = sys.stdin.fileno()             old_settings = termios.tcgetattr(fd)             try:                 tty.setraw(sys.stdin.fileno())                 ch = sys.stdin.read(1)                 as_code = ord(ch)                  # find the multi key for up/down                 if as_code == 27:                     is_multi_first = True                 elif as_code == 91:                     if is_multi_first:                         is_multi_second = True                 elif as_code == 65:                     if is_multi_first and is_multi_second:                         self.up()                     is_multi_second = False                     is_multi_first = False                 elif as_code == 66:                     if is_multi_first and is_multi_second:                         self.down()                     is_multi_second = False                     is_multi_first = False                 elif as_code == 13:                     is_multi_second = False                     is_multi_first = False                     self.exit()                     break                 elif as_code == 3:                     is_multi_second = False                     is_multi_first = False                     self.exit()                     self.is_cancel = True                     break                 else:                     is_multi_second = False                     is_multi_first = False             finally:                 termios.tcsetattr(fd, termios.TCSADRAIN, old_settings)          if self.is_cancel:             raise Exception('Cancel this operation.')          return self.selectors[self.cur_index]      def print_multi_line(self):         sys.stdout.write((self.cursor_index + 1) * up + left)         sys.stdout.write(clear_to_bottom)          up_size = self.bottom_index - self.cur_index + 1 + 1 + 1 # first and last word          has_first_sign = '          '         if self.top_index > 0:             has_first_sign = '   ==== ^ ===='          sys.stdout.write(left + clear_line + has_first_sign + 'n')           for index, item in enumerate(self.selectors):             if self.top_index <= index <= self.bottom_index:                 first_word = '   '                 if index == self.cur_index:                     first_word = ' > '                     sys.stdout.write(left + clear_line + first_word + item + 'n')                 else:                     sys.stdout.write(left + clear_line + first_word + item + 'n')         has_last_sign = '          '         if len(self.selectors) - 1 > self.bottom_index:             has_last_sign = '   ==== v ===='         sys.stdout.write(left + clear_line + has_last_sign + 'n')          back_to_cur_index = up * (up_size -1)         self.cursor_index = self.cur_index - self.top_index         sys.stdout.write(back_to_cur_index)         sys.stdout.write(left)      def clear_multi_line(self):         back_to_top = up * (self.cur_index - self.top_index + 2)         sys.stdout.write(back_to_top)         sys.stdout.write(left)         sys.stdout.write(clear_to_bottom)   if __name__ == '__main__':     selectors = ['HP Printer', 'XiaoMi Printer','DELL Printer']     command_selector = CommandSingleSelector(selectors=selectors, header_word='Please Select One Printer: ')     try:         sel = command_selector.get_selector()         print sel     except Exception, e:         print e.message  

大佬有話說 (4)

  • 資深大佬 : lisniuse

    可以来这里分享: https://www.kuxai.com/forum

  • 資深大佬 : ClericPy

    以前倒是折腾过类似 terminal UI 的, 有三个库印象深刻 PyInquirer, console-menu, questionary

    还好我只 star 最好的, 所以还能找到

  • 資深大佬 : renmu123

    我最近再用一个 poetry 出品的 celo 工具,也是类似的交互式命令行工具,相比上的几个,弱化了交互式组件的部分,增强了作为命令行的部分(其实完全可以拼一起造个融合怪)

  • 資深大佬 : frostming

    Paging 嘛,rich 有现成的支持,prompt_toolkit 也有

文章導覽

上一篇文章
下一篇文章

AD

其他操作

  • 登入
  • 訂閱網站內容的資訊提供
  • 訂閱留言的資訊提供
  • WordPress.org 台灣繁體中文

51la

4563博客

全新的繁體中文 WordPress 網站
返回頂端
本站採用 WordPress 建置 | 佈景主題採用 GretaThemes 所設計的 Memory
4563博客
  • Hostloc 空間訪問刷分
  • 售賣場
  • 廣告位
  • 賣站?
在這裡新增小工具