用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 类库
import win32clipboard as w
class ClipD(QtCore.QThread):
def __init__(self):
super(ClipD, self).__init__()
tempdir = tempfile.gettempdir()
self.fileposition = tempdir+"\\ClipSetting.ini"
#获取剪贴板内容
def getText(self):
w.OpenClipboard()
d = w.GetClipboardData(win32con.CF_TEXT)
w.CloseClipboard()
return d
# 设置剪贴板内容,
def setText(aString):
w.OpenClipboard()
w.EmptyClipboard()
w.SetClipboardData(win32con.CF_TEXT, aString)
w.CloseClipboard()
完整代码:
# -*- coding: UTF8 -*-
from PyQt4 import QtCore, QtGui
import os.path, time, tempfile,threading, sys
import win32clipboard as w
import win32con, pythoncom
import win32com.client
reload(sys)
sys.setdefaultencoding('gbk')
'''
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:恢复该对象所对应的被暂停的朗读进程。该方法没有参数。
'''
speaker = win32com.client.Dispatch("SAPI.SpVoice") # Dispatch("APPs") 需要app 注册COM服务, 且APPs是注册的名字 class Mwindow(QtGui.QDialog):
def __init__(self):
super(Mwindow, self).__init__()
self.resize(100, 60)
self.setWindowFlags(QtCore.Qt.WindowStaysOnTopHint)
self.setWindowTitle('speaker')
self.startser = QtGui.QPushButton(u'start')
self.pause = QtGui.QPushButton(u"status")
self.textarea = QtGui.QTextEdit()
self.textarea.setReadOnly(True)
self.textarea.setStyleSheet("QWidget { background-color: black;color:yellow;}")#样式表改变背景颜色
#top Layout
self.toplayout= QtGui.QHBoxLayout()
self.toplayout.addSpacing(0) # 空间距离 addSpacing 不可为空
self.toplayout.addWidget(self.startser)
self.toplayout.addWidget(self.pause)
#mainLayout
self.MainLayout = QtGui.QVBoxLayout()
self.MainLayout.addLayout(self.toplayout, 1)
self.MainLayout.addWidget(self.textarea, 1)
self.setLayout(self.MainLayout)
self.MainLayout.setContentsMargins(0, 0, 0, 0) # 距离边缘的距离
self.MainLayout.setSpacing(0) # 空间距离 self.connect(self.startser, QtCore.SIGNAL('clicked()'), self.starting)
self.connect(self.pause, QtCore.SIGNAL('clicked()'), self.paused)
#开始线程读取
def starting(self):
self.thread = ClipD()
self.connect(self.thread, QtCore.SIGNAL('updateresult'), self.showtextarea)
self.thread.start()
self.startser.setText('starting') # 暂停
def paused(self):
btnname = self.pause.text()
if btnname == 'status' or btnname =='stop':
speaker.pause()
self.pause.setText('resume')
elif btnname == 'resume':
speaker.resume()
self.pause.setText('stop') # 同步剪贴板的内容到text中
def showtextarea(self, text):
self.say(text)
self.textarea.setText(u''+text)
#读线程
def sayThread(self, talk):
pythoncom.CoInitialize()
speaker.Speak(talk) def say(self, talk):
threading.Thread(target=self.sayThread, args=(talk, )).start() # args是元组 class ClipD(QtCore.QThread):
def __init__(self):
super(ClipD, self).__init__()
tempdir = tempfile.gettempdir()
self.fileposition = tempdir+"\\ClipSetting.ini"
#获取剪贴板内容
def getText(self):
w.OpenClipboard()
d = w.GetClipboardData(win32con.CF_TEXT)
w.CloseClipboard()
return d
# 设置剪贴板内容,
def setText(aString):
w.OpenClipboard()
w.EmptyClipboard()
w.SetClipboardData(win32con.CF_TEXT, aString)
w.CloseClipboard()
# 获取临时目录记录的old 剪贴板内容
def getTmpText(self):
if os.path.exists(self.fileposition):
settingsFile = open(self.fileposition)
clip = settingsFile.read()
return clip
else:
return False # 设置临时剪贴板目录
def setTmpText(self):
settingsFile = open(self.fileposition, "w+")
clip = self.getText()
settingsFile.write(clip)
settingsFile.close() def run(self):
# for i in range(0, 100):
while True:
old = self.getTmpText()
new = self.getText()
if old != new:
self.setTmpText()
self.emit(QtCore.SIGNAL("updateresult"), self.getText())
time.sleep(1) if __name__ == '__main__':
import sys
app = QtGui.QApplication(sys.argv)
mainWin = Mwindow()
mainWin.show()
sys.exit(app.exec_())
效果: