python控制台中怎么控制开始和结束_Python3实践之:控制台时钟

0、问题描述

对于Python3的初学者来说,大部分时候,都是在写一些简单的控制台(console)程序。但如果你掌握了curses的用法,那么你就可以让你的程序表现丰富起来。利用curses,在console上,你就可以做一些简单的有交互性的应用,甚至做一些简单的游戏。以后,我们向大家展示如何使用curses做一些经典的游戏。

本文将教你如何用curses,在console实现一个时钟。这个时钟在控制台(屏幕)中展示当前的日期、星期和时间,秒数还会跳动。(效果请看封面图片)

不过,在阅读本文之前,你可能需要首先掌握datetime和curses的基本用法。以下是我推荐的几个介绍datetime和curses的网站,你可以各挑一个阅读了解。

介绍datetime的中文博客:Python datetime模块详解​www.cnblogs.com

datetime的Python官网文档:datetime - Basic date and time types - Python 3.8.2 documentation​docs.python.org

介绍curses的中文博客:CSDN-专业IT技术社区-登录​blog.csdn.net【译】Python Curses 编程​www.jianshu.comv2-2281f86b69d9587bdc3e6660f90c3043_ipico.jpg

curses的Python官网文档:Curses Programming with Python​docs.python.org

如果你使用的是Linux操作系统,并且安装了Python3,那么你很有可能已经可以直接使用curses库了。我使用的是ubuntu,安装的Python3是自带安装了curses库的。

但如果你使用windows,你需要自己安装curses。在下载curses的windows包的时候,一定要选择和你的Python版本相同的curses包。以下是一篇关于curses安装的中文博客:Windows安装Python3 curses模块​www.cnblogs.comv2-4a51de622fdaf83701fe185d41738674_180x120.jpg

本文将用面向过程(POP)和面向对象(OOP)两种方式来实现控制台时钟的功能。为了更加直观地展示各个细节的实现步骤和原理,POP版本会用比较简单粗暴的方式去实现。在OOP中,我们会对POP版本的一些代码进行优化,并引用一些POP版本没有用到的curses特性。

1、curses的基本用法

这个小节会对curses的使用进行一个简单的介绍,如果你想更好的了解curses,请阅读我在上一个小节中推荐的文章。

在使用curses的时候,有一个通用的流程。启动的时候,包括创建curses屏幕对象,一些基本的设置;结束的时候,撤销原来的设置,最后关闭屏幕对象。通用流程如下面代码所示:

# 导入curses模块

import curses

def SayHello(stdscr):

# 使用addstr将字符串输出的屏幕

# 注意:第一个参数是y坐标,第二个参数是x坐标

stdscr.addstr(0, 0, "Hello World!")

stdscr.addstr(1, 0, "Press Any Key To Exit...")

# 阻塞式等待键盘输入

stdscr.getch()

# 初始化屏蔽,得到屏蔽对象stdscr

# 正如你所理解的 scr将screen的前三个字母

stdscr = curses.initscr()

# 设置一

# 监听屏蔽输入,并且不在屏蔽显示输入的字符

curses.noecho()

# 设置二

# 在用户不敲击回车键的情况下,直接影响用户的键盘输入

curses.cbreak()

# 设置三

# 监听特殊键,如左向键、向右键、PgUp、PgDn等

stdscr.keypad(True)

# 经过以上步骤,你就可以操作屏蔽,展示你的内容啦

SayHello(stdscr)

# 程序结束之前,你必须对之前的几步设置进入反向操作

# 否则,控制的显示会出错乱

curses.nocbreak() # 设置三反操作

stdscr.keypad(False) # 设置二反操作

curses.echo() # 设置一反操作

# 关闭屏蔽

curses.endwin()

因为这个流程很常见,所以curses库提供了wrapper方法。wrapper会帮我们处理好屏幕的创建和关闭、屏幕的设置和反设置等的相关步骤, 我们只需要实现跟自己功能相关的逻辑就可以了。所以上面的功能,可以简化成下面的实现:

