33557浏览
查看: 33557|回复: 4

[教程] 基于树莓派的藏头诗生成器

[复制链接]
基于树莓派的藏头诗生成器
基于树莓派的藏头诗生成器图1
项目起源
最近收到了DF寄来的专门针对Raspberry Pi的5寸显示屏,支持5点电容触控,拥有800×480标准分辨率。
基于树莓派的藏头诗生成器图5
该显示屏采用Raspberry Pi标准DISPLAY接口---MIPI DSI,通过FPC软排线与Raspberry Pi连接,即可实现显示和触控功能,无需连接额外的USB线缆,更大的节省了设备的空间。张三生日快乐
基于树莓派的藏头诗生成器图6
最近旺仔爸爸正好制作了一款藏头诗生成器的PY程序,如果能将该程序运行在树莓派上,再搭配这块屏幕,就变成了种随时随地使用的终端设备,相信会是一种美妙的体验
那么,本期教程我们就带大家基于树莓派制作一个藏头诗生成器,让我们将心中要表达的情感寄托在诗句中。下面我们就一起来看看藏头诗生成器具体是如何实现的
基于树莓派的藏头诗生成器图8
图 1 藏头诗生成器运行界面
效果展示
基于树莓派的藏头诗生成器图3
图 2 藏头诗展示
程序设计
下面是本次程序设计的思路
编程思路
基于树莓派的藏头诗生成器图2
图 3 藏头诗程序设计思维导图
准备编程环境
本次藏头诗制作我们使用树莓派系统自带的Thonny编程环境
关于树莓派系统的配置这里就不展开叙述了,如果还没安装好树莓派系统可以参考之前的教程
基于树莓派的藏头诗生成器图9
4编程环境
创建文件
软件安装完成,我们就可以开始编写程序了,Thonny运行界面如下图
基于树莓派的藏头诗生成器图11
图 5 Mind+软件的 Python 模式
图 6 在 Mind+中添加本地文件
然后,将程序保存在自己熟悉的路径下新建一个专门用来存放 Python 程序的文件夹
基于树莓派的藏头诗生成器图10
图 7保存程序
安装第三方库
从前文中的思维导图我们知道,生成藏头诗需要用到几个第三方库,他们分别是网络请求库【requests】和数据解析库【lxml】。
接下来,在树莓派系统中安装这些库,首先安装requests库,输入指令sudo pip install requests
基于树莓派的藏头诗生成器图12
图 11 安装第三方库
之后,继续安装lxml库,输入指令sudo pip install lxml
基于树莓派的藏头诗生成器图7 图 12 安装第三方库
第三方库安装完成后
接着我们来尝试使用【requests】库制作藏头诗
访问藏头诗网站
从前文中的编程思路知道,要制作藏头诗我们需要借助一个网站来完成,通过搜索找到一个比较好用的藏头诗网站,地址如下:
基于树莓派的藏头诗生成器图34
14 藏头诗网站
要访问这个网站,首先我们需要知道该网站的API地址。我们在浏览器中输入藏头诗网站的地址,在出现的页面单击鼠标右键即可看到如下图15所示的界面,界面的右侧就是该网页后台运行的一些代码
基于树莓派的藏头诗生成器图37
15 藏头诗网站后台
随后,我们按照下图16所示的顺序,先点击“Network”选项,然后在左侧的页面中输入内容并点击“再来一首”,之后再点击右侧“Name”栏中出现的内容,这样就可以看到该网页对应的API地址了,也就是图中标注的“Request URL”,同时我们也可以知道它的请求方式为requests.get
基于树莓派的藏头诗生成器图35
16 藏头诗网站API地址
看到图中的地址你可能会觉得有点长,会有点陌生,不过没关系,我们可以参考下图17的标注就能够理解每个参数的含义了。其中包含了输入的内容“W=”,每句诗的字数“num=”,藏的位置“type=”以及押韵方式“yayuntype=”
基于树莓派的藏头诗生成器图36
17 API地址参数标注
理解了API地址各个参数的含义,现在我们就可以来尝试访问这个地址了
我们输入如下程序:
#导入requests库
import requests
#将藏头诗网站的API地址放入“poem_url”变量中
poem_url = "http://www.piaofangw.com/cangtoushi/fasong.php?w=%u8282%u81F3%u4EBA%u95F4%u4E07%u8C61%u66F4%u65B0%20%20%20%20%20&num=5&type=1&yayuntype=1"
#向藏头诗网站的API地址发送网络请求,并将返回数据放入“http_data”变量中
http_data = requests.get(poem_url).text
#打印输出数据
print(http_data)
在程序之中,我们复制了刚才看到的API地址,地址中的所有参数均为默认, 使用request.get的方式向网站发送请求,之后点击运行按钮运行程序
基于树莓派的藏头诗生成器图13
图 18 运行按钮
然后会看到如下图19所示的运行结果,你会发现返回的是一长串有点乱的数据,不过这不要紧,我们现在来整理这些数据即可
基于树莓派的藏头诗生成器图15
图 19 向藏头诗网站发送网络请求
解析处理返回数据
要整理这些返回的数据,首先我们得知道这些数据中都包含哪些内容。我们在网页的后台中按照下图20所示的顺序点击“Elements”,之后点击旁边的箭头,然后选择左侧的诗句,随后在右侧的界面中就可以看到这些数据了,其实这些就是标准的HTML数据。如果我们耐心的寻找,会发现我们要找的藏头诗就这里面,只不过这些诗句还缺少句头的一个汉字
基于树莓派的藏头诗生成器图39
20 HTML数据
那么,下面我们要做的就是将这些有用的诗句提取出来。要实现提取这些数据,就需要用到前面加载的【lxml】库了。
这里我们需要简单了解一下什么是【lxml】库,【lxml】主要用于解析和提取HTML或者XML格式的数据,它不仅功能非常丰富,而且便于使用,可以利用XPath语法快速地定位特定的元素或节点。
从中我们知道【lxml】库中有一个快速定位元素的方法【XPath】,那么如果能够找到这些诗句的【XPath】地址的话,是不是就可以提取这些数据呢?我们现在来试试看。
首先,在网页中出现的诗句中单击鼠标右键,然后选择“Copy”功能中的“Copy XPath”,复制出来的地址为:“//*[@id="commetcontentNew"]/text()[1]
基于树莓派的藏头诗生成器图38
21 复制XPath地址
之后,我们继续修改程序
#导入requests库
import requests
from lxml import etree#导入lxml库
#将藏头诗网站的API地址放入“poem_url”变量中
poem_url = "http://www.piaofangw.com/cangtoushi/fasong.php?w=%u8282%u81F3%u4EBA%u95F4%u4E07%u8C61%u66F4%u65B0%20%20%20%20%20&num=5&type=1&yayuntype=1"
#向藏头诗网站的API地址发送网络请求,并将返回数据放入“http_data”变量中
http_data = requests.get(poem_url).text
result = etree.HTML(http_data) #解析数据
text = result.xpath('//div[@id="commetcontentNew"]/text()[1]')
#打印输出数据
print(text)
程序中,我们导入了【lxml】库,通过“etree”方法解析返回的数据,再使用“xpath”的方法提取数据,“xpath”括号中的内容就是刚才我们复制到地址,程序运行后效果如下
基于树莓派的藏头诗生成器图14
22 解析数据
程序运行后,打印出了一句诗。观察程序不难发现,“xpath”的地址中,最后的结尾序号是[1],如果我们将其序号修改为2或者直接删除会有什么样的结果呢?
经过测试发现,这里的序号就是对应的第几句诗,如果直接输入text = result.xpath('//div[@id="commetcontentNew"]/text()'),则会出现如下图所示的结果,会有8句诗打印出来,诗句的数量和输入的藏头词字数一样。
基于树莓派的藏头诗生成器图20
23 解析数据
从藏头诗的网页中我们可以知道,当我们输入内容后可以生成六首不同的诗句,用户可以自由选择。现在我们只提取了 第一首诗句,那么剩下的五首诗句该如何提取呢?同样的方法我们复制其余诗句的【XPath】地址,比如第二首诗的地址为“//*[@id="commetcontentNew1"]/text()”,第三首诗的地址为“//*[@id="commetcontentNew2"]/text()”,以此类推。仔细观察这些地址,你会发现序号的改变就会改变诗句的内容,那么后面的诗句地址,相信你也可以推断出来了,1-5的编号分别对应第二首到第六首诗
基于树莓派的藏头诗生成器图16
24 提取其余诗句
不过,要一个一个修改XPath地址的序号的话,难免有些麻烦。这里我们可以通过for语句来遍历所有的诗句数据
for i in range(1,6):
    #打印输出数据
