• Python 实现点名系统


    安装扩展库pywin32和speech,然后修改一下speech.py文件使得适用于Python 3.x。

    步骤1:安装pywin32

    在命令行模式运行:

    pip install pywin32

    安装出现超时错误,如下:

     用镜像安装:

     pip --default-timeout=1000 install -U pywin32 -i http://pypi.douban.com/simple/ --trusted-host pypi.douban.com

    步骤2:安装扩展库speech

    安装扩展库speech

    pip3 install speech

    然后修改speech.py 文件使得适用于Python 3.x,重点修改之处如图,

     改为:

    改为:

    改为:

    完整的speech.py代码如下

    """
    speech recognition and voice synthesis module.
    
    Please let me know if you like or use this module -- it would make my day!
    
    speech.py: Copyright 2008 Michael Gundlach  (gundlach at gmail)
    License: Apache 2.0 (http://www.apache.org/licenses/LICENSE-2.0)
    
    For this module to work, you'll need pywin32 (http://tinyurl.com/5ezco9
    for Python 2.5 or http://tinyurl.com/5uzpox for Python 2.4) and
    the Microsoft Speech kit (http://tinyurl.com/zflb).
    
    
    Classes:
        Listener: represents a command to execute when phrases are heard.
    
    Functions:
        say(phrase): Say the given phrase out loud.
        input(prompt, phraselist): Block until input heard, then return text.
        stoplistening(): Like calling stoplistening() on all Listeners.
        islistening(): True if any Listener is listening.
        listenforanything(callback): Run a callback when any text is heard.
        listenfor(phraselist, callback): Run a callback when certain text is heard.
    
    
    Very simple usage example:
    
    import speech
    
    speech.say("Say something.")
    
    print "You said " + speech.input()
    
    def L1callback(phrase, listener):
        print phrase
    
    def L2callback(phrase, listener):
        if phrase == "wow":
            listener.stoplistening()
        speech.say(phrase)
    
    # callbacks are executed on a separate events thread.
    L1 = speech.listenfor(["hello", "good bye"], L1callback)
    L2 = speech.listenforanything(L2callback)
    
    assert speech.islistening()
    assert L2.islistening()
    
    L1.stoplistening()
    assert not L1.islistening()
    
    speech.stoplistening()
    """
    
    from win32com.client import constants as _constants
    import win32com.client
    import pythoncom
    import time
    import threading
    
    # Make sure that we've got our COM wrappers generated.
    from win32com.client import gencache
    gencache.EnsureModule('{C866CA3A-32F7-11D2-9602-00C04F8EE628}', 0, 5, 0)
    
    _voice = win32com.client.Dispatch("SAPI.SpVoice")
    _recognizer = win32com.client.Dispatch("SAPI.SpSharedRecognizer")
    _listeners = []
    _handlerqueue = []
    _eventthread=None
    
    class Listener(object):
    
        """Listens for speech and calls a callback on a separate thread."""
    
        _all = set()
    
        def __init__(self, context, grammar, callback):
            """
            This should never be called directly; use speech.listenfor()
            and speech.listenforanything() to create Listener objects.
            """
            self._grammar = grammar
            Listener._all.add(self)
    
            # Tell event thread to create an event handler to call our callback
            # upon hearing speech events
            _handlerqueue.append((context, self, callback))
            _ensure_event_thread()
    
        def islistening(self):
            """True if this Listener is listening for speech."""
            return self in Listener._all
    
        def stoplistening(self):
            """Stop listening for speech.  Returns True if we were listening."""
    
            try:
                Listener._all.remove(self)
            except KeyError:
                return False
    
            # This removes all refs to _grammar so the event handler can die
            self._grammar = None
    
            if not Listener._all:
                global _eventthread
                _eventthread = None # Stop the eventthread if it exists
    
            return True
    
    _ListenerBase = win32com.client.getevents("SAPI.SpSharedRecoContext")
    class _ListenerCallback(_ListenerBase):
    
        """Created to fire events upon speech recognition.  Instances of this
        class automatically die when their listener loses a reference to
        its grammar.  TODO: we may need to call self.close() to release the
        COM object, and we should probably make goaway() a method of self
        instead of letting people do it for us.
        """
    
        def __init__(self, oobj, listener, callback):
            _ListenerBase.__init__(self, oobj)
            self._listener = listener
            self._callback = callback
    
        def OnRecognition(self, _1, _2, _3, Result):
            # When our listener stops listening, it's supposed to kill this
            # object.  But COM can be funky, and we may have to call close()
            # before the object will die.
            if self._listener and not self._listener.islistening():
                self.close()
                self._listener = None
    
            if self._callback and self._listener:
                newResult = win32com.client.Dispatch(Result)
                phrase = newResult.PhraseInfo.GetText()
                self._callback(phrase, self._listener)
    
    def say(phrase):
        """Say the given phrase out loud."""
        _voice.Speak(phrase)
    
    
    def input(prompt=None, phraselist=None):
        """
        Print the prompt if it is not None, then listen for a string in phraselist
        (or anything, if phraselist is None.)  Returns the string response that is
        heard.  Note that this will block the thread until a response is heard or
        Ctrl-C is pressed.
        """
        def response(phrase, listener):
            if not hasattr(listener, '_phrase'):
                listener._phrase = phrase # so outside caller can find it
            listener.stoplistening()
    
        if prompt:
            print(prompt)
    
        if phraselist:
            listener = listenfor(phraselist, response)
        else:
            listener = listenforanything(response)
    
        while listener.islistening():
            time.sleep(.1)
    
        return listener._phrase # hacky way to pass back a response...
    
    def stoplistening():
        """
        Cause all Listeners to stop listening.  Returns True if at least one
        Listener was listening.
        """
        listeners = set(Listener._all) # clone so stoplistening can pop()
        returns = [l.stoplistening() for l in listeners]
        return any(returns) # was at least one listening?
    
    def islistening():
        """True if any Listeners are listening."""
        return not not Listener._all
    
    def listenforanything(callback):
        """
        When anything resembling English is heard, callback(spoken_text, listener)
        is executed.  Returns a Listener object.
    
        The first argument to callback will be the string of text heard.
        The second argument will be the same listener object returned by
        listenforanything().
    
        Execution takes place on a single thread shared by all listener callbacks.
        """
        return _startlistening(None, callback)
    
    def listenfor(phraselist, callback):
        """
        If any of the phrases in the given list are heard,
        callback(spoken_text, listener) is executed.  Returns a Listener object.
    
        The first argument to callback will be the string of text heard.
        The second argument will be the same listener object returned by
        listenfor().
    
        Execution takes place on a single thread shared by all listener callbacks.
        """
        return _startlistening(phraselist, callback)
    
    def _startlistening(phraselist, callback):
        """
        Starts listening in Command-and-Control mode if phraselist is
        not None, or dictation mode if phraselist is None.  When a phrase is
        heard, callback(phrase_text, listener) is executed.  Returns a
        Listener object.
    
        The first argument to callback will be the string of text heard.
        The second argument will be the same listener object returned by
        listenfor().
    
        Execution takes place on a single thread shared by all listener callbacks.
        """
        # Make a command-and-control grammar        
        context = _recognizer.CreateRecoContext()
        grammar = context.CreateGrammar()
    
        if phraselist:
            grammar.DictationSetState(0)
            # dunno why we pass the constants that we do here
            rule = grammar.Rules.Add("rule",
                    _constants.SRATopLevel + _constants.SRADynamic, 0)
            rule.Clear()
    
            for phrase in phraselist:
                rule.InitialState.AddWordTransition(None, phrase)
    
            # not sure if this is needed - was here before but dupe is below
            grammar.Rules.Commit()
    
            # Commit the changes to the grammar
            grammar.CmdSetRuleState("rule", 1) # active
            grammar.Rules.Commit()
        else:
            grammar.DictationSetState(1)
    
        return Listener(context, grammar, callback)
    
    def _ensure_event_thread():
        """
        Make sure the eventthread is running, which checks the handlerqueue
        for new eventhandlers to create, and runs the message pump.
        """
        global _eventthread
        if not _eventthread:
            def loop():
                while _eventthread:
                    pythoncom.PumpWaitingMessages()
                    if _handlerqueue:
                        (context,listener,callback) = _handlerqueue.pop()
                        # Just creating a _ListenerCallback object makes events
                        # fire till listener loses reference to its grammar object
                        _ListenerCallback(context, listener, callback)
                    time.sleep(.5)
            _eventthread = 1 # so loop doesn't terminate immediately
            _eventthread = threading.Thread(target=loop, args=()).start()

    安装之后使用发现错误:

    from speech import say

    ModuleNotFoundError: No module named 'speech'

    原因:安装了多个Python;需要安装到正确的位置;

     

    ModuleNotFoundError: No module named 'win32com'

    pip install pywin32

    原因:安装了多个Python;需要安装到正确的位置;

    speech会调用 win32com(即为pywin32)

    speech需要注册和激活

    步骤3:

    准备一个文本文件,保存学生信息,如图

    学生名单.txt

    20210223,张三

    20210224,李四

    20210225,王五

    20210226,赵六

    20210227,周七

    20210228,钱八

    我们自己写的源代码如下:

    import tkinter
    from tkinter.messagebox import showinfo
    from time import sleep
    from random import shuffle
    from itertools import cycle
    from threading import Thread
    from speech import say
    try :
        from speech import say
        has_speech = True
    except:
        has_speech = False
    root = tkinter.Tk() #窗口标题
    root.title('随机提问')#窗口初始大小和位置
    root.geometry( '260x180+400+300')#不允许改变窗口大小
    root.resizable(False,False)
    #关闭程序时执行的函数代码,停止滚动显示学生名单
    def closewindow( ):
        if rolling.get():
            showinfo('不能关闭','请先停止名单滚动')
            return
        root.destroy()
    root.protocol('WM_DELETE_WINDOw' , closewindow)
    #读取学生名单,如果不存在文件就使用模拟数据try :
    try:
        with open( '学生名单.txt' , encoding='utf8 ' ) as fp:
            students = fp.read( ).splitlines()
    except:
        showinfo('学生名单不存在',
            '当前目录中没有文件:学生名单.txt
    临时使用模拟数据')
        students =['张三','李四','王五','赵六','周七','钱八']
    #变量,用来控制是否滚动显示学生名单
    rolling = tkinter.BooleanVar(root, value=False)
    
    
    def switch():
        rolling.set(True)
        #随机打乱学生名单
        t = students[ : ]
        shuffle(t)
        t = cycle(t)
    
        while rolling.get():
            # 滚动显示
            lbFirst[ 'text'] = lbSecond[ 'text' ]
            lbSecond[ 'text'] = lbThird[ 'text']
            lbThird[ 'text'] = next(t)
            #数字可以修改,控制滚动速度
            sleep(0.1)
    
    def btnStartClick():
        # 每次单击“开始”按钮启动新线程
        Thread(target=switch).start()
        btnStart[ 'state' ] = 'disabled'
        btnStop[ 'state' ] = 'normal'
    btnStart = tkinter.Button( root,
        text='开始',
        command=btnStartClick)
    btnStart.place(x=30,y=10,width=80,height=20)
    saying = tkinter.BooleanVar(root, value=False)
    def say_name():
        while has_speech and saying.get():
            say(f"请{lbSecond[ 'text' ].replace( ' ,','')}回答问题")
    
    
    def btnStopClick():
        #单击“停”按钮结束滚动显示rolling.set(False)
        sleep(0.3)
        saying.set(True)
        Thread(target=say_name).start()
        showinfo('恭喜','本次中奖: '+lbSecond[ 'text' ])
        saying.set(False)
        btnStart[ 'state' ] = 'normal'
        btnStop[ 'state' ] = 'disabled'
    btnStop = tkinter.Button(root,text='', command=btnStopClick)
    btnStop[ 'state'] = 'disabled'
    btnStop.place(x=150,y=10, width=80,height=20)
    #用来滚动显示学生名单的3个Label组件
    #可以根据需要进行添加,但要修改上面的线程函数代码
    lbFirst = tkinter.Label(root, text='')
    lbFirst.place(x=80, y=60, width=100,height=20)
    #红色Label组件,表示中奖名单
    lbSecond = tkinter.Label(root,text='')
    lbSecond[ 'fg' ] = 'red'
    lbSecond.place(x=80,y=90,width=100,height=20)
    lbThird = tkinter.Label(root,text='')
    lbThird.place(x=80,y=120,width=100,height=20)
    #启动tkinter主程序
    root.mainloop()

    来自:

  • 相关阅读:
    [原创]设计模式建造者模式
    [原创]设计模式抽象工厂模式
    svn的branch/tag(转)
    [原创]设计模式访问者模式
    自定义安装python,退格,方向键无法正常使用(转)
    关于UDP 数据包长度的选择
    cent os 查看服务器信息
    【开源】QuickPager 分页控件的内部结构,和OO原则与设计模式
    【思路】表单控件和查询控件,整理一下思路。
    【测试】两种数据库,四种分页算法的效率比较
  • 原文地址:https://www.cnblogs.com/emanlee/p/15231651.html
Copyright © 2020-2023  润新知