python3 获取屏幕大小_Python3实践之:控制台时钟

本文介绍了如何使用Python3的curses库在控制台上创建一个实时更新的时钟,展示日期、星期和时间。通过面向过程(POP)和面向对象(OOP)两种方式详细讲解实现步骤,并提供了相关资源链接帮助读者了解datetime和curses。POP实现中,程序需通过Ctrl+C或Ctrl+D结束;而OOP实现增加了键盘监听,允许用户按键结束程序。
摘要由CSDN通过智能技术生成

3e378ca59f8c31bae6dfda35578de1b4.png

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.com
a635138937fbff3f0cadd433486d2026.png

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.com
c1bd91fecdf224056c7bb8b0991eba6c.png

本文将用面向过程(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)

2825e9af45a1b19e66f6900352dd9087.png
微信扫码关注,发家致富
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值