print(result.xpath('//div[@id="commetcontentNew{}"]/text()'.format(i)))
程序中涉及到了字符串格式化的方法format,程序运行后的效果如下图
基于树莓派的藏头诗生成器图18
25 提取其余诗句
通过观察程序的运行结果可以看出,我们已经成功提取了5首诗句的内容,从返回的数据中可以知道5首诗句数据为5个列表,再加上最开始我们获取到第一首诗,这样就有6首诗供我们选择了。不过每句诗都缺少一个句头汉字,那么接下来我们要做的就是将句头汉字加入到诗句中,组成完整的诗句。这里可能有朋友会问了,前面的数据请求过程使用的都是默认的数据,比如输入的内容、诗句的字数都是默认的,如果要修改这些参数该如何操作呢?现在,我们就一一解决这些问题
API地址参数修改
首先我们来看API地址
#将藏头诗网站的API地址放入“poem_url”变量中
poem_url = "http://www.piaofangw.com/cangtoushi/fasong.php?w=%u8282%u81F3%u4EBA%u95F4%u4E07%u8C61%u66F4%u65B0%20%20%20%20%20&num=5&type=1&yayuntype=1"
从上述地址中我们知道,其中包含了四个参数,分别是输入内容“w=”,每句诗的字数“num=”,藏的位置“type=”,押韵的的方式“yayuntype=”
输入内容的参数我们放到最后分析,先来看其余几项参数。每句诗的字数num,这里的num可以赋值为5或者7,也就是我们常说的五言或七言绝句。藏的位置“type”有1-5五种数字可选,分别对应藏头、藏尾、藏中、递增或递减。
押韵方式“yayuntype”有1-3三种数字可选,分别对应双句一压、双句押韵、一三四押。
以上三种参数了解后,最后我们来了解输入内容的参数如何修改。从代码中可以看到这是一种特殊的符号w=%u8282%u81F3%u4EBA%u95F4%u4E07%u8C61%u66F4%u65B0%20%20%20%20%20
其实它是一种unicode编码方式,也就是将输入的中文转换成网页能够读懂的编码。Unicode也叫万国码,是在计算机上使用的字符编码。它为每种语言中的每个字符设定了统一并且唯一的二进制编码,可以满足跨语言、跨平台进行文本转换、处理的要求。提高了编程语言在全球各个国家的兼容性。
unicode编码的使用方法也很简单,使用如下方法即可实现将中文转换成unicode编码
word = input("请输入藏头词:")
uni = word.encode('unicode-escape').decode()#中文转换为unicode
以上程序运行后的结果如下
基于树莓派的藏头诗生成器图17
26 编码转换
从上图26的运行结果可以看出,汉字转换成了unicode编码,不过再与前面API地址中的编码比较后发现,我们现在生成的编码中是用反斜杠“\”作为词与词的间隔划分的,而前面的API地址中则是用百分号“%”来划分,我们还需要将反斜杠替换为百分号,这里用到了replace的替换方法,程序如下
word = input("请输入藏头词:")
uni = word.encode('unicode-escape').decode()#中文转换为unicode
uni =uni.replace("\\", "%");#替换字符
从下图27的运行结果中可以看到编码已经被修改过来了
基于树莓派的藏头诗生成器图19
27 字符替换
实现了中文与unicode编码的转换后,我们将代码中的地址参数做如下修改
poem_url = "http://www.piaofangw.com/cangtoushi/fasong.php?w="+uni+"&num=5&type=1&yayuntype=1"
随后,运行程序,会看到我们输入藏头词后会返回对应的5首诗句
基于树莓派的藏头诗生成器图21
28 输出诗句
输入的藏头词可以通过input键盘输入的方式获取。同样的,诗句的字数、
藏的位置、押韵的方式也可以通过这种方式进行修改,我们以每句诗的字数为例修改程序,如下
word = input("请输入藏头词:")
num = input("请输入每句诗的字数(5or7):")
uni = word.encode('unicode-escape').decode()#中文转换为unicode
uni =uni.replace("\\", "%");#替换字符
#将藏头诗网站的API地址放入“poem_url”变量中
poem_url = "http://www.piaofangw.com/cangtoushi/fasong.php?w="+uni+"&num="+num+"&type=1&yayuntype=1"
程序运行后会看到如下图29所示的结果
基于树莓派的藏头诗生成器图22
29 从键盘输入参数
目前,我们已经实现了任意输入藏头词即可得到缺头的藏头诗,现在我们要做的就是将藏头词与返回的诗句合并为一整句诗,这里我们可以借助列表来完成这个任务,修改后的程序如下
poem1 = []#列表1
poem2 = []#列表2
#将第一首诗添加到列表1中
poem1.append(result.xpath('//div[@id="commetcontentNew"]/text()'))
for i in range(1,6):
    #将第二首至第六首诗添加到列表1中
    poem1.append(result.xpath('//div[@id="commetcontentNew{}"]/text()'.format(i)))
print(poem1)
word = list(word)#将藏头词转换成列表
print(word)
for i in range(6):
    for j in range(len(word)):
        poem2.append(word[j]+poem1[j])#藏头词与列表1的诗句合并后加入到列表2中
    if len(word)%2==1:#如果藏头词为奇数,还需要将最后一句没有包含藏头词的诗句加入列表2中
        poem2.append(poem1[len(word)])
print(poem2)
程序中我们新建了两个列表用来存放诗句,首先将第一首诗存放至列表1中,然后使用for语句将第二首至第六首诗存放至列表1 中。然后将藏头词转换为列表,再与列表1 中的诗句合并组成完整的诗句,之后将完整的诗句添加到列表2 中,上述程序运行结果如下图30
基于树莓派的藏头诗生成器图26
30 藏头词与诗句合并
不知道你有没有发现,这里生成的诗句数量跟藏头词的字数有关,比如藏头词的字数小于或等于两个字时,只生成两句诗。如果藏头词的字数为大于2 的奇数时,生成奇数+1句诗。如果藏头词的字数为大于2的偶数时,诗句的数量与藏头词的字数一样
知道这样的规律,现在我们就可以修改程序,每次只选择显示其中一首诗句,当用户对藏头诗不满意时可以再从其余几首诗中进行选择
if len(word)<=2:#藏头词的字数小于或等于两个字时,只生成两句诗
    word_num = 2
elif len(word)%2==1:#藏头词的字数为大于2 的奇数时,生成奇数+1句诗
    word_num = len(word)+1
else:#藏头词的字数为大于2的偶数时,诗句的数量与藏头词的字数一样
    word_num = len(word)
for i in range(word_num):
    print(poem2)#打印诗句
基于树莓派的藏头诗生成器图23
31 根据藏头词字数设置诗句数量
为了让程序看上去简洁高效,可以将以上程序封装成函数
#导入requests库
import requests
from lxml import etree#导入lxml库
poem1 = []
poem2 = []
#获取藏头诗
def getWord():
    word = input("请输入藏头词(8字以内):")
    num = input("请输入每句诗的字数(5or7):")
    uni = word.encode('unicode-escape').decode()#中文转换为unicode
    uni =uni.replace("\\", "%");#替换字符
    #将藏头诗网站的API地址放入“poem_url”变量中
    poem_url = "http://www.piaofangw.com/cangtoushi/fasong.php?w="+uni+"&num="+num+"&type=1&yayuntype=1"
    #向藏头诗网站的API地址发送网络请求,并将返回数据放入“http_data”变量中
    http_data = requests.get(poem_url).text
    result = etree.HTML(http_data)
    text = result.xpath('//div[@id="commetcontentNew1"]/text()')
    #将第一首诗添加到列表1中
    poem1.append(result.xpath('//div[@id="commetcontentNew"]/text()'))
    for i in range(1,6):
        #将第二首至第六首诗添加到列表1中
        poem1.append(result.xpath('//div[@id="commetcontentNew{}"]/text()'.format(i)))
    word = list(word)#将藏头词转换成列表
    for i in range(6):
        for j in range(len(word)):
            poem2.append(word[j]+poem1[j])#藏头词与列表1的诗句合并后加入到列表2中
        if len(word)%2==1:#如果藏头词为奇数,还需要将最后一句没有包含藏头词的诗句加入列表2中
            poem2.append(poem1[len(word)])
    return(word,poem2)
#输出藏头诗
def print_word(word,poem2):
    if len(word)<=2:#藏头词的字数小于或等于两个字时,只生成两句诗
        word_num = 2
    elif len(word)%2==1:#藏头词的字数为大于2 的奇数时,生成奇数+1句诗
        word_num = len(word)+1
    else:#藏头词的字数为大于2的偶数是,诗句的数量与藏头词的字数一样
        word_num = len(word)
    for i in range(word_num):
        print(poem2)#打印诗句
word,poem2 = getword()
print_word(word,poem2)
通过以上程序的测试,我们已经实现了输入任意藏头词之后输出对应的藏头诗,
藏头诗还需要一个人性化的操作界面,接下来我们为藏头诗制作一个可视化的操作界面
使用 Tkinter 库设计图形化界面
本次作品我们还是延续以往的惯例,使用Python自带的tkinter 库来创建图形化的应用界面,为了不增加难度,我们重新建一个新程序来学习使用tkinter 库,基本用法掌握后再与藏头诗的程序结合
基于树莓派的藏头诗生成器图24
图 32 新建图形化界面设置程序
第一步,创建图形化界面
创建窗口
在 Mind+软件中编写如下程序
from tkinter import * #导入tkinter库
if __name__ == '__main__':
    root = Tk()
    root.title('藏头诗生成器')#设置窗口标题
    #设置窗口大小(窗口横向长度X窗口纵向长度+距离屏幕左边框的横向距离+距离屏幕上边框的纵向距离)
    root.geometry('400x400+200+200')
    root.mainloop()#窗口循环运行
运行上述程序,会看到下图 33 所示的结果,在电脑屏幕中显示出了一个 400 像素宽,400像素高的空白窗口
基于树莓派的藏头诗生成器图25
图 33 创建窗口
我们再来看刚才的程序,在窗口界面设置中,root.geometry('400x400+200+200') 里的参数可以来调整窗口的尺寸和显示的位置,参数中第 1个数字为窗口的宽度,第2 个数字为窗口的高度,第3 个数字为窗口的左上角距离屏幕左边框的横向距离,第4 个数字为窗口的左上角距离屏幕上边框的纵向距离。
窗口新建完成,我们就可以在窗口内布置各种组件了
首先使用 Label 标签为界面添加一个标题和LOGO图片, Label 标签它是一个用于在指定的窗口中显示文本和图像的组件
设置 Label 标签
在编程环境中我们增加如下程序
   photo1=PhotoImage(file="shi.gif")#导入图片
    Label(root,image=photo1).grid(row = 0,column=0,pady = 10)#显示图片
    #定义label标签
    Label(root,
        text='藏头诗生成器',#标签的文字
        font=('simsun', 15)#设置字体和字号,simsun为宋体
        ).grid(row=0,column=1,pady = 10)# 将标签放置在窗口的第0行,第1列位置
    root.mainloop()#窗口循环运行
程序运行后,我们会看到如下图34所示的运行结果,由 Label 标签设置的“藏头诗生成器”几个汉字和LOGO图片会显示在窗口的左上方,图片显示在第 0 行,第 0 列的位置,汉字显示在第0行,第1列的位置,其中 “row”和“column”为行和列的参数,这里需要强调的是 tkinter 库只支持 gif 格式的图片,我们可以使用电脑中自带的画图工具将其他格式的图片转变成 gif 格式,并且还要将LOGO图片与py程序放在同一路径下
基于树莓派的藏头诗生成器图28
图 34 放置 Label 标签
Label标签显示的效果还可以通过修改程序中Label的文字内容“text=”,文字“fg=” 或背景颜色“bg=”,字体和字体大小“font=()”以及标签的尺寸“width= ,height= ” 来调整 Label 在窗口中的显示效果,如果不设置文字或背景颜色,则会默认为黑色文字,白色背景
以上,我们成功放置了 Label 标签,除 Label 标签外本次藏头诗生成器程序还会用到 tkinter 中的Entry输入框、Text 文本框、Button按钮和radiobutton按钮,接下来我们布局 Entry输入框
Entry输入框
Entry 输入框可以用来获取键盘输入的内容也可以用来显示单行文本让用户输入用户信息。在这里我们为藏头诗生成器增加一个 Entry 输入框,用来获取键盘输入的内容
在程序中增加如下程序
#定义输入框
    enter = Entry(root,width=50)#输入框
    enter.grid(row = 1,column=0, columnspan=3,padx = 20, pady = 20)#调整位置
    root.mainloop()#窗口循环运行
程序运行后会看到Label标签的下方出现了Entry 输入框,也就是第2行,第0列的位置增加了一个Entry输入框 ,并通过“padx”和“pady”设置了输入框距离上下左右的边距,其中 “ columnspan=”参数的含义是对列进行合并,大家可以尝试修改参数,看看会有什么样的效果
基于树莓派的藏头诗生成器图27
图 35 放置Entry 输入框
如果想要在 Entry 输入框中添加或删除内容,可以采用下面的方法enter.delete(0,END)#清空输入框
enter.insert(0,'李白')#输入框中添加文本
获取输入框中的内容可以使用指令 enter.get()#获取输入框中内容
输入框布局完成,接下来我们设置一些藏头诗的参数,比如每句诗的字数,也就是五言或七言绝句两种选择,我们可以使用radiobutton广播按钮来实现这个功能
Radiobutton 按钮放置
Radiobutton(单选按钮)组件用于实现多选一的问题。Radiobutton 组件可以包含文本或图像,每一个按钮都可以与一个 Python 的函数或方法相关联,当按钮被按下时,对应的函数或方法将被自动执行。直白的理解就是在多个按钮中每次只能选择一个按钮,选择不同的按钮会执行不同的函数
了解了这个按钮的功能,我们就可以用它来为藏头诗增加诗句字数的选择功能了,新增如下程序
    var = StringVar()    # 定义一个var用来将radiobutton的值和Label的值联系在一起.
    # 创建两个radiobutton选项,其中variable=var, value='A'的意思就是,当我们鼠标选中了其中一个选项,把value的值A放到变量var中,然后赋值给variable
    r1 = Radiobutton(root, text='五言', variable=var, value='A', indicatoron=False,command=print_selection)
    r1.grid(row = 2, column=0,columnspan=2, pady = 10)
    r2 = Radiobutton(root, text='七言', variable=var, value='B', indicatoron=False,command=print_selection)
    r2.grid(row = 2, column=1,columnspan=2, pady = 10)
root.mainloop()#窗口循环运行
在程序中我们增加了两个选择按钮,分别指向五言和七言两种选项。如何区分用户选择了哪种选项呢?这里就需要使用value的值来判断了,A、B分别对应五言和七言,通过按钮来触发print_selection()函数进行判断和设置变量num的数值,这里变量num的含义是每句诗的字数,也就是在发送网络请求时需要用到该变量,所以我们需要设置其为全局变量global,并且在给num变量赋值时特意将数字类型转换成的字符类型,原因是在发送网络请求时必须是字符串类型,所以这里进行了转换。print_selection()函数如下
# 定义选项触发函数功能
def print_selection():
    global num
    a = var.get()
    if a== 'A':
        num = '5'
    if a== 'B':
        num = '7'
程序运行后,会看到如下图所示的结果,在文本显示框下方出现了两个选择按钮,点击之后会有明显的变化
基于树莓派的藏头诗生成器图29
36 选择按钮
其实按钮不仅只有上面一种表现形式,如果我们将程序中的参数indicatoron=False设置为True,则会显示如下效果
基于树莓派的藏头诗生成器图30
37选择按钮
每句诗的字数选择按钮设置完成,我们还需要设置“生成”、“清空”和“换一首”的按钮
Button按钮设置
“生成”、“清空”和“换一首”三个按钮放置在同一行,程序如下
Button(root, text='生  成',width=10, command=getWord).grid(row = 3, column=0, pady = 10)  # 将"生成"Button放置在窗口
    Button(root, text = '清  空',width=10, command=clear).grid(row = 3, column = 1,  pady = 10)# 将清空Button放置在窗口中
    Button(root, text = '换一首',width=10, command=Next).grid(row = 3, column = 2,  pady = 10)# 将清空Button放置在窗口中
程序运行后会看到如下图38所示结果,
基于树莓派的藏头诗生成器图31
图 38 放置 Button 按钮
在程序中,我们增加了三个 Button 按钮组件,一个用来生成藏头诗,一个用来清空文本框的内容,如果对生成的藏头诗不满意,还可以点击“换一首”按钮来切换藏头诗
其中 command 参数用来设置按钮被点击后执行的命令,比如添加点击“生成”按钮就可以执行生成藏头诗的函数,只不过现在函数中还没有程序;点击“清空”按钮执行清空文本框的指令
#获取藏头诗
def getWord():
    pass
#清空显示
def clear():
    pass
#切换下一首
def Next():
pass
Button 按钮组件布局完成,还需要为Button 按钮关联程序,由于Button按钮与Text文本显示框有着密切的联系,所以现在并不急着为按钮添加程序,我们先来布局Text文本显示框
Text 文本显示框
Text 组件用于显示文本文档,包含纯文本或格式化文本比如可以插入图片、文本、链接等内容,本次藏头诗生成器只需要显示诗句文本即可,我们添加如下程序,其中参数padx和pady可以用来调节文本显示框与边框的距离
#定义text文本框
text = Text(root,width=20,height=10)# 定义文本框的尺寸 text.grid(row = 4,column=0, columnspan=3,padx = 20, pady = 5)#调整位置
root.mainloop()
程序运行后会看到在三个Button按钮下方出现了文本显示区域
基于树莓派的藏头诗生成器图32
39 放置text文本框
在文本框中添加或删除文本的指令是
text.insert('end', "显示内容")#在text显示框中添加内容 text.delete('0.0','end')#清空text显示框
获取文本框中的内容的指令是
text.get("1.0","end")    #获取文本输入框的内容
Button按钮关联程序
以上组件布置完成后,藏头诗生成器的界面就初具轮廓了,最后我们还需要将之前的藏头诗程序与图形化界面的程序关联起来,我们将前文中测试好的获取藏头诗的程序放在getWord()函数中,同时将程序中从键盘获取内容修改为从Entry输入框获取内容,并且设置在每次生成诗句之前清除前面的诗句内容,也就是将列表1和列表2 中的数据清空。再设置每句诗的字数变量num为全局变量,这样在选择完每句诗的字数后就可以使num的数值保持一致。程序修改后如下
#获取藏头诗
def getWord():
    del poem1[:]
    del poem2[:]
    global num
    word = enter.get()
    uni = word.encode('unicode-escape').decode()#中文转换为unicode
    uni =uni.replace("\\", "%");#替换字符
    #将藏头诗网站的API地址放入“poem_url”变量中
    poem_url = "http://www.piaofangw.com/cangtoushi/fasong.php?w="+uni+"&num="+str(num)+"&type=1&yayuntype=1"
    #向藏头诗网站的API地址发送网络请求,并将返回数据放入“http_data”变量中
    http_data = requests.get(poem_url).text
    result = etree.HTML(http_data)
    text = result.xpath('//div[@id="commetcontentNew1"]/text()')
    #将第一首诗添加到列表1中
    poem1.append(result.xpath('//div[@id="commetcontentNew"]/text()'))
    for i in range(1,6):
        #将第二首至第六首诗添加到列表1中
        poem1.append(result.xpath('//div[@id="commetcontentNew{}"]/text()'.format(i)))
    word = list(word)#将藏头词转换成列表
    for i in range(6):
        for j in range(len(word)):
            poem2.append(word[j]+poem1[j])#藏头词与列表1的诗句合并后加入到列表2中
        if len(word)%2==1:#如果藏头词为奇数,还需要将最后一句没有包含藏头词的诗句加入列表2中
            poem2.append(poem1[len(word)])
    print_word(word,poem2)