# 导入curses模块

import curses

def SayHello(stdscr):

stdscr.addstr(0, 0, "Hello World!")

stdscr.addstr(1, 0, "Press Any Key To Exit...")

# 阻塞式等待键盘输入

stdscr.getch()

curses.wrapper(SayHello)

2、POP实现

如下代码是面向过程(POP)的实现。你可以将如下代码拷贝并存储一个文件中,可以取名字叫clock.py。打开命令行控制台,运行python3 clock.py命令就可以看到效果啦。如果你的系统只安装了Python3,那么可能你的命令应该是Python clock.py。

import curses

import datetime

import time

week_days = (

"+ Mon. +",

"+ Tue. +",

"+ Wed. +",

"+ Thu. +",

"+ Fri. +",

"+ Sta. +",

"+ Sun. +",

)

# 时钟的一次嘀嗒,每秒调用一次

def tick(stdscr):

# 获取当前时间

now = datetime.datetime.now()

# 获取时期,等同于 date_str = str(now.date())

date_str = "+ {}-{:02d}-{:02d} +".format(now.year, now.month, now.day)

# 获取星期的三字母缩写

week_str = week_days[now.weekday()]

# 获取时间,等同于 time_str = now.time().strftime('%H:%M:%S')

time_str = "+ {:02d}:{:02d}:{:02d} +".format(now.hour, now.minute, now.second)

# 计算起始坐标

y = (curses.LINES - 5) // 2

x = (curses.COLS - 14) // 2

# 使用addstr将字符串输出的屏幕

# 注意:第一个参数是y坐标

stdscr.addstr(y, x, "+" * 14)

stdscr.addstr(y + 1, x, date_str)

stdscr.addstr(y + 2, x, week_str)

stdscr.addstr(y + 3, x, time_str)

stdscr.addstr(y + 4, x, "+" * 14)

# 刷新屏幕

stdscr.refresh()

def main(stdscr):

while True:

tick(stdscr)

time.sleep(1)

if __name__ == "__main__":

curses.wrapper(main)

3、OOP实现

我们将POP的实现改造成OOP的方式。其实现和POP的基本一样。我们对POP的实现进行简化。

在POP实现中,程序运行之后,我们没有办法交互性地结束程序。如果你要结束程序,在Linux中你必须使用Ctrl+C;在Windows中,你必须使用Ctrl+D。在OOP中,我们加入了对用户输入(键盘)的监听,程序运行之后,我们可以通过敲击键盘的任意键结束程序。

import curses

import datetime

import time

week_days = (

"Mon.",

"Tue.",

"Wed.",

"Thu.",

"Fri.+",

"Sta.",

"Sun.",

)

class ConsoleClock:

# 重载此方法,让对象可以像函数一样被调用

# curses.wrapper(clock)会调用clock(stdscr)

# clock(stdscr)相当于 clock.__call__(stdscr)

def __call__(self, stdscr):

self.y = (curses.LINES - 5) // 2

self.x = (curses.COLS - 14) // 2

self.stdscr = stdscr

self.run_forever()

def run_forever(self):

# 用不阻塞方式监听键盘的输入

self.stdscr.nodelay(True)

while True:

# 如果未监听到键盘输入,会返回curses.ERR

# 那么我们可以继续用屏蔽展示下一秒的时钟

if self.stdscr.getch() == curses.ERR:

self.tick()

time.sleep(1)

else:

# 如果监听到键盘输入,退出循环

break

def tick(self):

now = datetime.datetime.now()

strs = (

"+" * 12,

"+{}+".format(str(now.date())),

"+ {} +".format(week_days[now.weekday()]),

"+ {} +".format(now.time().strftime('%H:%M:%S')),

"+" * 12,

)

for i, s in enumerate(strs):

self.stdscr.addstr(self.y + i, self.x, s)

self.stdscr.refresh()

if __name__ == "__main__":

clock = ConsoleClock()

curses.wrapper(clock)微信扫码关注,发家致富

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值