电子书阅读器
演示效果
读取当前文件夹中的txt文件(你需要自己下载或者生成一下) 通过上下按键选择对应的文件名,当选到时,所在行文本颜色变成红色。
按下确认键选择对应的文件,即可进入阅读模式,阅读模式与常规MP4一致上下翻页,双击确认键退出。
阅读模式中自动判断中英及标点文本的宽度、结合换行符进行排版。
那么书籍从哪里来?可以通过微信小程序蓝牙传输(源代码见文末),如下方式:
代码
import os
import uTFT
import ubersam
# 屏幕配置
tft = uTFT.TFT(rotation=0)
screen_width = 9 # 屏幕宽度为9个汉字
screen_height = 9 # 屏幕高度为9个汉字
char_height = 16 # 每个汉字的高度为16个像素
char_width_chinese = 1 # 每个汉字和汉字标点占用1个宽度单位
char_width_english = 0.5 # 每个英文字符和标点占用0.5个宽度单位
def get_char_width(char):
"""获取字符的宽度单位"""
if '\u4e00' <= char <= '\u9fff' or '\u3000' <= char <= '\u303f': # 汉字和汉字标点
return char_width_chinese
else:
return char_width_english
def split_text(text, max_width):
"""根据屏幕宽度将文本分割成多行"""
lines = []
current_line = ""
current_width = 0
for char in text:
if char == '\n':
lines.append(current_line)
current_line = ""
current_width = 0
else:
char_width = get_char_width(char)
if current_width + char_width > max_width:
lines.append(current_line)
current_line = char
current_width = char_width
else:
current_line += char
current_width += char_width
if current_line:
lines.append(current_line)
return lines
def display_page(tft, lines, page, lines_per_page, highlight_line=None):
"""显示指定页码的文 本"""
start_line = page * lines_per_page
end_line = start_line + lines_per_page
page_lines = lines[start_line:end_line]
tft.fill(uTFT.BLACK) # 清空屏幕
for i, line in enumerate(page_lines):
y_position = i * char_height
color = 0xff0000 if highlight_line is not None and start_line + i == highlight_line else 0xffffff
tft.shows_text(line, x=0, y=y_position, center=False, color=color)
def get_txt_files():
"""获取当前文件夹中所有 .txt 文件的文件名(不包含扩展名)"""
txt_files = [f[:-4] for f in os.listdir() if f.endswith('.txt')]
return txt_files
def read_file_content(filename):
"""读取文件内容"""
with open(f"{filename}.txt", 'r', encoding='utf-8') as file:
return file.read()
def main():
txt_files = get_txt_files()
if not txt_files:
tft.shows_text("No .txt files found", x=0, y=0, center=False, color=0xffffff)
return
current_selection = 0
file_selection_mode = True
display_page(tft, txt_files, 0, screen_height, highlight_line=current_selection)
while file_selection_mode:
if ubersam.button_right.was_pressed() and current_selection < len(txt_files) - 1:
current_selection += 1
display_page(tft, txt_files, 0, screen_height, highlight_line=current_selection)
if ubersam.button_left.was_pressed() and current_selection > 0:
current_selection -= 1
display_page(tft, txt_files, 0, screen_height, highlight_line=current_selection)
if ubersam.button_ok.was_pressed():
file_selection_mode = False
selected_file = txt_files[current_selection]
# 进入阅读模式
text = read_file_content(selected_file)
lines = split_text(text, screen_width)
lines_per_page = screen_height
total_pages = (len(lines) + lines_per_page - 1) // lines_per_page
current_page = 0
display_page(tft, lines, current_page, lines_per_page)
while True:
if ubersam.button_right.was_pressed():
if current_page < total_pages - 1:
current_page += 1
display_page(tft, lines, current_page, lines_per_page)
if ubersam.button_left.was_pressed():
if current_page > 0:
current_page -= 1
display_page(tft, lines, current_page, lines_per_page)
main()
MP_NUM = 1
MP_FILE= "read"
蓝牙传书接收 方代码
import uTFT
import ble_peripheral
tft = uTFT.TFT(rotation=0)
文件名称 = ""
分片数 = 0
当前分片 = 0
接收缓存 = bytearray()
进度 = "0"
def ble_method(data):
global 文件名称, 分片数, 当前分片, 接收缓存,进度
print(type(data), data)
# 处理文件信息
if 分片数 == 0:
# 文件信息以字符串形式处理
文件信息 = data.split('|')
文件名称 = 文件信息[0]
分片数 = int(文件信息[1])
print(f"接收到的文件名称: {文件名称}, 分片数: {分片数}")
elif data != 'END' :
# 将接收到的数据块写入文件
接收缓存.extend(data)
当前分片 += 1
else:
print("文件接收完毕开始保存")
with open(文件名称, 'wb',encoding="utf-8") as f:
f.write(接收缓存)
print("文件保存成功")
分片数 = 0
当前分片 = 0
进度 = ":100%"
return
# 计算并显示当前进度
进度 = ":" + str(int((当前分片 / 分片数) * 100))+ "%"
# 初始化 BLE 外设
ble_p = ble_peripheral.BLESimplePeripheral('btspark')
tft.shows_text(f"蓝牙传输助手", x=0, y=30, center=True, color=0xffffff)
ble_p.recv(ble_method)
while True:
tft.shows_text(文件名称+进度, x=0, y=50, center=True, color=0xffffff)
MP_NUM = 2
MP_FILE= "load"
蓝牙传书发送方小程序代码
书籍需要为txt格式,utf-8编码格式,大小不超过0.5B
微信小程序源代码 miniprogram-3.zip