前言
在目前的系统设计中,常见的是窗口设计开发。因此我想做一款基于命令框的系统,同时带有一定的美观性。成果如下图所示。存C语言也能够实现这些功能,有兴趣,做一期这样的介绍。
Rich 是一个 Python 库,用于将富文本(带有颜色和样式)写入终端,并用于显示高级内容,例如表格、markdown 和语法高亮代码。
引入库
我们需要用到 rich 库。
pip install rich
数据存储
这里数据存储我就使用Json文本格式对数据进行存储
- 菜单数据
格式如下
[
{"id": 0, "type": "主食", "list": [
{"id": 0, "name": "米饭", "price": 2},
{"id": 1, "name": "馒头", "price": 1},
{"id": 2, "name": "面条", "price": 3}
]
},
{
"id": 1,
"type": "热菜",
"list": [
{"id": 0, "name": "红烧肉", "price": 28},
{"id": 1, "name": "地三鲜", "price": 18},
{"id": 2, "name": "宫保鸡丁", "price": 25}
]
},
{
"id": 2,
"type": "凉菜",
"list": [
{"id": 0, "name": "拍黄瓜", "price": 9},
{"id": 1, "name": "凉拌黄瓜", "price": 12},
{"id": 2, "name": "凉拌皮蛋", "price": 15}
]
},
{
"id": 3,
"type": "饮料",
"list": [
{"id": 0, "name": "可乐", "price": 3},
{"id": 1, "name": "雪碧", "price": 3},
{"id": 2, "name": "矿泉水", "price": 2}
]
},
{
"id": 4,
"type": "酒水",
"list": [
{"id": 0, "name": "白酒", "price": 38},
{"id": 1, "name": "啤酒", "price": 5}
]
}
]
用python进行读取
# 菜单
with open("res/menu.json", 'r', encoding="utf-8") as fp:
menu = json.load(fp)
- 评论数据
格式如下
["味道不错,下次还来!", "服务态度很好,下次还来!", "菜品很新鲜,下次还来!", "价格实惠,下次还来!", "环境很好,下次还来!"]
python读取
# 评论
with open("res/comment.json", 'r', encoding="utf-8") as fp:
comment = json.load(fp)
- 点菜数据
用python读取
# 点餐记录
orders_path = "res/orders.json"
with open(orders_path, 'r', encoding="utf-8") as fp:
orders = json.load(fp)
界面设计
启动加载页
该页面用于数据加载。但是实际上,我这里做的特别简单。知识有着样式,一个不实用的功能。
def start():
"""
启动页
:return:
"""
os.system("cls")
panel_group = Group(
Padding(Text.assemble("欢迎使用", ("点餐系统", "rgb(219,122,112)"), justify="center"), (5, 0)),
)
print(Panel(panel_group, title="Welcome", subtitle="点餐系统", border_style="rgb(113,112,219)"))
with Progress() as progress:
task = progress.add_task("{}[red]loading...".format(" " * 20), total=1000)
while not progress.finished:
progress.update(task, advance=5)
sleep(0.005)
PageIndex()
首页面
用 up down键来选择
import msvcrt
import sys
# 首页功能列表
indexFun = [
{"id": 0, "name": "点餐", "fun": PageOrder},
{"id": 1, "name": "查看未出单", "fun": NoOrderIssued},
{"id": 2, "name": "查看已出单", "fun": OrderIssued},
{"id": 3, "name": "退出", "fun": lambda: exit()}
]
def drawIndex(row):
"""
绘画首页面
"""
os.system("cls")
text = Text(justify="center")
text.append("请选择以下的功能:\n\n")
for i in range(len(indexFun)):
if i == row:
text.append("-{}- {}\n".format(indexFun[i]["id"], indexFun[i]["name"]), style="rgb(0,0,255)")
else:
text.append("-{}- {}\n".format(indexFun[i]["id"], indexFun[i]["name"]))
print(Panel(Padding(text, (2, 0)), title="Welcome", subtitle="点餐系统", border_style="rgb(113,112,219)"))
print("up 上移\tdown 下移\tenter 选择")
def PageIndex():
"""
首页面
:return:
"""
os.system("cls")
row = 0
drawIndex(row)
while True:
if msvcrt.kbhit(): # 检查是否有按键事件
choose = msvcrt.getch() # 获取字符,不需要回车确认
sys.stdout.flush() # 刷新输出缓冲区,确保字符立即显示
if ord(choose) == 72:
if row == 0:
row = len(indexFun) - 1
else:
row -= 1
drawIndex(row)
elif ord(choose) == 80:
if row == len(indexFun) - 1:
row = 0
else:
row += 1
drawIndex(row)
elif ord(choose) == 13:
indexFun[row]["fun"]()
break
点餐页
# 点餐单
console = Console()
order = []
def PageOrder():
"""
点餐页
:return:
"""
os.system("cls")
layout = Layout()
layout.split_column(
Layout(Panel(Text("菜单", justify="center", style="white on red")), size=3),
Layout(name="lower")
)
tables = []
for m in menu:
table = Table()
table.add_column("菜号", justify="center", style="cyan", no_wrap=True)
table.add_column("菜名", justify="center", style="cyan", no_wrap=True)
table.add_column("价格", justify="center", style="magenta")
for l in m["list"]:
table.add_row("{}-{}".format(m["id"], l["id"]), l["name"], "{}¥".format(float(l["price"])))
tables.append(table)
panel_left = Panel(Columns(tables, equal=True, expand=True), border_style="rgb(113,112,219)", title="菜单",
title_align="left")
layout["lower"].split_row(
Layout(panel_left, ratio=3),
Layout(Panel(Columns(comment, equal=True, expand=True), border_style="rgb(113,112,219)", subtitle="评论"))
)
print(layout)
while 1:
choose = Prompt.ask("请输入需要点菜的编号(e 返回首页)(o 完成|修改)", default="e")
if choose == "e":
PageIndex()
break
if choose == "o":
total = 0.0
table = Table()
for name in ["菜类型", "菜名", "价格", "数量", "总价"]:
table.add_column(name, justify="center", style="cyan")
with Live(table, refresh_per_second=4) as live:
for orde in order:
sleep(0.4)
total += orde["price"] * orde["num"]
table.add_row(orde["type"], orde["name"],
"{}¥".format(orde["price"]), str(orde["num"]),
"{}¥".format(orde["price"] * orde["num"]))
table.add_row("-", "-", "-", "-", "-")
table.add_row("", "", "", "", "{}¥".format(total))
choose = Prompt.ask("--1 提交 - 2 修改 - 3 返回首页--", choices=["1", "2", "3"], default="1")
if choose == "1":
orders.append(order)
with open(orders_path, "w+", encoding="utf-8") as f:
orders.append({"time": time.asctime(time.localtime(time.time())), "order": order, "type": False})
json.dump(orders, f)
with console.status("出票中...", spinner="hearts"):
print("购买成功")
for i in range(10):
time.sleep(0.2)
PageIndex()
break
elif choose == "2":
c = Prompt.ask("请选择需要修改的行号(从1开始),以及份数.格式为:行号-份数(或者行号,默认0)")
try:
c = c.split("-")
if len(c) == 1:
order[int(c[0]) - 1]["num"] = 0
else:
order[int(c[0]) - 1]["num"] = int(c[1])
except:
print("[red]输入有误[/red]")
elif choose == "3":
PageIndex()
break
try:
num = [int(i) for i in choose.split("-")]
except:
print("[red]输入的内容错误!!![/red]")
if len(num) == 2:
o = {"type": "", "name": "", "price": 0.0, "num": 0}
for m in menu:
if m["id"] == num[0]:
o["type"] = m["type"]
for l in m["list"]:
if l["id"] == num[1]:
o["name"] = l["name"]
o["price"] = l["price"]
break
break
if o["type"] == "":
print("[red]没有该菜类!!![/red]")
elif o["name"] == "":
print("[red]没有该菜品!!![/red]")
else:
while True:
choose = Prompt.ask("请输入需要该菜品的数量(默认1份): ", default="1")
try:
n = int(choose)
o["num"] = n
order.append(o)
break
except:
print("[red]输入的值类型错误[/red]")
else:
print("[red]输入格式有误!!![/red]")
单子查看
def issuedCommon(oss):
"""
单子展示样式函数
"""
total = 0.0
table = Table()
for name in ["时间", "菜类型", "菜名", "价格", "数量", "总价"]:
table.add_column(name, justify="center", style="cyan")
with Live(table, refresh_per_second=4) as live:
for o in oss["order"]:
sleep(0.4)
total += o["price"] * o["num"]
table.add_row(oss["time"], o["type"], o["name"],
"{}¥".format(o["price"]), str(o["num"]),
"{}¥".format(o["price"] * o["num"]))
table.add_row("-", "-", "-", "-", "-", "-")
table.add_row("", "", "", "", "", "{}¥".format(total))
def NoOrderIssued():
"""
未出单
:return:
"""
os.system("cls")
temp = []
for oss in orders:
if not oss["type"]:
temp.append(oss)
issuedCommon(oss)
choose = Prompt.ask("请输入要出单的行号(从1开始,错误输入返回首页面)")
try:
for i in range(len(orders)):
if temp[int(choose) - 1]["time"] == orders[i]["time"]:
orders[i]["type"] = True
with open(orders_path, "w+", encoding="utf-8") as f:
json.dump(orders, f)
with console.status("修改中...", spinner="monkey"):
print("出单成功")
for i in range(10):
time.sleep(0.2)
break
else:
with console.status("出单失败...", spinner="monkey"):
print("出单失败")
for i in range(10):
time.sleep(0.2)
break
PageIndex()
except:
PageIndex()
def OrderIssued():
"""
已出单
:return:
"""
os.system("cls")
for oss in orders:
if oss["type"]:
issuedCommon(oss)
console.input("任意键返回")
PageIndex()
# 首页功能列表
indexFun = [
{"id": 0, "name": "点餐", "fun": PageOrder},
{"id": 1, "name": "查看未出单", "fun": NoOrderIssued},
{"id": 2, "name": "查看已出单", "fun": OrderIssued},
{"id": 3, "name": "退出", "fun": lambda: exit()}
]
总结
这总简单的系统,代码就这么多了。最后,运行的时候主要在电脑的 cmd上运行。编译器上带的终端里面有些样式也 看不见。有问题,或者不懂的,直接问都可以。后面出C语言版本的。