用Pyqt 做一个读取系统剪贴板内容,然后通过语音合成(TTS)朗读出剪贴板的内容
知识要点
SpVoice
SpVoice类是支持语音合成(TTS)的核心类。通过SpVoice对象调用TTS引擎,从而实现朗读功能。 SpVoice类有以下主要属性:
Voice:表示发音类型,相当于进行朗读的人,包括Microsoft Mary,Microsoft Mike,Microsoft Sam和Microsoft Simplified Chinese四种。其中前三种只能读英文,最后一种可以读中文,也可以读英文,但对于英文单词只能将其包括的各个字母逐一朗读出来。下面的程序中我们将会想办法解决这个问题。
Rate:语音朗读速度,取值范围为-10到+10。数值越大,速度越快。
Volume:音量,取值范围为0到100。数值越大,音量越大。
SpVoice有以下主要方法:
Speak:完成将文本信息转换为语音并按照指定的参数进行朗读,该方法有Text和Flags两个参数,分别指定要朗读的文本和朗读方式(同步或异步等)。
Pause:暂停使用该对象的所有朗读进程。该方法没有参数。
Resume:恢复该对象所对应的被暂停的朗读进程。该方法没有参数。
python 通过
speaker = win32com.client.Dispatch("SAPI.SpVoice") # Dispatch("APPs") 需要app 注册COM服务, 且APPs是注册的名字
连接到SAPI.SpVoice COM服务
Clipboard剪贴板
python操作剪贴板通过win32clipboard 类库
1 import win32clipboard as w 2 class ClipD(QtCore.QThread): 3 def __init__(self): 4 super(ClipD, self).__init__() 5 tempdir = tempfile.gettempdir() 6 self.fileposition = tempdir+"\ClipSetting.ini" 7 #获取剪贴板内容 8 def getText(self): 9 w.OpenClipboard() 10 d = w.GetClipboardData(win32con.CF_TEXT) 11 w.CloseClipboard() 12 return d 13 # 设置剪贴板内容, 14 def setText(aString): 15 w.OpenClipboard() 16 w.EmptyClipboard() 17 w.SetClipboardData(win32con.CF_TEXT, aString) 18 w.CloseClipboard()
完整代码:
1 # -*- coding: UTF8 -*- 2 from PyQt4 import QtCore, QtGui 3 import os.path, time, tempfile,threading, sys 4 import win32clipboard as w 5 import win32con, pythoncom 6 import win32com.client 7 reload(sys) 8 sys.setdefaultencoding('gbk') 9 ''' 10 SpVoice类是支持语音合成(TTS)的核心类。通过SpVoice对象调用TTS引擎,从而实现朗读功能。 SpVoice类有以下主要属性: 11 Voice:表示发音类型,相当于进行朗读的人,包括Microsoft Mary,Microsoft Mike,Microsoft Sam和Microsoft Simplified Chinese四种。其中前三种只能读英文,最后一种可以读中文,也可以读英文,但对于英文单词只能将其包括的各个字母逐一朗读出来。下面的程序中我们将会想办法解决这个问题。 12 Rate:语音朗读速度,取值范围为-10到+10。数值越大,速度越快。 13 Volume:音量,取值范围为0到100。数值越大,音量越大。 14 SpVoice有以下主要方法: 15 Speak:完成将文本信息转换为语音并按照指定的参数进行朗读,该方法有Text和Flags两个参数,分别指定要朗读的文本和朗读方式(同步或异步等)。 16 Pause:暂停使用该对象的所有朗读进程。该方法没有参数。 17 Resume:恢复该对象所对应的被暂停的朗读进程。该方法没有参数。 18 ''' 19 speaker = win32com.client.Dispatch("SAPI.SpVoice") # Dispatch("APPs") 需要app 注册COM服务, 且APPs是注册的名字 20 21 class Mwindow(QtGui.QDialog): 22 def __init__(self): 23 super(Mwindow, self).__init__() 24 self.resize(100, 60) 25 self.setWindowFlags(QtCore.Qt.WindowStaysOnTopHint) 26 self.setWindowTitle('speaker') 27 self.startser = QtGui.QPushButton(u'start') 28 self.pause = QtGui.QPushButton(u"status") 29 self.textarea = QtGui.QTextEdit() 30 self.textarea.setReadOnly(True) 31 self.textarea.setStyleSheet("QWidget { background-color: black;color:yellow;}")#样式表改变背景颜色 32 #top Layout 33 self.toplayout= QtGui.QHBoxLayout() 34 self.toplayout.addSpacing(0) # 空间距离 addSpacing 不可为空 35 self.toplayout.addWidget(self.startser) 36 self.toplayout.addWidget(self.pause) 37 #mainLayout 38 self.MainLayout = QtGui.QVBoxLayout() 39 self.MainLayout.addLayout(self.toplayout, 1) 40 self.MainLayout.addWidget(self.textarea, 1) 41 self.setLayout(self.MainLayout) 42 self.MainLayout.setContentsMargins(0, 0, 0, 0) # 距离边缘的距离 43 self.MainLayout.setSpacing(0) # 空间距离 44 45 self.connect(self.startser, QtCore.SIGNAL('clicked()'), self.starting) 46 self.connect(self.pause, QtCore.SIGNAL('clicked()'), self.paused) 47 #开始线程读取 48 def starting(self): 49 self.thread = ClipD() 50 self.connect(self.thread, QtCore.SIGNAL('updateresult'), self.showtextarea) 51 self.thread.start() 52 self.startser.setText('starting') 53 54 # 暂停 55 def paused(self): 56 btnname = self.pause.text() 57 if btnname == 'status' or btnname =='stop': 58 speaker.pause() 59 self.pause.setText('resume') 60 elif btnname == 'resume': 61 speaker.resume() 62 self.pause.setText('stop') 63 64 # 同步剪贴板的内容到text中 65 def showtextarea(self, text): 66 self.say(text) 67 self.textarea.setText(u''+text) 68 #读线程 69 def sayThread(self, talk): 70 pythoncom.CoInitialize() 71 speaker.Speak(talk) 72 73 def say(self, talk): 74 threading.Thread(target=self.sayThread, args=(talk, )).start() # args是元组 75 76 77 78 class ClipD(QtCore.QThread): 79 def __init__(self): 80 super(ClipD, self).__init__() 81 tempdir = tempfile.gettempdir() 82 self.fileposition = tempdir+"\ClipSetting.ini" 83 #获取剪贴板内容 84 def getText(self): 85 w.OpenClipboard() 86 d = w.GetClipboardData(win32con.CF_TEXT) 87 w.CloseClipboard() 88 return d 89 # 设置剪贴板内容, 90 def setText(aString): 91 w.OpenClipboard() 92 w.EmptyClipboard() 93 w.SetClipboardData(win32con.CF_TEXT, aString) 94 w.CloseClipboard() 95 # 获取临时目录记录的old 剪贴板内容 96 def getTmpText(self): 97 if os.path.exists(self.fileposition): 98 settingsFile = open(self.fileposition) 99 clip = settingsFile.read() 100 return clip 101 else: 102 return False 103 104 # 设置临时剪贴板目录 105 def setTmpText(self): 106 settingsFile = open(self.fileposition, "w+") 107 clip = self.getText() 108 settingsFile.write(clip) 109 settingsFile.close() 110 111 def run(self): 112 # for i in range(0, 100): 113 while True: 114 old = self.getTmpText() 115 new = self.getText() 116 if old != new: 117 self.setTmpText() 118 self.emit(QtCore.SIGNAL("updateresult"), self.getText()) 119 time.sleep(1) 120 121 if __name__ == '__main__': 122 import sys 123 app = QtGui.QApplication(sys.argv) 124 mainWin = Mwindow() 125 mainWin.show() 126 sys.exit(app.exec_())
效果: