【基于python tkinter的本地小说阅读器】

历史文章

1.记录基于Python tkinter的音乐播放器的实现过程



前言

之前有用过carlibre在电脑上看小说,carlibre整体感觉还不错,引入小说然后转换就可以阅读了,有点不爽的是,转换有点慢,等待时间有点长。现在利用python tinker来模拟carlibre转换、阅读小说。


一、阅读器功能设计思路

1.转换功能:这里的转换不是将".txt"转换“.epub”格式的小说,而是将txt小说按章节切割、转换为多个章节文本,并且形成章节目录,方便使用者根据目录阅读。

2.选择小说:转换后会在txt小说的文件目录下生成小说同名文件夹,里面包含转换后的章节文件。阅读者选择该同名文件夹即可阅读。

3.阅读小说:读取当前选中的小说章节,将章节内容插入到阅读区。

4.上/下章:根据当前小说章节索引,操作读取上/下章文件内容。

5.阅读记录:记录阅读该小说时的章节次序,方便阅读者查看自己的阅读痕迹,同时方便再次打开该小说时,立马读取到上次阅读的最新章节。

6.朗读:机器朗读阅读区的文字内容,可以停止和继续朗读,朗读语速也可以调节。并且阅读区自动跟踪当前朗读的小说段落。朗读引擎选择的是pyttsx3。

7.字体设置:目前设置适配有“楷体”,“隶书”,“微软雅黑”三款字体。默认楷体,因为个人感觉楷体最简洁美观,阅读时赏心悦目。因为不同的字体,字体的像素也不同,所以切换字体时,组件的尺寸大小也会伸缩。为了达到美观,在切换字体时,需重新适配字体对应的参数。

二、阅读器使用展示

1.准备工作:将下载好的txt小说放到某个文件夹下,这里以《诛仙》小说为例。
txt小说位置
2.点击界面的转换按钮,在文件资源管理器里选择txt小说,就会自动转换。转换时按钮会亮,转换完成后会变回原来的颜色,所以可以根据颜色判断是否转换完成。转换完成后,在txt小说文件目录下,会看到小说同名文件夹。

转换一次就行,下次阅读直接通过选择按钮打开小说同名文件夹就可以了。
转换完成生成同名文件夹
3.点击“选择”按钮,在文件资源管理器里选择同名小说文件夹,如果是第一次打开该小说,就会读取小说最前面的章节;如果阅读过,就会打开上次读到过的最新章节。点击记录按钮可以查看阅读章节痕迹。
首次打开小说
4. 读取章节:选中目录框里章节,点击读取按钮,阅读区就会该章内容。也可以双击章节打开,或者通过上/下章来打开章节内容。
阅读下一章
5.查看阅读记录,最新阅读的章节在上面,最早阅读过的章节在下面。这里的背景颜色本应是灰色的,为了方便展示,特地调成白色。因为读者在阅读时不会太在意章节、记录这些,而目录的白色或其他颜色,会太过显眼而吸引读者的目光,削弱读者对阅读区的注意力。因而背景颜色默认都是灰黑色。
阅读章节记录
6.打开小说文件夹,可以看到3项
chapter文件夹,里面存放切割后的章节文本
chapterName.txt 记录小说的章节目录
readRecord.txt 记录阅读过的章节
小说文件夹
7.朗读功能:打开某章节,点击朗读,就会重头开始朗读本章内容。
可以停止/继续朗读, 点击“慢速”、“快速”用来调节朗读语速。
朗读功能
8.字体设置:“楷体”显示当前的字体,默然楷体。点击“楷体”,可以切换阅读的字体。

微软黑体
隶书

ps: 按钮区空出来的两个位置,后续想到新的功能,再将按钮补上吧。


三、 代码展示

下面是阅读器的完整代码:

import tkinter as tk
from tkinter import *
from tkinter import filedialog
from tkinter import ttk
from tkinter import scrolledtext
import os
import time
import threading
import pyttsx3
import shutil


class Reader():
	def __init__(self):

		# colors
		self.GlobalColor = '#F1E9D2'  # 羊皮纸颜色
		self.lightyellow = '#FFE57D'
		self.gray = "#414441"
		black = "#081010" #rgb(8,16,16) 背景色:暗黑色

		self.COLOR_SIZE = 12
		self.myColors = [self.GlobalColor]*self.COLOR_SIZE

		self.wordStyle = '楷体'
		self.bgStyle = self.gray
		self.fgStyle = 'white'
		self.fsize = 12
		self.oneSize = 4
		self.numSize = 3
		self.listbox_WidthSize = 45
		self.listbox_HeightSize = 52
		self.scorllT_WidthSize = 80
		self.scorllT_HeightSize = 28
		self.Label_novelName_size = 30
		self.Label_chapterName_size = 89

		self.PressCnt = 0
		self.SPEED = 200
		self.Step = 50

		self.OrientPath = ""
		self.chapterName_path = ""
		self.chapterId = 0
		self.BreakNum = 40


		self.CHANGE_NEW = 0
		self.FlagNo = 0
		self.SWITCH = 1

		# 朗读初始化
		self.speak = pyttsx3.init()

		self.screen = tk.Tk()
		self.screen.geometry('1500x700')
		self.screen.title('本地阅读器')
		

		# 小说名
		self.StrngVar_novelName = tk.StringVar()
		self.Label_novelName = tk.Label(self.screen, width=self.Label_novelName_size, height=2, fg=self.fgStyle, bg=self.bgStyle, font=(self.wordStyle, self.fsize+self.oneSize),
	                        textvariable=self.StrngVar_novelName)
		self.Label_novelName.place(x=400, y=10)

		# 章节名
		self.StrngVar_chapterName = tk.StringVar()
		self.Label_chapterName = tk.Label(self.screen, width=self.Label_chapterName_size, height=2, fg=self.fgStyle, bg=self.bgStyle, font=(self.wordStyle, self.fsize+self.oneSize),
	                        textvariable=self.StrngVar_chapterName)
		self.Label_chapterName.place(x=700, y=10)

		#滑动条
		self.scroll1 = tk.Scrollbar(self.screen)
		self.ListBox_chapterName = tk.Listbox(self.screen, width=self.listbox_WidthSize, height=self.listbox_HeightSize, bg=self.bgStyle, fg=black, font=(self.wordStyle, self.fsize),
		             yscrollcommand=self.scroll1.set)
		#章节名列表框
		self.ListBox_chapterName.config(yscrollcommand=self.scroll1.set)
		self.scroll1.config(command=self.ListBox_chapterName.yview)

		self.ListBox_chapterName.place(x=20, y=105)
		self.scroll1.pack(side='left', fill='both')

		# 选择小说文件夹
		self.Button_chooseFloder = tk.Button(self.screen, text='选择', bg=self.GlobalColor, fg=black, font=(self.wordStyle, self.fsize), command=self.get_floder)
		self.Button_chooseFloder.place(x=20, y=10)
		self.CreateToolTip(self.Button_chooseFloder, "选择小说文件夹")

		# 列出章节按钮
		self.Button_readMenu = tk.Button(self.screen, text='目录', bg=self.GlobalColor, fg=black, font=(self.wordStyle, self.fsize), command=self.readChapterName)
		self.Button_readMenu.place(x=70, y=10)
		self.CreateToolTip(self.Button_readMenu, "显示目录")

		# 读取章节按钮
		self.Button_readTxt = tk.Button(self.screen, text='读取', bg=self.GlobalColor, fg=black, font=(self.wordStyle, self.fsize), command=self.readText)
		self.Button_readTxt.place(x=120, y=10)
		self.CreateToolTip(self.Button_readTxt, "读取选中的章节")

		# 阅读历史
		self.Button_readHistory = tk.Button(self.screen, text='记录', bg=self.GlobalColor, fg=black, font=(self.wordStyle, self.fsize), command=self.readHistory)
		self.Button_readHistory.place(x=170, y=10)
		self.CreateToolTip(self.Button_readHistory, "显示阅读该小说的章节痕迹")

		# 转换分割小说
		self.Button_splitChapter = tk.Button(self.screen, text='转换', bg=self.GlobalColor, fg=black, font=(self.wordStyle, self.fsize), command=self.split_chapter)
		self.Button_splitChapter.place(x=220, y=10)
		self.CreateToolTip(self.Button_splitChapter, "选中txt小说转换")

		# 自动朗读小说
		self.Button_scrollread = tk.Button(self.screen, text='朗读', bg=self.GlobalColor, fg=black, font=(self.wordStyle, self.fsize), command=lambda: self.thread_it(self.srcollRead))
		self.Button_scrollread.place(x=270, y=10)
		self.CreateToolTip(self.Button_scrollread, "机器朗读")

		# 停止朗读小说
		self.Button_scrollreadStop = tk.Button(self.screen, text='停止', bg=self.GlobalColor, fg=black, font=(self.wordStyle, self.fsize), command=self.srcollReadStop)
		self.Button_scrollreadStop.place(x=320, y=10)
		self.CreateToolTip(self.Button_scrollreadStop, "停止朗读")

		# 字体设置
		self.Button_setFont = tk.Button(self.screen, text='楷体', bg=self.GlobalColor, fg=black, font=(self.wordStyle, self.fsize), command=self.setFont)
		self.Button_setFont.place(x=20, y=60)
		self.CreateToolTip(self.Button_setFont, "设置字体")

		# 上一章
		self.Button_lastChapter = tk.Button(self.screen, text='上章', bg=self.GlobalColor, fg=black, font=(self.wordStyle, self.fsize), command=self.lastChapter)
		self.Button_lastChapter.place(x=70, y=60)
		self.CreateToolTip(self.Button_lastChapter, "读取上一章")

		# 下一章
		self.Button_nextChapter = tk.Button(self.screen, text='下章', bg=self.GlobalColor, fg=black, font=(self.wordStyle, self.fsize), command=self.nextChapter)
		self.Button_nextChapter.place(x=120, y=60)
		self.CreateToolTip(self.Button_nextChapter, "读取下一章")

		# 减慢朗读速度
		self.Button_voiceReduce = tk.Button(self.screen, text='慢速', bg=self.GlobalColor, fg=black, font=(self.wordStyle, self.fsize), command=self.voiceReduce)
		self.Button_voiceReduce.place(x=270, y=60)
		self.CreateToolTip(self.Button_voiceReduce, "朗读减慢")

		# 减慢朗读速度
		self.Button_voiceIncrease = tk.Button(self.screen, text='快速', bg=self.GlobalColor, fg=black, font=(self.wordStyle, self.fsize), command=self.voiceIncrease)
		self.Button_voiceIncrease.place(x=320, y=60)
		self.CreateToolTip(self.Button_voiceIncrease, "朗读加快")

		# 阅读区
		self.Scoller_text = scrolledtext.ScrolledText(self.screen, width=self.scorllT_WidthSize, height=self.scorllT_HeightSize, wrap = tk.WORD, bg=self.bgStyle, fg=self.fgStyle, font=(self.wordStyle, self.fsize+self.numSize*self.oneSize))
		self.Scoller_text.place(x=400, y=60)


		self.ListBox_chapterName.bind('<Double-Button-1>', self.readText)
		self.ListBox_chapterName.bind('<Return>', self.readText)

		self.screen.mainloop()


	# 设置字体
	def setFont(self, *args):

		self.setColor(7)
		if(self.PressCnt%3 == 0):
			self.wordStyle = "微软雅黑"
			self.fsize = 12
			self.listbox_WidthSize = 40
			self.listbox_HeightSize = 40
			self.scorllT_WidthSize = 80
			self.scorllT_HeightSize = 26
			self.Label_chapterName_size = 75
			self.numSize = 2
			self.Button_setFont.config(text="雅黑", font=(self.wordStyle,self.fsize))
			self.BreakNum = 47
			
		elif(self.PressCnt%3 == 1):
			self.wordStyle = "隶书"
			self.fsize = 14
			self.listbox_WidthSize = 37
			self.listbox_HeightSize = 44
			self.scorllT_WidthSize = 71
			self.scorllT_HeightSize = 26
			self.Label_chapterName_size = 81
			self.numSize = 3
			self.Button_setFont.config(text="隶书",font=(self.wordStyle,self.fsize))
			self.BreakNum = 35

		else:
			self.wordStyle = "楷体"
			self.fsize = 12
			self.listbox_WidthSize = 45
			self.listbox_HeightSize = 52
			self.scorllT_WidthSize = 80
			self.scorllT_HeightSize = 28
			self.Label_novelName_size = 30
			self.Label_chapterName_size = 89
			self.numSize = 3
			self.Button_setFont.config(text="楷体", font=(self.wordStyle,self.fsize))
			self.BreakNum = 40
		
		self.Label_novelName.config(width=self.Label_novelName_size,font=(self.wordStyle, self.fsize+self.oneSize))
		self.Label_chapterName.config(width=self.Label_chapterName_size, font=(self.wordStyle, self.fsize+self.oneSize))
		self.ListBox_chapterName.config(width=self.listbox_WidthSize, height=self.listbox_HeightSize,font=(self.wordStyle,self.fsize))
		self.Button_chooseFloder.config(font=(self.wordStyle,self.fsize))
		self.Button_readMenu.config(font=(self.wordStyle,self.fsize))
		self.Button_readTxt.config(font=(self.wordStyle,self.fsize))
		self.Button_readHistory.config(fon=(self.wordStyle,self.fsize))
		self.Button_splitChapter.config(font=(self.wordStyle,self.fsize))
		self.Button_scrollread.config(font=(self.wordStyle,self.fsize))
		self.Button_scrollreadStop.config(font=(self.wordStyle,self.fsize))
		self.Button_lastChapter.config(fon=(self.wordStyle,self.fsize))
		self.Button_nextChapter.config(font=(self.wordStyle,self.fsize))
		self.Button_voiceReduce.config(font=(self.wordStyle,self.fsize))
		self.Button_voiceIncrease.config(font=(self.wordStyle,self.fsize))
		
		self.Scoller_text.config(width=self.scorllT_WidthSize, height=self.scorllT_HeightSize,font=(self.wordStyle, self.fsize+self.numSize*self.oneSize))
		self.fillScrolledText()
		self.PressCnt += 1
		

	# 点击按钮时色亮,突出显现
	def setColorWay(self, way, *args):
	    for i in range(self.COLOR_SIZE):
	        if way == i:
	            self.myColors[i] = self.lightyellow
	        else:
	            self.myColors[i] = self.GlobalColor
	   

	# button颜色变换封装
	def buttonColor(self, *args):

	    self.Button_chooseFloder.config(bg=self.myColors[0])
	    self.Button_readMenu.config(bg=self.myColors[1])
	    self.Button_readTxt.config(bg=self.myColors[2])
	    self.Button_readHistory.config(bg=self.myColors[3])
	    self.Button_splitChapter.config(bg=self.myColors[4])
	    self.Button_scrollread.config(bg=self.myColors[5])
	    self.Button_scrollreadStop.config(bg=self.myColors[6])
	    self.Button_setFont.config(bg=self.myColors[7])
	    self.Button_lastChapter.config(bg=self.myColors[8])
	    self.Button_nextChapter.config(bg=self.myColors[9])
	    self.Button_voiceReduce.config(bg=self.myColors[10])
	    self.Button_voiceIncrease.config(bg=self.myColors[11])

	# 设置点击时的颜色
	def setColor(self, num):
		self.setColorWay(num)
		self.buttonColor()
	

	# 选择小说
	def get_floder(self, *args):
		self.setColor(0)
		order = self.threadChangeFlag()
		self.OrientPath = filedialog.askdirectory()
		start = len(self.OrientPath) - self.OrientPath[::-1].index("/")
		novel = "《 "+self.OrientPath[start:]+" 》"
		self.StrngVar_novelName.set(novel)
		self.readChapterName()

	# 分割小说时保存章节名
	def write_Name(self, chapter_name):
		chapterName = self.OrientPath + "\\" + "chapterName.txt"
		with open(chapterName, "a") as f:
			f.write(chapter_name)
			f.write("\n")

	# 获取小说的章节名
	def get_name(self, line):
		jieName = ""
		chapter = self.OrientPath + "\\chapter"
		if (("第" in line) 
			and ( ( ("回 " in line) or ("章 " in line) or ("节 " in line) 
			or ("卷 " in line) or ("部 " in line) ) 
			or ( ("回:" in line) or ("章:" in line) or ("节:" in line) 
			or ("卷:" in line) or ("部:" in line)) ) ):
			line = "".join([char for char in line if(char != "?") or (char != "*")])

			jieName = chapter + "\\" + line.strip() + ".txt"
			self.write_Name(jieName)
		
		return jieName

	# 换行
	def lineBreak(self, line):
		
		cnt = 1
		if(line.strip() == ""):
			return line
		string = "\n"
		for i in range(len(line)):
			string = string+line[i]
			if(cnt%self.BreakNum==0):
				string = string + "\n\n"
			cnt += 1
		return string

	# 按小说章节名分割
	def split_chapter(self):
		
		self.setColor(4)
		order = self.threadChangeFlag()

		file = filedialog.askopenfilename()
		start = len(file) - file[::-1].index("/")
		end = file.index(".txt")
		floder_path = file[:end]
		floder_name = file[start:end]
		self.OrientPath = floder_path

		if os.path.exists(floder_path):
			for f in os.listdir(floder_path):
				file_path = os.path.join(floder_path, f)
				if(f.endswith(".txt")):
					os.remove(file_path)
				else:
					shutil.rmtree(file_path)
			os.rmdir(floder_path)
		else:
			os.makedirs(floder_path)
		
		chapter_path = floder_path+"\\chapter"
		os.makedirs(chapter_path)

		chapterName = ""
		with open(file, "r", encoding="utf-8") as f:
			try:
				lines = f.readlines()
				for line in lines:
					jieName = self.get_name(line)
					if(len(jieName)>1):
						chapterName = jieName
					if(len(chapterName)>1):
						with open(chapterName, "a+") as f2:
							f2.write(line)
							f2.write("\n")
			except:
				with open(file, "r", encoding="gbk") as f:
					lines = f.readlines()
					for line in lines:
						jieName = self.get_name(line)
						if(len(jieName)>1):
							chapterName = jieName
						if(len(chapterName)>1):
							with open(chapterName, "a+") as f2:
								f2.write(line)
								f2.write("\n")

		print(f"《 {floder_name} 》转换完成!")
		self.setColor(self.COLOR_SIZE)

	# 截取小说章节名
	def get_chaterName(self, string):
		start = string.index("第")
		name = string[start:-5]
		return name

	# 按保存的章节名读取出来就是小说目录了
	def readChapterName(self, *args):

		chapterName = self.OrientPath + "\\" + "chapterName.txt"
		readRecord = self.OrientPath + "\\" + "readRecord.txt"
		path = self.OrientPath + "\\" + "chapter"
		self.setColor(1)
		order = self.threadChangeFlag()

		first_chapter = ""
		with open(chapterName, 'r+', encoding="utf-8") as f:
			try:
				lines = f.readlines()
				first_chapter = lines[0]
				self.ListBox_chapterName.delete(0, tk.END)
				for line in lines:
					name = self.get_chaterName(line)
					self.ListBox_chapterName.insert('end', name)
			except:
				with open(chapterName, 'r+',encoding="gbk") as f:
					lines = f.readlines()
					first_chapter = lines[0]
					self.ListBox_chapterName.delete(0, tk.END)
					for line in lines:
						name = self.get_chaterName(line)
						self.ListBox_chapterName.insert('end', name)

		try:
			with open(readRecord, 'r+') as f1:
				lines = f1.readlines()
				if(len(lines)>0):
					lines.reverse()
					line = lines[0]
					end = line.index(":")
					index = int(line[:end])				
					self.chapterId = self.ListBox_chapterName.index(index)
					self.chapterName_path = path+"\\"+line[end+1:].strip() +".txt"
					self.StrngVar_chapterName.set(line[end+1:].strip())
					self.Scoller_text.delete(1.0, tk.END)
					self.listBoxSee()
					with open(self.chapterName_path, 'r') as f2:
						lines = f2.readlines()
						for line in lines:
							strings = self.lineBreak(line)
							self.Scoller_text.insert("end", strings)
		except:
			self.chapterName_path = first_chapter.strip()
			self.StrngVar_chapterName.set(self.get_chaterName(first_chapter))
			self.chapterId = 0
			self.listBoxSee()
			with open(self.chapterName_path,"r", encoding="utf-8") as f3:
				try:
					lines = f3.readlines()
					self.Scoller_text.delete(1.0, tk.END)
					for line in lines:
						strings = self.lineBreak(line)
						self.Scoller_text.insert("end", strings)
				except:
					with open(self.chapterName_path,"r", encoding="gbk") as f3:
						lines = f3.readlines()
						self.Scoller_text.delete(1.0, tk.END)
						for line in lines:
							strings = self.lineBreak(line)
							self.Scoller_text.insert("end", strings)
			

	# 每读取一章,就保存该章节的名字
	def mark(self, string):
		readRecord = self.OrientPath + "\\" + "readRecord.txt"
		with open(readRecord, "a+") as f:
			f.write(string)
			f.write("\n")

	# 换字体时重新读取阅读区
	def fillScrolledText(self):

		self.Scoller_text.delete(1.0, tk.END)
		with open(self.chapterName_path, "r") as f:
			lines = f.readlines()
			for line in lines:
				strings = self.lineBreak(line)
				self.Scoller_text.insert("end", strings)

	# 读取小说章节
	def readText(self, *args):

		order = self.threadChangeFlag()
		self.setColor(2)

		path = self.OrientPath + "\\" + "chapter"
		chapterName = self.ListBox_chapterName.get(self.ListBox_chapterName.curselection())
		self.chapterId = self.ListBox_chapterName.index(self.ListBox_chapterName.curselection())
		self.StrngVar_chapterName.set(self.ListBox_chapterName.get(self.ListBox_chapterName.curselection()))
		self.chapterName_path = path+"\\"+chapterName+".txt"
		string = str(self.chapterId) + ":" + chapterName
		self.mark(string)
		self.Scoller_text.delete(1.0, tk.END)
		with open(self.chapterName_path, "r") as f:
			lines = f.readlines()
			for line in lines:
				strings = self.lineBreak(line)
				self.Scoller_text.insert("end", strings)

	# 读取阅读后的章节历史
	def readHistory(self, *args):
		readRecord = self.OrientPath + "\\" + "readRecord.txt"
		self.ListBox_chapterName.delete(0,tk.END)
		order = self.threadChangeFlag()
		self.setColor(3)
		
		with open(readRecord, "r+") as f:
			lines = f.readlines()
			lines.reverse()
			for line in lines:
				self.ListBox_chapterName.insert('end', line)

	# 滚动浏览需要用到延时,所以需要线程
	# 这是线程的信令
	def threadChangeFlag(self, *args):
	    if self.FlagNo >= 100:
	        self.FlagNo = 0
	    else:
	        self.FlagNo += 1

	    self.CHANGE_NEW = self.FlagNo
	    return self.FlagNo

	# 无参数传递的线程封装,按钮函数
	def thread_it(self, func, *args):
	    '''将函数放入线程中执行'''
	    # 创建线程
	    t = threading.Thread(target=func, args=args)
	    # 守护线程
	    t.setDaemon = True
	    # 启动线程
	    t.start()
	    # 等待结束
	    # t.join()

	# 朗读速度增加
	def voiceIncrease(self, *args):
		self.SPEED += self.Step
		self.setColor(11)
		return self.SPEED

	# 朗读速度减慢
	def voiceReduce(self, *args):
		self.SPEED -= self.Step
		self.setColor(10)
		return self.SPEED

	# 朗读文本
	def recitation(self, text):
		self.speak.setProperty("rate", self.SPEED)
		self.speak.setProperty("voice", "zh+m7")
		self.speak.say(text)
		self.speak.runAndWait()

	# 滚动朗读
	def srcollRead(self, *args):

		lines = []
		size = 0
		index = 0
		order = self.threadChangeFlag()
		self.setColor(5)
		
		with open(self.chapterName_path, "r") as f:
			lines = f.readlines()
			size = len(lines)

		self.Scoller_text.delete(1.0, tk.END)

		while(index < size and order == self.CHANGE_NEW):
			
			if(self.SWITCH == 1):
				paragraph = lines[index]
				text = self.lineBreak(paragraph)
				
				self.Scoller_text.insert(tk.END, text)
				self.Scoller_text.update()
				self.Scoller_text.see(tk.END)
				self.recitation(text)				

				index += 1
				
			elif(self.SWITCH == 0):
				index += 0
				time.sleep(1)
		

	# 停止滚动浏览
	def srcollReadStop(self, *args):
		self.setColor(6)
		if(self.SWITCH == 1):
			self.SWITCH = 0
			self.Button_scrollreadStop.config(text="停止")
		else:
			self.SWITCH = 1
			self.Button_scrollreadStop.config(text="继续")
		
			

	# 上下章的中间处理过程
	def chapterProcess(self):

		chapterName = self.ListBox_chapterName.get(self.chapterId)
		self.chapterName_path = self.OrientPath + "\\" + "chapter" + "\\" + chapterName + ".txt"
		self.StrngVar_chapterName.set(chapterName)
		string = str(self.chapterId) + ":" + chapterName
		self.mark(string)
		self.listBoxSee()
		
		self.Scoller_text.delete(1.0, tk.END)
		with open(self.chapterName_path, "r", encoding="utf-8") as f:
			lines = f.readlines()
			for line in lines:
				strings = self.lineBreak(line)
				self.Scoller_text.insert("end", strings)

	# 上一章
	def lastChapter(self, *args):
		
		order = self.threadChangeFlag()
		self.setColor(8)

		self.chapterId -= 1
		self.chapterProcess()
		
	# 下一章
	def nextChapter(self, *args):
		order = self.threadChangeFlag()
		self.setColor(9)

		self.chapterId += 1
		self.chapterProcess()

	# 跟踪显示章节名
	def listBoxSee(self):
		self.ListBox_chapterName.selection_clear(0, 'end')
		self.ListBox_chapterName.selection_set(self.chapterId)
		self.ListBox_chapterName.see(self.chapterId)

	#创建该控件的函数
	"""
	第一个参数:是定义的控件的名称
	第二个参数,是要显示的文字信息
	"""
	def CreateToolTip(self, widget, text):
		toolTip = ToolTip(widget)
		def enter(event):
		    toolTip.showtip(text)
		def leave(event):
		    toolTip.hidetip()
		widget.bind('<Enter>', enter)
		widget.bind('<Leave>', leave)

#对提示信息控件的定义
class ToolTip(object):

    def __init__(self, widget):
        self.widget = widget
        self.tipwindow = None
        self.id = None
        self.x = self.y = 0
    #当光标移动指定控件是显示消息
    def showtip(self, text):
        "Display text in tooltip window"
        self.text = text
        if self.tipwindow or not self.text:
            return
        x, y, cx, cy = self.widget.bbox("insert")
        x = x + self.widget.winfo_rootx()+30
        y = y + cy + self.widget.winfo_rooty()+30
        self.tipwindow = tw = Toplevel(self.widget)
        tw.wm_overrideredirect(True)
        tw.wm_geometry("+%d+%d" % (x, y))
        label = Label(tw, text=self.text,justify=LEFT,
                      background="white", relief=SOLID, borderwidth=1,
                      font=("雅黑", "10"))
        label.pack(side=BOTTOM)
    #当光标移开时提示消息隐藏
    def hidetip(self):
        tw = self.tipwindow
        self.tipwindow = None
        if tw:
            tw.destroy()




if __name__ == "__main__":
	app = Reader()
	





  • 18
    点赞
  • 14
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值