PyQt5番外篇(2-5):冲顶大会小工具之解析篇程序整合

PyQt5番外篇(2-5):冲顶大会小工具之解析篇程序整合

上期我们介绍了UI的设计、问题采集、问题识别。这期我们讲讲问题搜索及程序整合。


回顾上期的

我想飞:PyQt5番外篇(2-2):冲顶大会语音答题辅助小工具之解析篇——界面搭建zhuanlan.zhihu.com图标我想飞:PyQt5番外篇(2-3):冲顶大会语音答题辅助小工具之解析篇——问题采集zhuanlan.zhihu.com图标我想飞:PyQt5番外篇(2-4):冲顶大会语音答题辅助小工具之解析篇——问题识别zhuanlan.zhihu.com图标

请点这里。


实现思路

既然界面设计好了、问题也采集、识别了,接下来就用百度搜下答案吧!


用百度搜索答案


实现的代码就一句


webbrowser.open('https://baidu.com/s?wd=' + urllib.parse.quote(str(voice['result'])[2:-3]), new=2, autoraise=True)


百度搜索的格式一般是这样:

https://baidu.com/s?wd=xxxxxx

"wd="后面的就是我们得到的问题了。例如下图:

webbrowser.open(url, new=0, autoraise=True)

在系统的默认浏览器中访问url地址,如果new = 0,url会在同一个浏览器窗口中打开;如果new = 1,新的浏览器窗口会被打开;new = 2新的浏览器tab会被打开。


str(voice['result'])[2:-3]


这里voice表示的是调用百度语音识别API后的返回值,其中result是类似[“北京天气”]的一个列表,所以我们通过列表切片方式以及str()函数将其强制转换成字符串:”北京天气”


urllib.parse.quote()

用这个函数可以很简单的解决url中出现中文的编码问题,例如在url中出现“世界上的最高山”,编码后就变成这个了:

程序整合


解决好问题搜索,接下来我们把之前的程序稍微整合一下。


因为问题采集、问题识别都是需要花费时间的,如何更有效的在PyQt5中执行呢。


我先来做一个对比试验,假设我们要处理一项工作用时大约20s的样子,我们比较不同处理方式的异同:

方式一

方式二


方式一与方式二最大的区别就是我们采用了多线程这个方法。


为什么在GUI程序中,处理较长时间的步骤使用多线程呢?


因为长时间的工作导致UI主线程就没有办法刷新自己,要等很费时间的事情做完之后才能刷新,系统就认为这个窗口这么长时间没有刷新肯定挂了,就变成了未响应。而且,这让用户体验也变得非常低,窗口在等待的时候,不仅仅不能点击,连移动窗口都不行,如果等的久了,还可能被用户杀掉,所以分离工作线程是非常必要的。


在PyQt5中我使用的是QThread类(这个知识点较为复杂,后期单独成章节,本次只介绍最基本的使用),将工作线程与主线程分离。


那么怎么实现的呢?


下面的代码仅演示如何应用QThread类,具体实现功能的代码在前面几章已经讲解的很多,只需把相应的代码移至进去就行了。


class Speech_Recognition_Thread(QThread):
    finished_signal = pyqtSignal(str)

    def __init__(self, parent = None):
        super().__init__(parent)
    
    def run(self):

        time.sleep(20)#这里演示这项工作需要执行20秒
        self.finished_signal.emit('over')
    
class dig_recorder(QDialog, Ui_dialog):

    def __init__(self, parent = None):
        super(dig_recorder, self).__init__(parent)
        self.setupUi(self)

    def _show_message(self, message):
        print('message:', message)
    
    @pyqtSlot()
    def on_pushButton_clicked(self):
        self.speech = Speech_Recognition_Thread()
        self.speech.finished_signal.connect(self._show_message)
        self.speech.start()


我们通过新建一个Speech_Recognition_Thread类(继承了QThread),将大量耗时工作移植到run()函数中,实现线程分离。


class Speech_Recognition_Thread(QThread):
    finished_signal = pyqtSignal(str)


我们新建一个Speech_Recognition_Thread类(继承了QThread),同时自定义一个返回值为str类型的信号。


def run(self):

    time.sleep(20)#这里演示这项工作需要执行20秒
    self.finished_signal.emit('over')


我们把耗时的工作移至到run()函数中,当工作结束后,我们主动的发出信号’over’


@pyqtSlot()
def on_pushButton_clicked(self):
    self.speech = Speech_Recognition_Thread()
    self.speech.finished_signal.connect(self._show_message)
    self.speech.start()


当我们点击按钮的时候,我们将自定义的多线程类初始化,同时将初始化对象中的finished_signal()关联到_show_message()这个槽函数中。也就是说当耗时任务完成时发射'over'信号,该值被_show_message()接收后打印出来。


self.speech.start()


表明我们启动多线程程序。这个和普通的Python多线程程序启动方式类似啊。


我主讲的Python多线程编程的课程请见这里:

Python多线程编程_腾讯课堂ke.qq.com图标


最后


冲顶大会语音答题辅助小工具之解析篇全部的内容就介绍到这里了。可能你看到这里还是有所模糊,这个没有关系,是正常的。


所以请各位关注:学点编程吧,发送:pyqt5冲顶,获得全部的代码再次对照相应的文章研究,相信会有所提升的。也欢迎各位留言,相互学习,共同成长。


记得程序中的APP_ID、API_KEY、SECRET_KEY需要换成自己的啊!

实操中有问题?来讨论吧!

学点编程吧-百度贴吧--计算机程序学习的园地!--学点编程吧,让我们的生活更简单,更高效!能用计算机解决的事情,尽量不要让人解决。如果你在学习当中有任何疑问、学习心得、职业发展等内容欢迎在贴吧中分享,让我tieba.baidu.com图标

编辑于 2018-09-18

文章被以下专栏收录