的诗句合并后加入到列表2中
        if len(word)%2==1:#如果藏头词为奇数,还需要将最后一句没有包含藏头词的诗句加入列表2中
            poem2.append(poem1[len(word)])
    print_word(word,poem2)
接下来我们将print_word(word,poem2)函数做如下修改,将原来的打印诗句print(poem2)
修改为在文本框中添加诗句text.insert('end', poem2),并且在每次生输出藏头诗之前将上一次的诗句清除text.delete('1.0','end'),程序如下
#输出藏头诗
def print_word(word,poem2):
    text.delete('1.0','end')#清空text显示框
    if len(word)<=2:#藏头词的字数小于或等于两个字时,只生成两句诗
        word_num = 2
    elif len(word)%2==1:#藏头词的字数为大于2 的奇数时,生成奇数+1句诗
        word_num = len(word)+1
    else:#藏头词的字数为大于2的偶数时,诗句的数量与藏头词的字数一样
        word_num = len(word)
    for i in range(word_num):
        text.insert('end', poem2)#在text显示框中添加内容
随后,在与清空按钮关联的函数clear()中添加清空显示的程序,如下
#清空显示
def clear():
    text.delete('1.0','end')#清空text显示框
    enter.delete(0,END)#清空entry输入框
最后就是“换一首”按钮的关联程序了,换一首的程序很简单,目的就是将生成的6首诗句轮番切换,其中变量num_i作为诗的序号,变量word_num为诗句的数量,使用poem2[i+word_num*num_i]的方法即可切换不同的诗句
#切换下一首
num_i = 0
def Next():
    global word_num,num_i
    num_i += 1
    if num_i>5:
        num_i=0
    text.delete('1.0','end')#清空text显示框
    for i in range(word_num):
        text.insert('end', poem2[i+word_num*num_i])#在text显示框中添加内容
优化程序
通过上述程序,我们已经实现了藏头诗的制作,不过还有提升的空间,可以将程序进行优化,比如在选项触发函数中增加清空列表的程序,这样可以保证当前的数据不会被上一次的数据影响
# 定义选项触发函数功能
def print_selection():
    del poem1[:]
    del poem2[:]
    global num
    a = var.get()
    if a== 'A':
        num = '5'
    if a== 'B':
        num = '7'
我们还可以使用“columnspan=”
合并居中的方式,调节logo和标题的位置,最终效果如下图40
基于树莓派的藏头诗生成器图33
40 藏头诗生成器运行界面
最后,附上本次藏头诗生成器的完整程序,当然此程序在其他编程环境同样适用,大家可以自行编译运行
from tkinter import * #导入tkinter库
#导入requests库
import requests
from lxml import etree#导入lxml库
#获取藏头诗
def getWord():
    del poem1[:]
    del poem2[:]
    global num
    word = enter.get()
    uni = word.encode('unicode-escape').decode()#中文转换为unicode
    uni =uni.replace("\\", "%");#替换字符
    #将藏头诗网站的API地址放入“poem_url”变量中
    poem_url = "http://www.piaofangw.com/cangtoushi/fasong.php?w="+uni+"&num="+num+"&type=1&yayuntype=1"
    #向藏头诗网站的API地址发送网络请求,并将返回数据放入“http_data”变量中
    http_data = requests.get(poem_url).text
    result = etree.HTML(http_data)
    text = result.xpath('//div[@id="commetcontentNew1"]/text()')
    #将第一首诗添加到列表1中
    poem1.append(result.xpath('//div[@id="commetcontentNew"]/text()'))
    for i in range(1,6):
        #将第二首至第六首诗添加到列表1中
        poem1.append(result.xpath('//div[@id="commetcontentNew{}"]/text()'.format(i)))
    word = list(word)#将藏头词转换成列表
    for i in range(6):
        for j in range(len(word)):
            poem2.append(word[j]+poem1[j])#藏头词与列表1的诗句合并后加入到列表2中
        if len(word)%2==1:#如果藏头词为奇数,还需要将最后一句没有包含藏头词的诗句加入列表2中
            poem2.append(poem1[len(word)])
    print_word(word,poem2)
