首页 > 编程语言 >2023-02-18-我写了一个python库dumb_meun

2023-02-18-我写了一个python库dumb_meun

时间:2023-10-09 19:26:34浏览次数:58  
标签:02 index return python 18 selected key menu options

+++
title = "我写了一个python库:dumb_meun"
description = ""
date = 2023-02-18T16:19:07+08:00
featured = false
comment = true
toc = true
reward = true
categories = [
""
]
tags = [
"python"
]
series = []
images = []
+++

我之前再我的程序里面 用了一个第三方库:simple_term_menu,提供菜单功能。但是当我再windows上尝试跑一下终于写好的程序时,竟然不能用。原因是它依赖于 termios 库, 不支持 win 。
因为我的功能需求比较简单,我决定自己下一个代替品,就是这个 dumb_meun 了。

主要要实现的功能:

  • 传入一个 list ,显示菜单, 返回选中的 index
    • 上下键选择
    • enter建确认
    • *支持快捷键

因为python没有提供类似于c语言中的getchar函数,再 linux 上用 termios 库可以实现,但是在windows上使用的是 msvcrt 库。所以实际上在 python 中实现起来不是很容易。

def get_key(): #get keypress using getch , msvcrt = windows or termios = linux
    try :
        import getch
        first_char = getch.getch()
        if first_char == '\x1b': #arrow keys
            a=getch.getch()
            b=getch.getch()
            return {'[A': 'up', '[B': 'down', '[C': 'right', '[D': 'left' }[a+b]
        if ord(first_char) == 10:
            return  'enter'
        if ord(first_char) == 32:
            return  'space'
        else:
            return first_char #normal keys like abcd 1234
    except :
        pass
    try:
        import msvcrt
        key = msvcrt.getch()  # get keypress
        if key == b'\x1b':  # Esc key to exit
            return 'esc'
        elif key == b'\r':  # Enter key to select
            return 'enter'
        elif key == b'\x48':  # Up or Down arrow
            return  'up'
        elif key == b'\x50':  # Up or Down arrow
            return 'down'
        else:
            return key.decode('utf-8')
    except:
        pass

while True:
    key = get_key()
    print("You pressed: ", key)

这个函数可以获取键盘输入,返回值是一个字符串,比如up down / enter / a b c / 1 2 3,这样统一一下,可以兼容linux 和 win。

测试结果:

Press a key to test out!
You pressed:  down
You pressed:  up
You pressed:  a
...

我拷问了chatgpt老半天,他才给我编好

后补充的流程图

  • 提取快捷键是用 re 库的正则表达式

  • 显示菜单通过 os.system("cls" if os.name == "nt" else "clear") 清屏,再打印出来,每次给菜单传入 list 和选中的 index ,这样用户可以看到自己正在选择哪个。

import os
import re
def get_menu_choice(options):
    shortcuts = scan_short_cuts(options)  # scan for shortcuts
    selected_index = 0
    print(shortcuts)
    while True:
        show_menu(options, selected_index)
        key = get_key()
        if key == 'enter':  # Enter key to select
            return selected_index
        elif key in ('up','down'):  # Up or Down arrow
            selected_index = (selected_index + (1 if key == 'down' else -1) + len(options)) % len(options)
        elif key in shortcuts:  # Shortcut key
            show_menu(options, shortcuts[key]) #show selected option when using shortcut
            return shortcuts[key]

def scan_short_cuts(options):
    shortcuts = {}
    for i, option in enumerate(options):
        match = re.match(r"\[(.*)\](.*)", option)
        if match:
            shortcut, text = match.group(1, 2)
            shortcuts[shortcut] = i
    return shortcuts


def show_menu(options, selected_index):
    os.system("cls" if os.name == "nt" else "clear")
    print("Menu","current option:",selected_index)
    for i, option in enumerate(options):
        if i == selected_index:
            print(f"> {option}")
        else:
            print(f"  {option}")
    print("\nUse the arrow keys to move, Enter/Hotkey to select.")

使用方法非常直白:

options = ["[1]Option 1", "[2]Option 2", "[3]Option 3","[q]quit"]
index = get_menu_choice(options)
print(f"You selected option {index + 1}: {options[index]}")

看看效果:

代码地址

其实我一开始想要参考一下 simple_term_menu 的源码,但是我发现我太菜了,根本看不懂他们的贼复杂的源代码(还用了信号啥的,我都不会),所以我就自己写了一个简单的。

使用的话就:

pip install dumb-menu

可以看看我在 pypi 写的简明教程

标签:02,index,return,python,18,selected,key,menu,options
From: https://www.cnblogs.com/kasusa/p/17752923.html

相关文章

  • 2023-02-18-python打包成exe
    +++title="如何把Python程序打包成exe"description=""date=2023-02-18T22:27:09+08:00featured=falsecomment=truetoc=truereward=truecategories=[""]tags=["python"]series=[]images=[]+++我需要把我......
  • 2023-02-18-python打包
    +++title="Python打包和上传到pypi"description=""date=2023-02-18T21:59:09+08:00featured=falsecomment=truetoc=truereward=truecategories=[""]tags=["python"]series=[]images=[]+++教程用pyth......
  • 2023-02-09-使用simple_term_menu创建更好的python菜单
    +++title="用simple_term_menu创建更好的python菜单"description=""date=2023-02-09T16:25:24+08:00featured=falsecomment=truetoc=truereward=truecategories=[""]tags=["python","menu"]seri......
  • 2023-02-09-dbdiagram
    +++title="Dbdiagram.io,数据库设计的好选择"description=""date=2023-02-09T16:01:23+08:00featured=falsecomment=truetoc=truereward=truecategories=[""]tags=["database","free"]series=[]......
  • 2023.10.9——每日总结
    学习所花时间(包括上课):0h代码量(行):0行博客量(篇):1篇今天,上午学习,下午学习;我了解到的知识点:1.DIV+CSS;明日计划:学习......
  • python29days
    继承单继承下的属性查找多继承下的属性查找super和mro的使用多态和鸭子类型—————————————————————————————————————————————————面向对象的三大特征:封装,继承,多态什么是继承?继承就是让类和类之......
  • [BJDCTF2020]ZJCTF,不过如此
    原理关于preg_replace\e的代码执行双引号和单引号的区别可变变量解题过程代码审计<?phperror_reporting(0);$text=$_GET["text"];$file=$_GET["file"];if(isset($text)&&(file_get_contents($text,'r')==="Ihaveadream")){echo......
  • LY1380 [ 20231009 NOIP 模拟赛 T1 ] AK 神
    题意给定长度为\(n\)的序列\(S\)。\(A\),\(B\)两人轮流取连续\(k\)个数,保证\(n\equiv1\pmodk\)。\(A\)使最终数字更小,\(B\)使最终数字更大。问取到数的和。Sol直接考虑每次选哪些数,怎么选显然是不好做的。不难发现\(n\equiv1\pmodk\)的条件。题面提示我们......
  • Win10安装VSCode并配置Python环境(完美避开踩过的所有坑)
    安装VScode下载vscode下载链接:https://code.visualstudio.com/Download根据自己的电脑型号下载对应的版本。我下载的是windows/UserInstaller,但是使用时会提示“”。所以,推荐下载SystemInstaller版本。两者区别可以自行百度,或......
  • VS code+python环境部署
    安装VScode下载vscode下载链接:https://code.visualstudio.com/Download根据自己的电脑型号下载对应的版本。我下载的是windows/UserInstaller,但是使用时会提示“”。所以,推荐下载SystemInstaller版本。两者区别可以自行百度,或......