本次使用PyQt5开发一款在线小说播放器,支持在线收听多个数据源的小说,支持小说检索,走起~

一.准备工作

1.PyQt5

pyqt5是一套Python绑定Digia QT5应用的框架。它可用于Python 2和3。本教程使用Python 3。Qt库是最强大的GUI库之一。pyqt5的官方网站http://www.riverbankcomputing.co.uk/news
pyqt5做为Python的一个模块,它有620多个类和6000个函数和方法。这是一个跨平台的工具包,它可以运行在所有主要的操作系统,包括UNIX,Windows,Mac OS。pyqt5是双重许可。开发者可以在GPL和商业许可之间进行选择。

2.qtawesome

QtAwesome 是一个简单的库,可用于将Font Awesome图标添加到Qt 应用程序。
注意:虽然名称是 QtAwesome 并且目前它非常基于 Font Awesome,但您可以使用您想要的所有其他图标/字形字体。
通过添加命名图标画家,该类还可用于管理您自己的动态代码绘制图标。(翻译)

简单说,就是利用qtawesome里面的小图标组件,帮助我们可视化地设计GUI界面。

给出三个网站,可以学习一下
QtAwesome-GitHub
Font Awesome-官网
Font Awesome-中文网

3.QMediaPlayer

QMediaPlayer 类是高级媒体播放类。它可用于播放歌曲、电影和网络广播等内容。要播放的内容被指定为 QMediaContent 对象,可以将其视为附加了附加信息的主 URL 或规范 URL。当提供了一个 QMediaContent 播放可能就可以开始了。
QMediaPlayer-Qt官网
QMediaPlayer-PyQt官网

本文利用QMediaPlayer播放在线小说音频,运用其封装好的函数对播放器进行控制。

4.LAVFilters

LAV Filters是一组基于 ffmpeg 项目中的 libavformat/libavcodec 库的 directshow 分离器和音视频解码器,几乎允许在 directshow 播放器中播放任何格式的媒体文件!
LAVFilters-GitHub

考虑到小说文件格式不同,在此需要安装解码器。可以去GitHub下载,也可以去网络上搜索后下载。

二.预览

1.启动

请添加图片描述

启动后会自动加载推荐的小说,并且显示数量,此时播放器以及右边详情页、剧集页为默认状态。

2.查看小说详情&播放小说

在这里插入图片描述

点击左侧小说列表,查看小说详情、剧集。选择双击小说剧集,播放器开始播放小说,播放模式默认为列表顺序播放,可以手动拖动播放进度条,改变当前播放进度。

3.搜索后播放

请添加图片描述
搜索小说后,播放小说。

4.动态演示

请添加图片描述
在这里放一张gif演示一下软件使用过程。(gif太小的原因是csdn限制上传图片大小,请理解!)

三.设计流程

1.UI设计

1.小说搜索UI
在这里插入图片描述
本程序UI设计并不复杂,左侧小说推荐、小说搜索Table Widget和右侧小说详情、小说剧集水平布局,最后再和下面播放器垂直布局。

2.整体流程设计

在这里插入图片描述

四.源代码

1.Novel_Listen.py(主程序调用)

import sys
import threading
import qtawesome
from novel_get import *
from PyQt5.QtCore import *
from base64 import b64decode
from PyQt5.QtGui import QIcon
from PyQt5.uic import loadUi
from 小说搜索UI import MainWindow
from PyQt5.QtWidgets import QTableWidgetItem
from PyQt5.QtMultimedia import QMediaPlayer, QMediaContent, QMediaPlaylist
from PyQt5.Qt import QMainWindow,QMessageBox,QApplication,QPixmap,QUrl


class Listen_Sound_Window(QMainWindow):
    load_recommend_finish_single=pyqtSignal()
    def __init__(self):
        super().__init__()
        self.ui=MainWindow()
        self.ui.setupUi(self)
        self.thread_it(self.load_recommend_novels)
        self.player_init()
        self.icon_init()
        self.ui.pushButton.clicked.connect(self.search_novels)
        self.ui.pushButton_8.clicked.connect(self.do_sq_and_zk)
        self.ui.pushButton_5.clicked.connect(lambda :self.get_appoint_audio_play_link("up"))
        self.ui.pushButton_6.clicked.connect(lambda :self.get_appoint_audio_play_link("down"))
        self.ui.label_4.setMaximumSize(QSize(300,250))#图片缩放,还有问题
        for i in range(1,8):
            exec("self.ui.tableWidget_{}.currentCellChanged.connect(self.show_novel_detail)".format(i))
        self.load_recommend_finish_single.connect(self.display_recommend)

    def icon_init(self):
        self.ui.pushButton_8.setIcon(QIcon(qtawesome.icon('fa.angle-double-down', color='black')))
        self.ui.pushButton_2.setIcon(QIcon(qtawesome.icon('fa.play', color='black')))
        self.ui.pushButton_3.setIcon(QIcon(qtawesome.icon('fa.pause', color='black')))
        self.ui.pushButton_4.setIcon(QIcon(qtawesome.icon('fa.stop', color='black')))
        self.ui.pushButton_5.setIcon(QIcon(qtawesome.icon('fa.backward', color='black')))
        self.ui.pushButton_6.setIcon(QIcon(qtawesome.icon('fa.forward', color='black')))
        self.ui.pushButton_7.setIcon(QIcon(qtawesome.icon('fa.volume-down', color='black')))
        self.default_img=b'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'
        self.default_img_base64=b64decode(self.default_img)

    def do_sq_and_zk(self):
        """
        播放区,收起  展开
        :return:
        """
        state=self.ui.frame_7.isVisible()
        self.ui.frame_7.setVisible(not state)
        if state:
            self.ui.pushButton_8.setIcon(QIcon(qtawesome.icon('fa.angle-double-up', color='black')))
            self.ui.pushButton_8.setText("展开")
        else:
            self.ui.pushButton_8.setText("收起")
            self.ui.pushButton_8.setIcon(QIcon(qtawesome.icon('fa.angle-double-down', color='black')))

    def load_recommend_novels(self):
        """
        加载推荐小说
        :return:
        """
        self.ting_China_recommend_list=Ting_China_spider().get_recommend()
        self.youshengxiaoshuo_recommend_list=YouSheng_xiaoshuo_spider().get_recommend()
        self.tingshubao_recommend_list=Tingshu_bao_spider().get_recommend()
        self.i275_recommend_list=I275_spider().get_recommend()
        self.tingshucn_recommend_list=Tingshu_cn_spider().get_recommend()
        self.mangguoting_recommend_list=Mangguo_ting_spider().get_recommend()
        self.load_recommend_finish_single.emit()

    def display_recommend(self):
        if self.ting_China_recommend_list:
            book_num=len(self.ting_China_recommend_list)
            self.ui.groupBox.setTitle(f"听China({book_num})")
            self.ui.tableWidget_1.setRowCount(book_num)
            for index, novel_item in enumerate(self.ting_China_recommend_list):
                novel_name = novel_item['novel_name']
                table_widget_item = QTableWidgetItem(novel_name)
                self.ui.tableWidget_1.setItem(index, 0, table_widget_item)

        if self.youshengxiaoshuo_recommend_list:
            book_num=len(self.youshengxiaoshuo_recommend_list)
            self.ui.groupBox_2.setTitle(f"有声小说({book_num})")
            self.ui.tableWidget_2.setRowCount(book_num)
            for index,novel_item in enumerate(self.youshengxiaoshuo_recommend_list):
                novel_name=novel_item['novel_name']
                table_widget_item=QTableWidgetItem(novel_name)
                self.ui.tableWidget_2.setItem(index,0,table_widget_item)

        if self.tingshubao_recommend_list:
            book_num=len(self.tingshubao_recommend_list)
            self.ui.groupBox_3.setTitle(f"听书宝({book_num})")
            self.ui.tableWidget_3.setRowCount(book_num)
            for index,novel_item in enumerate(self.tingshubao_recommend_list):
                novel_name=novel_item['novel_name']
                table_widget_item=QTableWidgetItem(novel_name)
                self.ui.tableWidget_3.setItem(index,0,table_widget_item)

        if self.i275_recommend_list:
            book_num=len(self.i275_recommend_list)
            self.ui.groupBox_4.setTitle(f"I2725({book_num})")
            self.ui.tableWidget_4.setRowCount(book_num)
            for index,novel_item in enumerate(self.i275_recommend_list):
                novel_name=novel_item['novel_name']
                table_widget_item=QTableWidgetItem(novel_name)
                self.ui.tableWidget_4.setItem(index,0,table_widget_item)

        if self.tingshucn_recommend_list:
            book_num=len(self.tingshucn_recommend_list)
            self.ui.groupBox_5.setTitle(f"听书cn({book_num})")
            self.ui.tableWidget_5.setRowCount(book_num)
            for index,novel_item in enumerate(self.tingshucn_recommend_list):
                novel_name=novel_item['novel_name']
                table_widget_item=QTableWidgetItem(novel_name)
                self.ui.tableWidget_5.setItem(index,0,table_widget_item)

        if self.mangguoting_recommend_list:
            book_num=len(self.mangguoting_recommend_list)
            self.ui.groupBox_6.setTitle(f"芒果听({book_num})")
            self.ui.tableWidget_6.setRowCount(book_num)
            for index,novel_item in enumerate(self.mangguoting_recommend_list):
                novel_name=novel_item['novel_name']
                table_widget_item=QTableWidgetItem(novel_name)
                self.ui.tableWidget_6.setItem(index,0,table_widget_item)

    def search_novels(self):
        key_word=self.ui.lineEdit.text()
        if key_word!="":
            combobox_current_index=self.ui.comboBox.currentIndex()
            if combobox_current_index!=0:
                self.current_page=0
                self.current_keyword=key_word
                self.do_search_novels(index=combobox_current_index,key_word=key_word)
            else:
                QMessageBox.warning(self,"警告","请选择音源!")
        else:
            QMessageBox.warning(self, "警告", "关键字不能为空!")

    def get_spider(self,index):
        if index==1:
            spider=Ting_China_spider()
        elif index==2:
            spider=YouSheng_xiaoshuo_spider()
        elif index==3:
            spider=Tingshu_bao_spider()
        elif index==4:
            spider=I275_spider()
        elif index==5:
            spider=Tingshu_cn_spider()
        elif index==6:
            spider=Mangguo_ting_spider()
        return spider

    def do_search_novels(self,index,key_word):
        spider=self.get_spider(index)
        self.search_result_list=[]
        search_result = spider.do_search(key_word=key_word)
        if search_result:
            page = 2
            while True:
                self.search_result_list.extend(search_result['search_result_list'])
                if search_result['next_page_flag']==True:
                    search_result = spider.do_search(key_word=key_word,page=page)
                    if search_result:
                        self.search_result_list.extend(search_result['search_result_list'])
                        page+=1
                    else:
                        break
                else:
                    break
                if  page==6: #仅展示前5页
                    break
            novel_num=len(self.search_result_list)
            self.ui.tableWidget_7.setRowCount(novel_num)
            if novel_num==1:
                #如果只有一个搜索结果,则直接选中此单元格
                self.ui.tableWidget_7.setCurrentCell(0,0)
            self.ui.label_3.setText('<html><head/><body><p align="center">{current_status}</p></body></html>'.replace("{current_status}",f'搜索到关于<span style=" color:#55aaff;">{self.current_keyword}</span>的小说<span style=" color:#55aaff;">{novel_num}</span>本'))
            self.show_search_result()
        else:
            QMessageBox.information(self,"提示",f"没有搜索到关于{self.current_keyword}的小说,请尝试更换关键字或更换音源")

    def show_search_result(self):
        """
        :return:
        """
        for index,item in enumerate(self.search_result_list):
           new_table_widget_item=QTableWidgetItem(item['novel_name'])
           self.ui.tableWidget_7.setItem(index,0,new_table_widget_item)

    def show_novel_detail(self,row,column):
        """
        所有tablewidget
        :param row:
        :param column:
        :return:
        """
        if self.sender()==self.ui.tableWidget_1:
            spider=Ting_China_spider()
            current_sound_link=self.ting_China_recommend_list[row]['novel_link']
        elif self.sender()==self.ui.tableWidget_2:
            spider=YouSheng_xiaoshuo_spider()
            current_sound_link=self.youshengxiaoshuo_recommend_list[row]['novel_link']
        elif self.sender()==self.ui.tableWidget_3:
            spider=Tingshu_bao_spider()
            current_sound_link=self.tingshubao_recommend_list[row]['novel_link']
        elif self.sender()==self.ui.tableWidget_4:
            spider=I275_spider()
            current_sound_link=self.i275_recommend_list[row]['novel_link']
        elif self.sender()==self.ui.tableWidget_5:
            spider=Tingshu_cn_spider()
            current_sound_link=self.tingshucn_recommend_list[row]['novel_link']
        elif self.sender()==self.ui.tableWidget_6:
            spider=Mangguo_ting_spider()
            current_sound_link=self.mangguoting_recommend_list[row]['novel_link']
        elif self.sender()==self.ui.tableWidget_7:
            current_sound_link=self.search_result_list[row]['novel_link']
            index=self.ui.comboBox.currentIndex()
            spider=self.get_spider(index)
        novel_detail=spider.get_novel_detail(current_sound_link)
        self.do_show_novel_detail(novel_detail)

    def do_show_novel_detail(self,novel_detail):
        novel_cover_link=novel_detail['novel_cover']
        pix_map = QPixmap()
        if novel_cover_link=="未知":
            img_bytes=b64decode(self.default_img)
        else:
            res=Sound_Get().do_get_img_bytes(novel_cover_link)
            if res:
                header_type=res[1]
                if "html" in header_type:
                    img_bytes = self.default_img_base64
                else:
                    img_bytes=res[0]
            else:
                img_bytes = self.default_img_base64
        pix_map.loadFromData(img_bytes)
        self.ui.label_4.setPixmap(pix_map)
        self.ui.label_4.resize(200,150)
        play_list=novel_detail['play_list']
        self.__play_list=play_list
        self.current_play_novel_name=novel_detail['novel_name']
        self.ui.label_6.setText(novel_detail['novel_name'])
        self.ui.label_8.setText(novel_detail['novel_status'])
        self.ui.label_10.setText(novel_detail['novel_author'])
        self.ui.label_12.setText(novel_detail['novel_anchor'])
        self.ui.label_22.setText(novel_detail['novel_type'])
        self.ui.label_24.setText(novel_detail['novel_update_time'])
        clean_res=self.string_clean(novel_detail['novel_introduce'].strip())
        if len(clean_res)>120:
            self.ui.label_25.setText(clean_res[:120]+"......")
        else:
            self.ui.label_25.setText(clean_res)
        self.ui.label_27.setText(f"{len(play_list)}集")
        self.ui.play_list.setRowCount(len(play_list))
        for index,item in enumerate(play_list):
            novel_name=item['play_name']
            new_item=QTableWidgetItem(novel_name)
            new_item.setToolTip(novel_name)
            self.ui.play_list.setItem(index,0,new_item)
        self.ui.play_list.verticalScrollBar().setSliderPosition(1)#将滚动条位置恢复

    def string_clean(self,raw_strings):
        reg=r"[\/\\\:\*\?\"\<\>\|\n|\t|\s]"
        clean_res=re.sub(reg,"",raw_strings)
        return clean_res

    def player_init(self):
        self.dur='' #当前播放时常
        self.cur_dur='' #总时长
        self.ui.volume_slider.setValue(100)
        self.player = QMediaPlayer(self)
        self.playlist = QMediaPlaylist(self)
        self.ui.volume_slider.setRange(0, 100)
        self.player.setPlaylist(self.playlist)
        self.ui.progress_slider.setEnabled(False)
        self.playlist.loadFailed.connect(lambda :QMessageBox.critical(self,"错误","此音频不可播放!"))
        self.ui.volume_slider.valueChanged[int].connect(lambda v :self.player.setVolume(v))
        self.player.stateChanged.connect(self.play_state_Change)
        self.player.durationChanged.connect(self.get_duration_func)
        self.player.positionChanged.connect(self.get_position_func)
        self.player.mediaStatusChanged.connect(self.player_status_chnge)
        self.player.error.connect(self.do_progress_error)
        self.ui.play_list.itemDoubleClicked.connect(self.do_play_novel)
        self.ui.progress_slider.sliderMoved.connect(self.update_position_func)
        self.ui.volume_slider.valueChanged.connect(self.volume_slider_func)
        self.ui.pushButton_2.clicked.connect(self.do_start_play)
        self.ui.pushButton_5.clicked.connect(lambda :self.playlist.previous())
        self.ui.pushButton_6.clicked.connect(lambda :self.playlist.next())
        self.ui.pushButton_3.clicked.connect(lambda :self.player.pause())
        self.ui.pushButton_4.clicked.connect(lambda :self.player.stop())
        self.ui.pushButton_7.clicked.connect(self.on_mute_clicked)

    def do_progress_error(self,error):
        if error==1:
            QMessageBox.critical(self,"错误",'请检查资源!')
        elif error==3:
            QMessageBox.critical(self,"错误",'网络错误!')
        elif error==5:
            QMessageBox.critical(self,"错误",'缺少相关服务!')
        elif error==2:
            QMessageBox.critical(self,"错误",'格式错误!')
        elif error==4:
            QMessageBox.critical(self,"错误",'访问权限错误!')

    def get_appoint_audio_play_link(self,direction):
        """
        获取指定音频播放地址,此函数用于“上一集”,“下一集”,“切换”
        :param index:
        :return:
        """
        if direction=='up':
            if self.current_select_row-1<=0:
                QMessageBox.warning(self,'警告','前面没有啦!')
                return
            else:
                self.current_select_row-=1
        elif direction=="down":
            if self.current_select_row+1>=len(self.__play_list):
                QMessageBox.warning(self,'警告','后面没有啦!')
                return
            else:
                self.current_select_row+=1
        real_play_link=self.get_real_play_link(self.__play_list[self.current_select_row]['play_link'])
        print(real_play_link)
        self.do_play_a_aduio(real_play_link)

    def do_play_a_aduio(self,play_link):
        """
        根据传入播放链接,播放指定音频
        :param play_link:
        :return:
        """
        if play_link:
            novel = QMediaContent(QUrl(play_link))
            self.playlist.clear()
            self.playlist.addMedia(novel)
            self.playlist.setPlaybackMode(QMediaPlaylist.CurrentItemOnce)  # 当前音频播放一次
            self.ui.label_play_state.setText(
                '<html><head/><body><p>正在播放\t<span style=" color:#55aaff;">{current_state_string}</span></p></body></html>'.replace(
                    "{current_state_string}",
                    f"{self.current_play_novel_name}\t{self.__play_list[self.current_select_row]['play_name']}"))
            self.playlist.setCurrentIndex(0)
            self.player.play()
        else:
            QMessageBox.information(self, "提示", "音频播放失败!")

    def do_play_novel(self,begin_index):
        """
        双击剧集tablewidget触发事件
        :param begin_index:
        :return:
        """
        self.current_select_row=begin_index.row()
        real_play_link=self.get_real_play_link(self.__play_list[self.current_select_row]['play_link'])
        if isinstance(real_play_link,list):
            #单独为spider2写一种获取播放链接
            real_play_link=real_play_link[self.current_select_row]
            split_list=real_play_link.split('/',3)
            suffix=split_list[-1]
            reg=r'[\u4e00-\u9fa5]+'
            #如果url包含中文,则转为urlencode
            if re.match(reg,suffix):
                real_play_link=split_list[0]+"://"+split_list[2]+"/"+quote(suffix)
            else:
                real_play_link=real_play_link
        else:
            real_play_link=real_play_link
        self.do_play_a_aduio(real_play_link)

    @pyqtSlot()
    def do_start_play(self):
        if self.playlist.currentIndex()<0:
            self.playlist.setCurrentIndex(0)
        self.player.play()

    def get_real_play_link(self,link):
        if "tingchina.com" in link:
            spider=Ting_China_spider()
        elif "m.ysxs8.com" in link:
            spider=YouSheng_xiaoshuo_spider()
        elif "m.tingshubao.com" in link:
            spider=Tingshu_bao_spider()
        elif "www.i275.com" in link:
            spider=I275_spider()
        elif "www.tingshucn.com" in link:
            spider=Tingshu_cn_spider()
        elif "www.mgting.com" in link:
            spider=Mangguo_ting_spider()
        real_play_link=spider.get_audio_play_link(link)
        if real_play_link:
            return real_play_link
        else:
            return False

    @pyqtSlot()
    def on_mute_clicked(self):
        """
        静音
        :return:
        """
        mute=self.player.isMuted()
        self.player.setMuted(not mute)
        if mute:
            #显示音量图标
            self.ui.pushButton_7.setIcon(QIcon(qtawesome.icon('fa.volume-down', color='black')))
            self.ui.pushButton_7.setText("静音")
            self.ui.volume_slider.setValue(100)
            self.player.setVolume(100)
        else:
            #显示静音图标
            self.ui.pushButton_7.setIcon(QIcon(qtawesome.icon('fa.volume-off', color='black')))
            self.ui.pushButton_7.setText("取消静音")
            self.ui.volume_slider.setValue(0)

    def play_state_Change(self,state):
        self.ui.pushButton_2.setEnabled(state!=1)
        self.ui.pushButton_4.setEnabled(state==1)
        if state==2:
            self.ui.label_play_state.setText(
                '<html><head/><body><p>暂停播放\t<span style=" color:#55aaff;">{current_state_string}</span></p></body></html>'.replace(
                    "{current_state_string}",
                    f"{self.current_play_novel_name}\t{self.__play_list[self.current_select_row]['play_name']}"))
        elif state==0:
            self.ui.label_play_state.setText(
                '<html><head/><body><p>停止播放\t<span style=" color:#55aaff;">{current_state_string}</span></p></body></html>'.replace(
                    "{current_state_string}",
                    f"{self.current_play_novel_name}\t{self.__play_list[self.current_select_row]['play_name']}"))
        elif state==1:
            self.ui.label_play_state.setText(
                '<html><head/><body><p>正在播放\t<span style=" color:#55aaff;">{current_state_string}</span></p></body></html>'.replace(
                    "{current_state_string}",
                    f"{self.current_play_novel_name}\t{self.__play_list[self.current_select_row]['play_name']}"))

    def player_status_chnge(self,state):
        if state==7:
            #当前音频播放结束,state==7(EndOfMedia)
            self.get_appoint_audio_play_link("down")

    def get_duration_func(self, d):
        secs=d/1000
        mins=secs/60
        secs=secs%60
        self.dur="%d:%d"%(mins,secs)
        current_progress='{}/{}'.format(self.cur_dur,self.dur)
        self.ui.label_play_time.setText(
            '<html><head/><body><p><span style=" color:#55aaff;">{current_progress}</span></p></body></html>'.replace(
                "{current_progress}", current_progress))
        self.ui.progress_slider.setRange(0,d)
        self.ui.progress_slider.setEnabled(True)

    def get_position_func(self, p):
        if (self.ui.progress_slider.isSliderDown()):
            return
        self.ui.progress_slider.setValue(p)
        secs=p/1000
        mins=secs/60
        secs=secs%60
        self.cur_dur="%d:%d"%(mins,secs)
        current_progress='{}/{}'.format(self.cur_dur,self.dur)
        self.ui.label_play_time.setText(
            '<html><head/><body><p><span style=" color:#55aaff;">{current_progress}</span></p></body></html>'.replace(
                "{current_progress}", current_progress))

    def update_position_func(self, v):
        self.player.setPosition(v)
        secs = v / 1000
        mins = secs / 60
        secs = secs % 60
        self.cur_dur = "%d:%d" % (mins, secs)
        current_progress='{}/{}'.format(self.cur_dur,self.dur)
        self.ui.label_play_time.setText(
            '<html><head/><body><p><span style=" color:#55aaff;">{current_progress}</span></p></body></html>'.replace(
                "{current_progress}", current_progress))

    @pyqtSlot(int)
    def volume_slider_func(self, value):
        self.player.setVolume(value)
        if value == 0:
            #静音
            self.ui.pushButton_7.setIcon(QIcon('images/sound_off.png'))
        else:
            #正常
            self.ui.pushButton_7.setIcon(QIcon('images/sound_on.png'))

    def closeEvent(self,event):
        reply = QMessageBox.question(self, '关闭', "确定要退出吗?",
                                     QMessageBox.Yes | QMessageBox.No, QMessageBox.Yes)
        if reply == QMessageBox.Yes:
            self.player.stop()
            event.accept()
        else:
            event.ignore()

    def keyPressEvent(self, event):
        if event.key()==Qt.Key.Key_Escape:
            self.close()

    def thread_it(self,func,*args):
        t=threading.Thread(target=func,args=args)
        t.setDaemon(True)
        t.start()

if __name__ == '__main__':
    app=QApplication(sys.argv)
    app.setStyle("Fusion")
    ui=Listen_Sound_Window()
    ui.show()
    sys.exit(app.exec_())

2.小说搜索UI.py(UI界面)

# -*- coding: utf-8 -*-

# Form implementation generated from reading ui file '小说搜索UI.ui'
#
# Created by: PyQt5 UI code generator 5.15.4
#
# WARNING: Any manual changes made to this file will be lost when pyuic5 is
# run again.  Do not edit this file unless you know what you are doing.


from PyQt5 import QtCore, QtGui, QtWidgets


class MainWindow(object):
    def setupUi(self, MainWindow):
        MainWindow.setObjectName("MainWindow")
        MainWindow.resize(1496, 810)
        sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Fixed, QtWidgets.QSizePolicy.Fixed)
        sizePolicy.setHorizontalStretch(0)
        sizePolicy.setVerticalStretch(0)
        sizePolicy.setHeightForWidth(MainWindow.sizePolicy().hasHeightForWidth())
        MainWindow.setSizePolicy(sizePolicy)
        MainWindow.setStyleSheet("QPushButton:hover{\n"
"    border-color:#55aaff;\n"
"}\n"
"\n"
"QPushButton{    \n"
"    border: 1px solid ;\n"
"    border-radius: 4px;\n"
"    min-height: 25px;\n"
"}\n"
"QLineEdit{    \n"
"    border: 1px solid ;\n"
"    border-radius: 4px;\n"
"}\n"
"QLineEdit:hover{\n"
"    border-color:#55aaff;\n"
"}\n"
"\n"
"QComboBox {    \n"
"    border: 1px solid ;\n"
"    border-radius:4px;\n"
"    min-height: 20px;\n"
"}\n"
"QComboBox:hover{\n"
"    border-color:#55aaff;\n"
"}\n"
"/* 下拉列表里的颜色 */\n"
"QComboBox QAbstractItemView {\n"
"    border: 2px solid darkgray;\n"
"    selection-background-color:#1E90FF;\n"
"}\n"
"")
        self.centralwidget = QtWidgets.QWidget(MainWindow)
        self.centralwidget.setObjectName("centralwidget")
        self.verticalLayout_13 = QtWidgets.QVBoxLayout(self.centralwidget)
        self.verticalLayout_13.setObjectName("verticalLayout_13")
        self.horizontalLayout_16 = QtWidgets.QHBoxLayout()
        self.horizontalLayout_16.setObjectName("horizontalLayout_16")
        self.tabWidget = QtWidgets.QTabWidget(self.centralwidget)
        sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Fixed, QtWidgets.QSizePolicy.Expanding)
        sizePolicy.setHorizontalStretch(0)
        sizePolicy.setVerticalStretch(0)
        sizePolicy.setHeightForWidth(self.tabWidget.sizePolicy().hasHeightForWidth())
        self.tabWidget.setSizePolicy(sizePolicy)
        self.tabWidget.setObjectName("tabWidget")
        self.tab = QtWidgets.QWidget()
        self.tab.setObjectName("tab")
        self.verticalLayout_2 = QtWidgets.QVBoxLayout(self.tab)
        self.verticalLayout_2.setObjectName("verticalLayout_2")
        self.horizontalLayout_5 = QtWidgets.QHBoxLayout()
        self.horizontalLayout_5.setObjectName("horizontalLayout_5")
        self.groupBox = QtWidgets.QGroupBox(self.tab)
        self.groupBox.setObjectName("groupBox")
        self.verticalLayout_3 = QtWidgets.QVBoxLayout(self.groupBox)
        self.verticalLayout_3.setObjectName("verticalLayout_3")
        self.tableWidget_1 = QtWidgets.QTableWidget(self.groupBox)
        self.tableWidget_1.setEditTriggers(QtWidgets.QAbstractItemView.NoEditTriggers)
        self.tableWidget_1.setAlternatingRowColors(True)
        self.tableWidget_1.setSelectionMode(QtWidgets.QAbstractItemView.SingleSelection)
        self.tableWidget_1.setSelectionBehavior(QtWidgets.QAbstractItemView.SelectRows)
        self.tableWidget_1.setObjectName("tableWidget_1")
        self.tableWidget_1.setColumnCount(1)
        self.tableWidget_1.setRowCount(0)
        item = QtWidgets.QTableWidgetItem()
        self.tableWidget_1.setHorizontalHeaderItem(0, item)
        self.tableWidget_1.horizontalHeader().setStretchLastSection(True)
        self.verticalLayout_3.addWidget(self.tableWidget_1)
        self.horizontalLayout_5.addWidget(self.groupBox)
        self.groupBox_2 = QtWidgets.QGroupBox(self.tab)
        self.groupBox_2.setObjectName("groupBox_2")
        self.verticalLayout_4 = QtWidgets.QVBoxLayout(self.groupBox_2)
        self.verticalLayout_4.setObjectName("verticalLayout_4")
        self.tableWidget_2 = QtWidgets.QTableWidget(self.groupBox_2)
        self.tableWidget_2.setEditTriggers(QtWidgets.QAbstractItemView.NoEditTriggers)
        self.tableWidget_2.setAlternatingRowColors(True)
        self.tableWidget_2.setSelectionMode(QtWidgets.QAbstractItemView.SingleSelection)
        self.tableWidget_2.setSelectionBehavior(QtWidgets.QAbstractItemView.SelectRows)
        self.tableWidget_2.setObjectName("tableWidget_2")
        self.tableWidget_2.setColumnCount(1)
        self.tableWidget_2.setRowCount(0)
        item = QtWidgets.QTableWidgetItem()
        self.tableWidget_2.setHorizontalHeaderItem(0, item)
        self.tableWidget_2.horizontalHeader().setStretchLastSection(True)
        self.verticalLayout_4.addWidget(self.tableWidget_2)
        self.horizontalLayout_5.addWidget(self.groupBox_2)
        self.groupBox_3 = QtWidgets.QGroupBox(self.tab)
        self.groupBox_3.setObjectName("groupBox_3")
        self.verticalLayout_5 = QtWidgets.QVBoxLayout(self.groupBox_3)
        self.verticalLayout_5.setObjectName("verticalLayout_5")
        self.tableWidget_3 = QtWidgets.QTableWidget(self.groupBox_3)
        self.tableWidget_3.setEditTriggers(QtWidgets.QAbstractItemView.NoEditTriggers)
        self.tableWidget_3.setAlternatingRowColors(True)
        self.tableWidget_3.setSelectionMode(QtWidgets.QAbstractItemView.SingleSelection)
        self.tableWidget_3.setSelectionBehavior(QtWidgets.QAbstractItemView.SelectRows)
        self.tableWidget_3.setObjectName("tableWidget_3")
        self.tableWidget_3.setColumnCount(1)
        self.tableWidget_3.setRowCount(0)
        item = QtWidgets.QTableWidgetItem()
        self.tableWidget_3.setHorizontalHeaderItem(0, item)
        self.tableWidget_3.horizontalHeader().setStretchLastSection(True)
        self.verticalLayout_5.addWidget(self.tableWidget_3)
        self.horizontalLayout_5.addWidget(self.groupBox_3)
        self.verticalLayout_2.addLayout(self.horizontalLayout_5)
        self.horizontalLayout_6 = QtWidgets.QHBoxLayout()
        self.horizontalLayout_6.setObjectName("horizontalLayout_6")
        self.groupBox_4 = QtWidgets.QGroupBox(self.tab)
        self.groupBox_4.setObjectName("groupBox_4")
        self.verticalLayout_6 = QtWidgets.QVBoxLayout(self.groupBox_4)
        self.verticalLayout_6.setObjectName("verticalLayout_6")
        self.tableWidget_4 = QtWidgets.QTableWidget(self.groupBox_4)
        self.tableWidget_4.setEditTriggers(QtWidgets.QAbstractItemView.NoEditTriggers)
        self.tableWidget_4.setAlternatingRowColors(True)
        self.tableWidget_4.setSelectionMode(QtWidgets.QAbstractItemView.SingleSelection)
        self.tableWidget_4.setSelectionBehavior(QtWidgets.QAbstractItemView.SelectRows)
        self.tableWidget_4.setObjectName("tableWidget_4")
        self.tableWidget_4.setColumnCount(1)
        self.tableWidget_4.setRowCount(0)
        item = QtWidgets.QTableWidgetItem()
        self.tableWidget_4.setHorizontalHeaderItem(0, item)
        self.tableWidget_4.horizontalHeader().setStretchLastSection(True)
        self.verticalLayout_6.addWidget(self.tableWidget_4)
        self.horizontalLayout_6.addWidget(self.groupBox_4)
        self.groupBox_5 = QtWidgets.QGroupBox(self.tab)
        self.groupBox_5.setObjectName("groupBox_5")
        self.verticalLayout_7 = QtWidgets.QVBoxLayout(self.groupBox_5)
        self.verticalLayout_7.setObjectName("verticalLayout_7")
        self.tableWidget_5 = QtWidgets.QTableWidget(self.groupBox_5)
        self.tableWidget_5.setEditTriggers(QtWidgets.QAbstractItemView.NoEditTriggers)
        self.tableWidget_5.setAlternatingRowColors(True)
        self.tableWidget_5.setSelectionMode(QtWidgets.QAbstractItemView.SingleSelection)
        self.tableWidget_5.setSelectionBehavior(QtWidgets.QAbstractItemView.SelectRows)
        self.tableWidget_5.setObjectName("tableWidget_5")
        self.tableWidget_5.setColumnCount(1)
        self.tableWidget_5.setRowCount(0)
        item = QtWidgets.QTableWidgetItem()
        self.tableWidget_5.setHorizontalHeaderItem(0, item)
        self.tableWidget_5.horizontalHeader().setStretchLastSection(True)
        self.verticalLayout_7.addWidget(self.tableWidget_5)
        self.horizontalLayout_6.addWidget(self.groupBox_5)
        self.groupBox_6 = QtWidgets.QGroupBox(self.tab)
        self.groupBox_6.setObjectName("groupBox_6")
        self.verticalLayout_8 = QtWidgets.QVBoxLayout(self.groupBox_6)
        self.verticalLayout_8.setObjectName("verticalLayout_8")
        self.tableWidget_6 = QtWidgets.QTableWidget(self.groupBox_6)
        self.tableWidget_6.setEditTriggers(QtWidgets.QAbstractItemView.NoEditTriggers)
        self.tableWidget_6.setAlternatingRowColors(True)
        self.tableWidget_6.setSelectionMode(QtWidgets.QAbstractItemView.SingleSelection)
        self.tableWidget_6.setSelectionBehavior(QtWidgets.QAbstractItemView.SelectRows)
        self.tableWidget_6.setObjectName("tableWidget_6")
        self.tableWidget_6.setColumnCount(1)
        self.tableWidget_6.setRowCount(0)
        item = QtWidgets.QTableWidgetItem()
        self.tableWidget_6.setHorizontalHeaderItem(0, item)
        self.tableWidget_6.horizontalHeader().setStretchLastSection(True)
        self.verticalLayout_8.addWidget(self.tableWidget_6)
        self.horizontalLayout_6.addWidget(self.groupBox_6)
        self.verticalLayout_2.addLayout(self.horizontalLayout_6)
        self.tabWidget.addTab(self.tab, "")
        self.tab_2 = QtWidgets.QWidget()
        self.tab_2.setObjectName("tab_2")
        self.verticalLayout_17 = QtWidgets.QVBoxLayout(self.tab_2)
        self.verticalLayout_17.setObjectName("verticalLayout_17")
        self.verticalLayout = QtWidgets.QVBoxLayout()
        self.verticalLayout.setObjectName("verticalLayout")
        self.horizontalLayout_2 = QtWidgets.QHBoxLayout()
        self.horizontalLayout_2.setObjectName("horizontalLayout_2")
        self.label = QtWidgets.QLabel(self.tab_2)
        self.label.setObjectName("label")
        self.horizontalLayout_2.addWidget(self.label)
        self.lineEdit = QtWidgets.QLineEdit(self.tab_2)
        self.lineEdit.setAlignment(QtCore.Qt.AlignCenter)
        self.lineEdit.setObjectName("lineEdit")
        self.horizontalLayout_2.addWidget(self.lineEdit)
        self.horizontalLayout_4 = QtWidgets.QHBoxLayout()
        self.horizontalLayout_4.setObjectName("horizontalLayout_4")
        self.pushButton = QtWidgets.QPushButton(self.tab_2)
        self.pushButton.setMinimumSize(QtCore.QSize(120, 27))
        self.pushButton.setObjectName("pushButton")
        self.horizontalLayout_4.addWidget(self.pushButton)
        self.horizontalLayout_2.addLayout(self.horizontalLayout_4)
        self.verticalLayout.addLayout(self.horizontalLayout_2)
        self.horizontalLayout_3 = QtWidgets.QHBoxLayout()
        self.horizontalLayout_3.setObjectName("horizontalLayout_3")
        self.label_2 = QtWidgets.QLabel(self.tab_2)
        self.label_2.setObjectName("label_2")
        self.horizontalLayout_3.addWidget(self.label_2)
        spacerItem = QtWidgets.QSpacerItem(40, 20, QtWidgets.QSizePolicy.Expanding, QtWidgets.QSizePolicy.Minimum)
        self.horizontalLayout_3.addItem(spacerItem)
        self.comboBox = QtWidgets.QComboBox(self.tab_2)
        sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Expanding, QtWidgets.QSizePolicy.Fixed)
        sizePolicy.setHorizontalStretch(0)
        sizePolicy.setVerticalStretch(0)
        sizePolicy.setHeightForWidth(self.comboBox.sizePolicy().hasHeightForWidth())
        self.comboBox.setSizePolicy(sizePolicy)
        self.comboBox.setObjectName("comboBox")
        self.comboBox.addItem("")
        self.comboBox.addItem("")
        self.comboBox.addItem("")
        self.comboBox.addItem("")
        self.comboBox.addItem("")
        self.comboBox.addItem("")
        self.comboBox.addItem("")
        self.horizontalLayout_3.addWidget(self.comboBox)
        spacerItem1 = QtWidgets.QSpacerItem(40, 20, QtWidgets.QSizePolicy.Expanding, QtWidgets.QSizePolicy.Minimum)
        self.horizontalLayout_3.addItem(spacerItem1)
        self.verticalLayout.addLayout(self.horizontalLayout_3)
        self.verticalLayout_17.addLayout(self.verticalLayout)
        self.frame = QtWidgets.QFrame(self.tab_2)
        self.frame.setFrameShape(QtWidgets.QFrame.StyledPanel)
        self.frame.setFrameShadow(QtWidgets.QFrame.Raised)
        self.frame.setObjectName("frame")
        self.verticalLayout_21 = QtWidgets.QVBoxLayout(self.frame)
        self.verticalLayout_21.setObjectName("verticalLayout_21")
        self.verticalLayout_20 = QtWidgets.QVBoxLayout()
        self.verticalLayout_20.setObjectName("verticalLayout_20")
        self.horizontalLayout_8 = QtWidgets.QHBoxLayout()
        self.horizontalLayout_8.setObjectName("horizontalLayout_8")
        self.tableWidget_7 = QtWidgets.QTableWidget(self.frame)
        sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Preferred, QtWidgets.QSizePolicy.Preferred)
        sizePolicy.setHorizontalStretch(0)
        sizePolicy.setVerticalStretch(0)
        sizePolicy.setHeightForWidth(self.tableWidget_7.sizePolicy().hasHeightForWidth())
        self.tableWidget_7.setSizePolicy(sizePolicy)
        self.tableWidget_7.setEditTriggers(QtWidgets.QAbstractItemView.NoEditTriggers)
        self.tableWidget_7.setAlternatingRowColors(True)
        self.tableWidget_7.setSelectionMode(QtWidgets.QAbstractItemView.SingleSelection)
        self.tableWidget_7.setSelectionBehavior(QtWidgets.QAbstractItemView.SelectRows)
        self.tableWidget_7.setObjectName("tableWidget_7")
        self.tableWidget_7.setColumnCount(1)
        self.tableWidget_7.setRowCount(0)
        item = QtWidgets.QTableWidgetItem()
        self.tableWidget_7.setHorizontalHeaderItem(0, item)
        self.tableWidget_7.horizontalHeader().setStretchLastSection(True)
        self.horizontalLayout_8.addWidget(self.tableWidget_7)
        self.verticalLayout_20.addLayout(self.horizontalLayout_8)
        self.verticalLayout_21.addLayout(self.verticalLayout_20)
        self.verticalLayout_17.addWidget(self.frame)
        self.frame_8 = QtWidgets.QFrame(self.tab_2)
        self.frame_8.setFrameShape(QtWidgets.QFrame.StyledPanel)
        self.frame_8.setFrameShadow(QtWidgets.QFrame.Raised)
        self.frame_8.setObjectName("frame_8")
        self.horizontalLayout_10 = QtWidgets.QHBoxLayout(self.frame_8)
        self.horizontalLayout_10.setObjectName("horizontalLayout_10")
        self.horizontalLayout_7 = QtWidgets.QHBoxLayout()
        self.horizontalLayout_7.setObjectName("horizontalLayout_7")
        spacerItem2 = QtWidgets.QSpacerItem(40, 20, QtWidgets.QSizePolicy.Expanding, QtWidgets.QSizePolicy.Minimum)
        self.horizontalLayout_7.addItem(spacerItem2)
        spacerItem3 = QtWidgets.QSpacerItem(40, 20, QtWidgets.QSizePolicy.Expanding, QtWidgets.QSizePolicy.Minimum)
        self.horizontalLayout_7.addItem(spacerItem3)
        self.label_3 = QtWidgets.QLabel(self.frame_8)
        self.label_3.setObjectName("label_3")
        self.horizontalLayout_7.addWidget(self.label_3)
        spacerItem4 = QtWidgets.QSpacerItem(40, 20, QtWidgets.QSizePolicy.Expanding, QtWidgets.QSizePolicy.Minimum)
        self.horizontalLayout_7.addItem(spacerItem4)
        spacerItem5 = QtWidgets.QSpacerItem(40, 20, QtWidgets.QSizePolicy.Expanding, QtWidgets.QSizePolicy.Minimum)
        self.horizontalLayout_7.addItem(spacerItem5)
        self.horizontalLayout_10.addLayout(self.horizontalLayout_7)
        self.verticalLayout_17.addWidget(self.frame_8)
        self.verticalLayout_17.setStretch(0, 2)
        self.verticalLayout_17.setStretch(1, 7)
        self.verticalLayout_17.setStretch(2, 1)
        self.tabWidget.addTab(self.tab_2, "")
        self.horizontalLayout_16.addWidget(self.tabWidget)
        self.line = QtWidgets.QFrame(self.centralwidget)
        self.line.setFrameShape(QtWidgets.QFrame.VLine)
        self.line.setFrameShadow(QtWidgets.QFrame.Sunken)
        self.line.setObjectName("line")
        self.horizontalLayout_16.addWidget(self.line)
        self.frame_2 = QtWidgets.QFrame(self.centralwidget)
        sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Minimum, QtWidgets.QSizePolicy.Expanding)
        sizePolicy.setHorizontalStretch(0)
        sizePolicy.setVerticalStretch(0)
        sizePolicy.setHeightForWidth(self.frame_2.sizePolicy().hasHeightForWidth())
        self.frame_2.setSizePolicy(sizePolicy)
        self.frame_2.setMinimumSize(QtCore.QSize(250, 0))
        self.frame_2.setFrameShape(QtWidgets.QFrame.StyledPanel)
        self.frame_2.setFrameShadow(QtWidgets.QFrame.Raised)
        self.frame_2.setObjectName("frame_2")
        self.verticalLayout_10 = QtWidgets.QVBoxLayout(self.frame_2)
        self.verticalLayout_10.setObjectName("verticalLayout_10")
        self.frame_3 = QtWidgets.QFrame(self.frame_2)
        sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Minimum, QtWidgets.QSizePolicy.Expanding)
        sizePolicy.setHorizontalStretch(0)
        sizePolicy.setVerticalStretch(0)
        sizePolicy.setHeightForWidth(self.frame_3.sizePolicy().hasHeightForWidth())
        self.frame_3.setSizePolicy(sizePolicy)
        self.frame_3.setFrameShape(QtWidgets.QFrame.Box)
        self.frame_3.setFrameShadow(QtWidgets.QFrame.Raised)
        self.frame_3.setObjectName("frame_3")
        self.verticalLayout_9 = QtWidgets.QVBoxLayout(self.frame_3)
        self.verticalLayout_9.setObjectName("verticalLayout_9")
        self.horizontalLayout_9 = QtWidgets.QHBoxLayout()
        self.horizontalLayout_9.setObjectName("horizontalLayout_9")
        self.label_4 = QtWidgets.QLabel(self.frame_3)
        sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.MinimumExpanding, QtWidgets.QSizePolicy.Expanding)
        sizePolicy.setHorizontalStretch(0)
        sizePolicy.setVerticalStretch(0)
        sizePolicy.setHeightForWidth(self.label_4.sizePolicy().hasHeightForWidth())
        self.label_4.setSizePolicy(sizePolicy)
        self.label_4.setScaledContents(True)
        self.label_4.setObjectName("label_4")
        self.horizontalLayout_9.addWidget(self.label_4)
        self.verticalLayout_9.addLayout(self.horizontalLayout_9)
        self.verticalLayout_10.addWidget(self.frame_3)
        self.frame_5 = QtWidgets.QFrame(self.frame_2)
        self.frame_5.setFrameShape(QtWidgets.QFrame.Box)
        self.frame_5.setFrameShadow(QtWidgets.QFrame.Raised)
        self.frame_5.setObjectName("frame_5")
        self.horizontalLayout_13 = QtWidgets.QHBoxLayout(self.frame_5)
        self.horizontalLayout_13.setObjectName("horizontalLayout_13")
        self.formLayout = QtWidgets.QFormLayout()
        self.formLayout.setObjectName("formLayout")
        self.label_5 = QtWidgets.QLabel(self.frame_5)
        self.label_5.setObjectName("label_5")
        self.formLayout.setWidget(0, QtWidgets.QFormLayout.LabelRole, self.label_5)
        self.label_6 = QtWidgets.QLabel(self.frame_5)
        self.label_6.setObjectName("label_6")
        self.formLayout.setWidget(0, QtWidgets.QFormLayout.FieldRole, self.label_6)
        self.label_7 = QtWidgets.QLabel(self.frame_5)
        self.label_7.setObjectName("label_7")
        self.formLayout.setWidget(1, QtWidgets.QFormLayout.LabelRole, self.label_7)
        self.label_8 = QtWidgets.QLabel(self.frame_5)
        self.label_8.setObjectName("label_8")
        self.formLayout.setWidget(1, QtWidgets.QFormLayout.FieldRole, self.label_8)
        self.label_9 = QtWidgets.QLabel(self.frame_5)
        self.label_9.setObjectName("label_9")
        self.formLayout.setWidget(2, QtWidgets.QFormLayout.LabelRole, self.label_9)
        self.label_10 = QtWidgets.QLabel(self.frame_5)
        self.label_10.setObjectName("label_10")
        self.formLayout.setWidget(2, QtWidgets.QFormLayout.FieldRole, self.label_10)
        self.label_11 = QtWidgets.QLabel(self.frame_5)
        self.label_11.setObjectName("label_11")
        self.formLayout.setWidget(3, QtWidgets.QFormLayout.LabelRole, self.label_11)
        self.label_12 = QtWidgets.QLabel(self.frame_5)
        self.label_12.setObjectName("label_12")
        self.formLayout.setWidget(3, QtWidgets.QFormLayout.FieldRole, self.label_12)
        self.label_21 = QtWidgets.QLabel(self.frame_5)
        self.label_21.setObjectName("label_21")
        self.formLayout.setWidget(4, QtWidgets.QFormLayout.LabelRole, self.label_21)
        self.label_22 = QtWidgets.QLabel(self.frame_5)
        self.label_22.setObjectName("label_22")
        self.formLayout.setWidget(4, QtWidgets.QFormLayout.FieldRole, self.label_22)
        self.label_23 = QtWidgets.QLabel(self.frame_5)
        self.label_23.setObjectName("label_23")
        self.formLayout.setWidget(5, QtWidgets.QFormLayout.LabelRole, self.label_23)
        self.label_24 = QtWidgets.QLabel(self.frame_5)
        self.label_24.setObjectName("label_24")
        self.formLayout.setWidget(5, QtWidgets.QFormLayout.FieldRole, self.label_24)
        self.label_26 = QtWidgets.QLabel(self.frame_5)
        self.label_26.setObjectName("label_26")
        self.formLayout.setWidget(6, QtWidgets.QFormLayout.LabelRole, self.label_26)
        self.label_27 = QtWidgets.QLabel(self.frame_5)
        self.label_27.setObjectName("label_27")
        self.formLayout.setWidget(6, QtWidgets.QFormLayout.FieldRole, self.label_27)
        self.horizontalLayout_13.addLayout(self.formLayout)
        self.verticalLayout_10.addWidget(self.frame_5)
        self.groupBox_7 = QtWidgets.QGroupBox(self.frame_2)
        sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Minimum, QtWidgets.QSizePolicy.Expanding)
        sizePolicy.setHorizontalStretch(0)
        sizePolicy.setVerticalStretch(0)
        sizePolicy.setHeightForWidth(self.groupBox_7.sizePolicy().hasHeightForWidth())
        self.groupBox_7.setSizePolicy(sizePolicy)
        self.groupBox_7.setObjectName("groupBox_7")
        self.horizontalLayout_11 = QtWidgets.QHBoxLayout(self.groupBox_7)
        self.horizontalLayout_11.setObjectName("horizontalLayout_11")
        self.label_25 = QtWidgets.QLabel(self.groupBox_7)
        sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Preferred, QtWidgets.QSizePolicy.Expanding)
        sizePolicy.setHorizontalStretch(0)
        sizePolicy.setVerticalStretch(0)
        sizePolicy.setHeightForWidth(self.label_25.sizePolicy().hasHeightForWidth())
        self.label_25.setSizePolicy(sizePolicy)
        self.label_25.setScaledContents(True)
        self.label_25.setWordWrap(True)
        self.label_25.setObjectName("label_25")
        self.horizontalLayout_11.addWidget(self.label_25)
        self.verticalLayout_10.addWidget(self.groupBox_7)
        self.horizontalLayout_16.addWidget(self.frame_2)
        self.line_2 = QtWidgets.QFrame(self.centralwidget)
        self.line_2.setFrameShape(QtWidgets.QFrame.VLine)
        self.line_2.setFrameShadow(QtWidgets.QFrame.Sunken)
        self.line_2.setObjectName("line_2")
        self.horizontalLayout_16.addWidget(self.line_2)
        self.frame_4 = QtWidgets.QFrame(self.centralwidget)
        self.frame_4.setMinimumSize(QtCore.QSize(200, 0))
        self.frame_4.setFrameShape(QtWidgets.QFrame.StyledPanel)
        self.frame_4.setFrameShadow(QtWidgets.QFrame.Raised)
        self.frame_4.setObjectName("frame_4")
        self.verticalLayout_11 = QtWidgets.QVBoxLayout(self.frame_4)
        self.verticalLayout_11.setObjectName("verticalLayout_11")
        self.groupBox_8 = QtWidgets.QGroupBox(self.frame_4)
        sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Minimum, QtWidgets.QSizePolicy.Minimum)
        sizePolicy.setHorizontalStretch(0)
        sizePolicy.setVerticalStretch(0)
        sizePolicy.setHeightForWidth(self.groupBox_8.sizePolicy().hasHeightForWidth())
        self.groupBox_8.setSizePolicy(sizePolicy)
        self.groupBox_8.setObjectName("groupBox_8")
        self.horizontalLayout_12 = QtWidgets.QHBoxLayout(self.groupBox_8)
        self.horizontalLayout_12.setObjectName("horizontalLayout_12")
        self.play_list = QtWidgets.QTableWidget(self.groupBox_8)
        self.play_list.setEditTriggers(QtWidgets.QAbstractItemView.NoEditTriggers)
        self.play_list.setSelectionMode(QtWidgets.QAbstractItemView.SingleSelection)
        self.play_list.setSelectionBehavior(QtWidgets.QAbstractItemView.SelectRows)
        self.play_list.setObjectName("play_list")
        self.play_list.setColumnCount(1)
        self.play_list.setRowCount(0)
        item = QtWidgets.QTableWidgetItem()
        self.play_list.setHorizontalHeaderItem(0, item)
        self.play_list.horizontalHeader().setStretchLastSection(True)
        self.play_list.verticalHeader().setVisible(True)
        self.horizontalLayout_12.addWidget(self.play_list, 0, QtCore.Qt.AlignHCenter)
        self.verticalLayout_11.addWidget(self.groupBox_8)
        self.horizontalLayout_16.addWidget(self.frame_4)
        self.verticalLayout_13.addLayout(self.horizontalLayout_16)
        self.line_3 = QtWidgets.QFrame(self.centralwidget)
        self.line_3.setFrameShape(QtWidgets.QFrame.HLine)
        self.line_3.setFrameShadow(QtWidgets.QFrame.Sunken)
        self.line_3.setObjectName("line_3")
        self.verticalLayout_13.addWidget(self.line_3)
        self.frame_6 = QtWidgets.QFrame(self.centralwidget)
        self.frame_6.setFrameShape(QtWidgets.QFrame.StyledPanel)
        self.frame_6.setFrameShadow(QtWidgets.QFrame.Sunken)
        self.frame_6.setObjectName("frame_6")
        self.verticalLayout_14 = QtWidgets.QVBoxLayout(self.frame_6)
        self.verticalLayout_14.setContentsMargins(10, -1, -1, -1)
        self.verticalLayout_14.setObjectName("verticalLayout_14")
        self.horizontalLayout_14 = QtWidgets.QHBoxLayout()
        self.horizontalLayout_14.setContentsMargins(100, -1, 100, -1)
        self.horizontalLayout_14.setObjectName("horizontalLayout_14")
        self.label_play_state = QtWidgets.QLabel(self.frame_6)
        self.label_play_state.setObjectName("label_play_state")
        self.horizontalLayout_14.addWidget(self.label_play_state, 0, QtCore.Qt.AlignHCenter)
        self.pushButton_8 = QtWidgets.QPushButton(self.frame_6)
        sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Fixed, QtWidgets.QSizePolicy.Fixed)
        sizePolicy.setHorizontalStretch(0)
        sizePolicy.setVerticalStretch(0)
        sizePolicy.setHeightForWidth(self.pushButton_8.sizePolicy().hasHeightForWidth())
        self.pushButton_8.setSizePolicy(sizePolicy)
        self.pushButton_8.setObjectName("pushButton_8")
        self.horizontalLayout_14.addWidget(self.pushButton_8)
        self.verticalLayout_14.addLayout(self.horizontalLayout_14)
        self.frame_7 = QtWidgets.QFrame(self.frame_6)
        self.frame_7.setFrameShape(QtWidgets.QFrame.StyledPanel)
        self.frame_7.setFrameShadow(QtWidgets.QFrame.Raised)
        self.frame_7.setObjectName("frame_7")
        self.verticalLayout_12 = QtWidgets.QVBoxLayout(self.frame_7)
        self.verticalLayout_12.setContentsMargins(-1, 0, -1, 0)
        self.verticalLayout_12.setObjectName("verticalLayout_12")
        self.horizontalLayout = QtWidgets.QHBoxLayout()
        self.horizontalLayout.setContentsMargins(100, 10, 100, -1)
        self.horizontalLayout.setObjectName("horizontalLayout")
        self.pushButton_2 = QtWidgets.QPushButton(self.frame_7)
        self.pushButton_2.setObjectName("pushButton_2")
        self.horizontalLayout.addWidget(self.pushButton_2)
        self.pushButton_3 = QtWidgets.QPushButton(self.frame_7)
        sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Preferred, QtWidgets.QSizePolicy.Fixed)
        sizePolicy.setHorizontalStretch(0)
        sizePolicy.setVerticalStretch(0)
        sizePolicy.setHeightForWidth(self.pushButton_3.sizePolicy().hasHeightForWidth())
        self.pushButton_3.setSizePolicy(sizePolicy)
        self.pushButton_3.setObjectName("pushButton_3")
        self.horizontalLayout.addWidget(self.pushButton_3)
        self.pushButton_4 = QtWidgets.QPushButton(self.frame_7)
        self.pushButton_4.setObjectName("pushButton_4")
        self.horizontalLayout.addWidget(self.pushButton_4)
        self.pushButton_5 = QtWidgets.QPushButton(self.frame_7)
        self.pushButton_5.setObjectName("pushButton_5")
        self.horizontalLayout.addWidget(self.pushButton_5)
        self.pushButton_6 = QtWidgets.QPushButton(self.frame_7)
        self.pushButton_6.setObjectName("pushButton_6")
        self.horizontalLayout.addWidget(self.pushButton_6)
        self.pushButton_7 = QtWidgets.QPushButton(self.frame_7)
        sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Preferred, QtWidgets.QSizePolicy.Fixed)
        sizePolicy.setHorizontalStretch(0)
        sizePolicy.setVerticalStretch(0)
        sizePolicy.setHeightForWidth(self.pushButton_7.sizePolicy().hasHeightForWidth())
        self.pushButton_7.setSizePolicy(sizePolicy)
        self.pushButton_7.setObjectName("pushButton_7")
        self.horizontalLayout.addWidget(self.pushButton_7)
        self.volume_slider = QtWidgets.QSlider(self.frame_7)
        sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Minimum, QtWidgets.QSizePolicy.Fixed)
        sizePolicy.setHorizontalStretch(0)
        sizePolicy.setVerticalStretch(0)
        sizePolicy.setHeightForWidth(self.volume_slider.sizePolicy().hasHeightForWidth())
        self.volume_slider.setSizePolicy(sizePolicy)
        self.volume_slider.setMaximum(100)
        self.volume_slider.setOrientation(QtCore.Qt.Horizontal)
        self.volume_slider.setObjectName("volume_slider")
        self.horizontalLayout.addWidget(self.volume_slider)
        self.verticalLayout_12.addLayout(self.horizontalLayout)
        self.horizontalLayout_15 = QtWidgets.QHBoxLayout()
        self.horizontalLayout_15.setContentsMargins(200, 10, 200, -1)
        self.horizontalLayout_15.setObjectName("horizontalLayout_15")
        self.progress_slider = QtWidgets.QSlider(self.frame_7)
        self.progress_slider.setOrientation(QtCore.Qt.Horizontal)
        self.progress_slider.setObjectName("progress_slider")
        self.horizontalLayout_15.addWidget(self.progress_slider)
        self.label_play_time = QtWidgets.QLabel(self.frame_7)
        self.label_play_time.setObjectName("label_play_time")
        self.horizontalLayout_15.addWidget(self.label_play_time)
        self.verticalLayout_12.addLayout(self.horizontalLayout_15)
        self.verticalLayout_14.addWidget(self.frame_7)
        self.verticalLayout_13.addWidget(self.frame_6)
        MainWindow.setCentralWidget(self.centralwidget)
        self.menubar = QtWidgets.QMenuBar(MainWindow)
        self.menubar.setGeometry(QtCore.QRect(0, 0, 1496, 26))
        self.menubar.setObjectName("menubar")
        MainWindow.setMenuBar(self.menubar)
        self.statusbar = QtWidgets.QStatusBar(MainWindow)
        self.statusbar.setObjectName("statusbar")
        MainWindow.setStatusBar(self.statusbar)

        self.retranslateUi(MainWindow)
        self.tabWidget.setCurrentIndex(0)
        QtCore.QMetaObject.connectSlotsByName(MainWindow)

    def retranslateUi(self, MainWindow):
        _translate = QtCore.QCoreApplication.translate
        MainWindow.setWindowTitle(_translate("MainWindow", "小说听听听"))
        self.groupBox.setTitle(_translate("MainWindow", "听China"))
        item = self.tableWidget_1.horizontalHeaderItem(0)
        item.setText(_translate("MainWindow", "书名"))
        self.groupBox_2.setTitle(_translate("MainWindow", "有声小说"))
        item = self.tableWidget_2.horizontalHeaderItem(0)
        item.setText(_translate("MainWindow", "书名"))
        self.groupBox_3.setTitle(_translate("MainWindow", "听书宝"))
        item = self.tableWidget_3.horizontalHeaderItem(0)
        item.setText(_translate("MainWindow", "书名"))
        self.groupBox_4.setTitle(_translate("MainWindow", "I275"))
        item = self.tableWidget_4.horizontalHeaderItem(0)
        item.setText(_translate("MainWindow", "书名"))
        self.groupBox_5.setTitle(_translate("MainWindow", "听书cn"))
        item = self.tableWidget_5.horizontalHeaderItem(0)
        item.setText(_translate("MainWindow", "书名"))
        self.groupBox_6.setTitle(_translate("MainWindow", "芒果听"))
        item = self.tableWidget_6.horizontalHeaderItem(0)
        item.setText(_translate("MainWindow", "书名"))
        self.tabWidget.setTabText(self.tabWidget.indexOf(self.tab), _translate("MainWindow", "小说推荐"))
        self.label.setText(_translate("MainWindow", "关键字:"))
        self.pushButton.setText(_translate("MainWindow", "搜索"))
        self.label_2.setText(_translate("MainWindow", "音源:"))
        self.comboBox.setItemText(0, _translate("MainWindow", "-请选择-"))
        self.comboBox.setItemText(1, _translate("MainWindow", "听China"))
        self.comboBox.setItemText(2, _translate("MainWindow", "有声小说"))
        self.comboBox.setItemText(3, _translate("MainWindow", "听书宝"))
        self.comboBox.setItemText(4, _translate("MainWindow", "I275"))
        self.comboBox.setItemText(5, _translate("MainWindow", "听书cn"))
        self.comboBox.setItemText(6, _translate("MainWindow", "芒果听"))
        item = self.tableWidget_7.horizontalHeaderItem(0)
        item.setText(_translate("MainWindow", "书名"))
        self.label_3.setText(_translate("MainWindow", "<html><head/><body><p align=\"center\"><span style=\" color:#55aaff;\">请先搜索</span></p></body></html>"))
        self.tabWidget.setTabText(self.tabWidget.indexOf(self.tab_2), _translate("MainWindow", "小说搜索"))
        self.label_4.setText(_translate("MainWindow", "<html><head/><body><p align=\"center\">这里显示小说封面</p></body></html>"))
        self.label_5.setText(_translate("MainWindow", "名称:"))
        self.label_6.setText(_translate("MainWindow", "未知"))
        self.label_7.setText(_translate("MainWindow", "状态:"))
        self.label_8.setText(_translate("MainWindow", "未知"))
        self.label_9.setText(_translate("MainWindow", "作者:"))
        self.label_10.setText(_translate("MainWindow", "未知"))
        self.label_11.setText(_translate("MainWindow", "主播:"))
        self.label_12.setText(_translate("MainWindow", "未知"))
        self.label_21.setText(_translate("MainWindow", "类型:"))
        self.label_22.setText(_translate("MainWindow", "未知"))
        self.label_23.setText(_translate("MainWindow", "更新时间:"))
        self.label_24.setText(_translate("MainWindow", "未知"))
        self.label_26.setText(_translate("MainWindow", "剧集数量"))
        self.label_27.setText(_translate("MainWindow", "未知"))
        self.groupBox_7.setTitle(_translate("MainWindow", "介绍"))
        self.label_25.setText(_translate("MainWindow", "<html><head/><body><p align=\"center\">未知</p></body></html>"))
        self.groupBox_8.setTitle(_translate("MainWindow", "点播列表"))
        item = self.play_list.horizontalHeaderItem(0)
        item.setText(_translate("MainWindow", "剧集"))
        self.label_play_state.setText(_translate("MainWindow", "<html><head/><body><p><span style=\" color:#55aaff;\">播放器已就绪</span></p></body></html>"))
        self.pushButton_8.setText(_translate("MainWindow", "收起"))
        self.pushButton_2.setText(_translate("MainWindow", "播放"))
        self.pushButton_3.setText(_translate("MainWindow", "暂停"))
        self.pushButton_4.setText(_translate("MainWindow", "停止"))
        self.pushButton_5.setText(_translate("MainWindow", "上一集"))
        self.pushButton_6.setText(_translate("MainWindow", "下一集"))
        self.pushButton_7.setText(_translate("MainWindow", "静音"))
        self.label_play_time.setText(_translate("MainWindow", "<html><head/><body><p><span style=\" color:#55aaff;\">0:00/0:00</span></p></body></html>"))

五.总结

本次使用PyQt5制作了一款在线小说播放器,支持六个音源的搜索,音频内容均来自互联网,UI没有详细地取设计,使用的默认的Fusion作为整体的主题皮肤,在播放器中使用第三方库qtawesome小图标,可视效果更强。写本文是为了记录一下开发思路与设计流程。思路、代码方面有什么不足欢迎各位大佬指正、批评!觉得还行,能点个赞吗?
请添加图片描述

posted on 2021-12-25 09:13  懷淰メ  阅读(4714)  评论(0编辑  收藏  举报