#输出藏头诗
def print_word(word,poem2):
    text.delete('1.0','end')#清空text显示框
    global word_num
    if len(word)<=2:#藏头词的字数小于或等于两个字时,只生成两句诗
        word_num = 2
    elif len(word)%2==1:#藏头词的字数为大于2 的奇数时,生成奇数+1句诗
        word_num = len(word)+1
    else:#藏头词的字数为大于2的偶数时,诗句的数量与藏头词的字数一样
        word_num = len(word)
    for i in range(word_num):
        print(poem2)#打印诗句
        text.insert('end', poem2)#在text显示框中添加内容
#清空显示
def clear():
    text.delete('1.0','end')#清空text显示框
    enter.delete(0,END)#清空entry输入框
#切换下一首
num_i = 0
def Next():
    global word_num,num_i
    num_i += 1
    if num_i>5:
        num_i=0
    text.delete('1.0','end')#清空text显示框
    for i in range(word_num):
        text.insert('end', poem2[i+word_num*num_i])#在text显示框中添加内容
# 定义选项触发函数功能
def print_selection():
    del poem1[:]
    del poem2[:]
    global num
    a = var.get()
    if a== 'A':
        num = '5'
    if a== 'B':
        num = '7'
if __name__ == '__main__':
    poem1 = []#列表1
    poem2 = []#列表2
    root = Tk()
    root.title('藏头诗生成器')#设置窗口标题
    #设置窗口大小(窗口横向长度X窗口纵向长度+距离屏幕左边框的横向距离+距离屏幕上边框的纵向距离)
    root.geometry('400x400+200+200')
    photo1=PhotoImage(file="shi.gif")#导入图片
    Label(root,image=photo1).grid(row = 0,column=0,columnspan=2,pady = 10)#显示图片
    #定义label标签
    Label(root,
        text='藏头诗生成器',#标签的文字
        font=('simsun', 15)#设置字体和字号
        ).grid(row=0,column=1,columnspan=3,pady = 10)# 将标签放置在窗口的第0行,第1列位置
    #定义输入框
    enter = Entry(root,width=50)#输入框
    enter.grid(row = 1,column=0, columnspan=3,padx = 20, pady = 20)#调整位置
    var = StringVar()    # 定义一个var用来将radiobutton的值和Label的值联系在一起.
    # 创建两个radiobutton选项,其中variable=var, value='A'的意思就是,当我们鼠标选中了其中一个选项,把value的值A放到变量var中,然后赋值给variable
    r1 = Radiobutton(root, text='五言', variable=var, value='A', indicatoron=False,command=print_selection)
    r1.grid(row = 2, column=0,columnspan=2, pady = 10)
    r2 = Radiobutton(root, text='七言', variable=var, value='B', indicatoron=False,command=print_selection)
    r2.grid(row = 2, column=1,columnspan=2, pady = 10)
    Button(root, text='生  成',width=10, command=getWord).grid(row = 3, column=0, pady = 10)  # 将"生成"Button放置在窗口
    Button(root, text = '清  空',width=10, command=clear).grid(row = 3, column = 1,  pady = 10)# 将清空Button放置在窗口中
    Button(root, text = '换一首',width=10, command=Next).grid(row = 3, column = 2,  pady = 10)# 将清空Button放置在窗口中
    text = Text(root,width=50, height=10)
    text.grid(row = 4,column=0, columnspan=3,padx = 20, pady = 5)#调整位置
    root.mainloop()#窗口循环运行
基于树莓派的藏头诗生成器图4
总结
这样,藏头诗生成器就制作完成了,这次我们巩固了requests库的使用方法,学会了使用lxml库来解析和提取html网页数据,本次我们只是将藏头词放置在了诗头的位置,你还可以通过修改程序来体验感受剩余的几种方式会产生什么样的效果。在生活中类似于这样的网站会有很多种,我们可以开动脑筋思考一下还可以做哪些有趣的案例
相信你还会有更多精彩的创意,赶快去试试吧
造物让生活更美好,我们下期再见
更多精彩内容请关注旺仔爸爸造物社
基于树莓派的藏头诗生成器图40

2022-04-10_235628.jpg
2022-04-10_235612.jpg
2022-04-19_000720.jpg
2022-04-19_000643.jpg

 初级技匠

发表于 2022-4-23 10:13:50

这是个好东西
回复

使用道具 举报

 初级技匠

发表于 2022-4-23 10:18:36

代码乱了,要整理一下
回复

使用道具 举报

TuTu  高级技师

发表于 2022-4-26 09:58:19

有意思
回复

使用道具 举报

派大星ym  初级技匠

发表于 2022-8-1 14:30:43

,,,
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

为本项目制作心愿单
购买心愿单
心愿单 编辑
[[wsData.name]]

硬件清单

  • [[d.name]]
btnicon
我也要做!
点击进入购买页面
上海智位机器人股份有限公司 沪ICP备09038501号-4

© 2013-2024 Comsenz Inc. Powered by Discuz! X3.4 Licensed

mail