zl程序教程

您现在的位置是:首页 >  其它

当前栏目

Pyqt SpVoice朗读功能

功能 Pyqt
2023-09-11 14:17:02 时间

用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_())

 

效果: