python +pyqt 小说下载阅读器 转语音合成 ,基于PyQt5生成图形页面(已打成exe可直接下载使用)

最近在学习python,写了一款简单的小说下载器,基本功能都已经实现,废话不多说 直接上效果

    

简单说下功能把

1.支持在线阅读,翻页 键盘快捷键上下(阅读) 左右(翻页)。可以导出TXT到本地,默认是当前目录。

2.支持搜索,暂停下载,继续下载 。由于采用的是轻量化sqlite数据库存储。好处是方便迁移。

3.已经打成EXE文件 放到文末,所需要的安装文件都有,可以直接去下载享用。

目录

源代码:

seachbook.py (主程序页面)

bookQThread.py 多线程调用(下载功能)

sqlFactory.py (sql文件)

Ui_rebook.py (ui页面)

下载地址


源代码:

seachbook.py (主程序页面)

1.样式使用了官方的qt_material 默认皮肤

2.播放声音需要下载解码器,可以自己搜索安装下 LAVFilters,很简单直接傻瓜式下一步

import requests
import parsel
import uuid
import datetime
import time
import sys
import os
from sqlFactory import sqlFactory
from Ui_rebook import Ui_MainWindow
import PyQt5.QtWidgets as QtWidgets
import PyQt5.QtCore as QtCore
import PyQt5.QtGui as QtGui
from qt_material import apply_stylesheet
from bs4 import BeautifulSoup
from bookQThread import downQThread
import ctypes
import pyttsx3
from PyQt5.QtMultimedia import QMediaPlayer, QMediaContent

ctypes.windll.shell32.SetCurrentProcessExplicitAppUserModelID("myappid")
class mainstart(QtWidgets.QMainWindow, Ui_MainWindow):

    def __init__(self):
          # 初始化父类
        super().__init__()

        self.player = QMediaPlayer()    

        # 调用Ui_Form的setupUi()方法构建页面
        self.setupUi(self)
        #透明度
        self.setWindowOpacity(0.95)
        #self.setAttribute(PyQt5.QtCore.Qt.WA_TranslucentBackground)  # 设置窗口背景透明
        self.setWindowFlag(QtCore.Qt.FramelessWindowHint)  # 隐藏边框

        self.setWindowTitle("小说搜索阅读器")   # 设置窗口名
        self.setWindowIcon(QtGui.QIcon("./bookicon.jpeg")) 
        #self.setWindowFlag(QtCore.Qt.FramelessWindowHint)

        self.timer = QtCore.QTimer(self)
        self.timer.start(1000)
        self.timer.timeout.connect(self.playByMode)

        self.pushButton.clicked.connect(self.pushButton_click)
        self.pushButton_2.clicked.connect(self.pushButton_2_click)
        self.pushButton_3.clicked.connect(self.pushButton_3_click)
        #下一章
        self.pushButton_4.clicked.connect(self.pushButton_4_click)
        #上一章
        self.pushButton_5.clicked.connect(self.pushButton_5_click)
        #展示
        self.pushButton_6.clicked.connect(self.pushButton_6_click)
        #刷新
        self.pushButton_7.clicked.connect(self.pushButton_7_click)

        self.pushButton_8.clicked.connect(self.pushButton_8_click)
        #取消
        self.pushButton_9.clicked.connect(self.pushButton_9_click)
        #转语音
        self.pushButton_10.clicked.connect(self.pushButton_10_click)
        #播放
        self.pushButton_11.clicked.connect(self.pushButton_11_click)
        #暂停
        self.pushButton_12.clicked.connect(self.pushButton_12_click)

        self.horizontalSlider.valueChanged.connect(self.pushButton_13_click)

        self.tabWidget.currentChanged.connect(self.tabCurrentIndex)
        self.treeWidget.clicked.connect(self.treeWidget_Clicked)
        #self.treeWidget.itemClicked.connect(self.treeWidget_Clicked)
        self.treeWidget.setContextMenuPolicy(QtCore.Qt.CustomContextMenu)  # 打开右键菜单的策略
        self.treeWidget.customContextMenuRequested.connect(self.treeWidgetItem_fun)  # 绑定事件

        #异步操作 处理后台任务
        self.p = downQThread(mainstart=self)  # 把主函数对象传给服务,方便服务操作控件
    
        #self.tab_2.mousePressEvent
        # 设置搜索列表总列数
        self.tableWidget.setColumnCount(6)
        self.textEdit.setReadOnly(True)
        self.textEdit.setFont(QtGui.QFont("宋体",10))
        #自适应列宽 占满空间
        self.tableWidget.horizontalHeader().setSectionResizeMode(QtWidgets.QHeaderView.Stretch)
        # 设置表头(excel_data.columns可以获取表头列表,默认第一列为表头)
        self.tableWidget.setHorizontalHeaderLabels(["小说地址","小说名称","最新章节","作者","更新日期","操作"])
        self.tableWidget.setColumnHidden(0, True)
        
        # 向下拉框中添加选型,具体为在下拉框第index+1个选型设置为内容name
        self.comboBox.addItems(['10','12','14'])
        self.comboBox.currentIndexChanged.connect(self.comboBoxChanged)

        
        #重置进度条
        self.progressBar.reset()

        self.sql = sqlFactory()
        self.count = 0
        self.content = None
        self.istree = True
        self.islose = None
        self.bookurl = None
        self.bookname = None
        self.chapter = None
        self.autoname = None
        self.chapterurl = None
        self.isdownend = None
        self.is_pause = True
        self.ismp3 = False
        t = time.time()
        now=datetime.datetime.now()
        self.mill = int(round(t * 1000))
        self.date = now.strftime("%Y-%m-%d %H:%M:%S")
    
    def comboBoxChanged(self):
        # 将下拉框中所有的选项删除
        #self.comboBox.clear()
        # 根据索引获取当前的下拉框内容
        index = self.comboBox.currentIndex()
        text = self.comboBox.itemText(index)
        self.textEdit.setFont(QtGui.QFont("宋体",int(text)))

    def treeWidgetItem_fun(self):
        item=self.treeWidget.currentItem()
        #item1= self.treeWidget.itemAt(pos)
        if item!=None : # 判断菜单是否为空
            popMenu =QtWidgets.QMenu()
            popMenu.addAction(QtWidgets.QAction(u'导出小说', self.treeWidget))
            popMenu.addAction(QtWidgets.QAction(u'删除小说', self.treeWidget))
            popMenu.triggered[QtWidgets.QAction].connect(self.processtrigger) # 右键点击清空之后执行的操作
            popMenu.exec_(QtGui.QCursor.pos())
    def processtrigger(self,q):
        #判断是项目节点还是任务节点
        item=self.treeWidget.currentItem()
        command=q.text()
        #item=self.taskTreeWidget.currentItem()
        if command=="导出小说":
            if item.parent() is None:
                if item.text(2)!='':
                    self.sql.sqlquery =(item.text(2),)
                    rows = self.sql.sql_select()
                    with open(rows[0][3]+'.txt','a',encoding='utf-8') as f:
                        for row in rows:
                            f.write(row[4])
            elif item.parent() is not None:
                self.sql.sqlquery =(item.text(2),item.text(1),)
                row = self.sql.sql_selectchapter()
                with open(row[1]+'.txt','a',encoding='utf-8') as f:
                    f.write(row[4])
            
            QtWidgets.QMessageBox.about(self, '提示', '导出小说成功')
        elif command=="删除小说":

            if item.parent() is None:
                if item.text(2)!='':
                    self.sql.sqlquery =(item.text(2),)
                    rows = self.sql.sql_delbook()
            elif item.parent() is not None:
                self.sql.sqlquery =(item.text(2),item.text(1),)
                row = self.sql.sql_delbookchapter()
            
            QtWidgets.QMessageBox.about(self, '提示', '删除小说成功')
            self.pushButton_7_click()
    def treeWidget_Clicked(self):
        te = self.treeWidget.currentItem().text(1)
        self.chapter = self.treeWidget.currentItem().text(0)
        self.ismp3 = False
        self.is_pause = True
        self.pushButton_10.setEnabled(True)
        self.pushButton_11.setEnabled(False)
        self.pushButton_12.setEnabled(False)
        self.label_3.setText('')
        self.label_4.setText('')
        if te =='':
            self.pushButton_10.setEnabled(False)
            self.textEdit.setText('') 
            return
        if os.path.exists('./'+str(self.chapter)+'.mp3'):
            self.player.setMedia(QMediaContent(QtCore.QUrl('./'+str(self.chapter)+'.mp3')))
            self.ismp3 = True
            self.pushButton_10.setEnabled(False)
            self.pushButton_11.setEnabled(True)
            self.pushButton_12.setEnabled(True)
            self.horizontalSlider.setMinimum(0)
            self.horizontalSlider.setMaximum(self.player.duration())
            self.label_3.setText('00:00')
            self.label_4.setText('00:00')
       

        chapterId = self.treeWidget.currentItem().text(1)
        bookId = self.treeWidget.currentItem().text(2)
        #print(bookId,chapterId)
        if bookId !="":
            self.sql.sqlquery =(bookId,chapterId,)
            row = self.sql.sql_selectchapter()
            self.textEdit.setFont(QtGui.QFont("宋体",10))
            self.textEdit.setText(row[4])
            self.bookname =row[1]
            self.chapter =row[3]
            #print(row[4])


    def gettree(self):
        self.treeWidget.setColumnCount(3)
        self.treeWidget.setHeaderLabels(['目录','章节id','书籍id'])
        self.treeWidget.setColumnWidth(0,150)
        #隐藏章节id和目录id
        self.treeWidget.setColumnHidden(1,True)
        self.treeWidget.setColumnHidden(2,True)
        
        #self.sql.sqlquery = (str("14930"),)
        rows = self.sql.sql_selectbook()
        rootlist = []
        if rows is not None:
            for row in rows:
                root = QtWidgets.QTreeWidgetItem(self.treeWidget)     #创建节点
                root.setText(0, row[1])
                root.setText(2, row[0]) #bookid
                self.sql.sqlquery = (row[0],)
                chapterrows = self.sql.sql_select()
                for chapter in chapterrows:
                    child = QtWidgets.QTreeWidgetItem(root)   #创建子节点
                    child.setText(0, chapter[0])   #设置第一列的值
                    child.setText(1, chapter[1]) #设置第二列的值
                    child.setText(2, row[0]) #设置第三列的值
                    #self.treeWidget.setAlternatingRowColors(True)
                    rootlist.append(child)

        self.treeWidget.insertTopLevelItems(0,rootlist)   #将创建的树节点添加到树控件中


    def tabCurrentIndex(self):
        if self.tabWidget.currentIndex() == 0:
            print('000')
        elif self.tabWidget.currentIndex() == 1:
            print('111')
        else:
            pass
    
    def keyPressEvent(self, a0: QtGui.QKeyEvent):
        print("key press response", a0.key())
        # if a0.key() == QtCore.Qt.Key_PageUp:
        #     self.on_back_image_view()
    
        # if a0.key() == QtCore.Qt.Key_PageDown:
        #     self.on_forward_image_view()

    def keyReleaseEvent(self, a0: QtGui.QKeyEvent):
        #print("key release response", a0.key())
        if a0.key() == QtCore.Qt.Key_Left:
            self.pushButton_5_click()

        if a0.key() == QtCore.Qt.Key_Right:
            self.pushButton_4_click()

    def mousePressEvent(self, event):  ##重写鼠标点击事件
        if event.button() == QtCore.Qt.LeftButton:
            self.Move = True  ##鼠标按下时设置为移动状态
            self.Point = event.globalPos() - self.pos()  ##记录起始点坐标
            event.accept()
            

    def mouseMoveEvent(self, QMouseEvent):  ##移动时间
        try:
            # 仅监听标题栏
            if QtCore.Qt.LeftButton and self.Move and self.label.underMouse():
                # 更改鼠标图标
                #self.setCursor(QtGui.QCursor(Qt.OpenHandCursor))
                # 更改窗口位置
                self.move(QMouseEvent.globalPos() - self.Point)
                QMouseEvent.accept()
        except Exception as e:
            print("报错信息=", e)

    def mouseReleaseEvent(self, QMouseEvent):  ##结束事件 
        self.Move = False

    def pushButton_click(self):
        self.close()

    def pushButton_2_click(self):
        self.content = self.lineEdit.text()
        self.seachtext()

    def pushButton_3_click(self):
        self.lineEdit.setText("")


    def pushButton_4_click(self):
        t = self.treeWidget.currentItem()
        if t is None or t=='' or t.text(1) =='':return
        #获取当前索引
        childint = t.parent().indexOfChild(t)
        
        t.setSelected(False)
        childints = t.parent().child(childint+1)
        if childints is None:
            QtWidgets.QMessageBox.warning(self, '提示', '已经到底啦!')
            return
        #设置显示选中
        childints.setSelected(True)
        #设置显示选中的是当前项   (当前项不一定是选中项 所以需要指定显示项为当前项)
        self.treeWidget.setCurrentItem(childints)
        
        self.treeWidget_Clicked()

    def pushButton_5_click(self):
        t = self.treeWidget.currentItem()
        if t is None or t=='' or t.text(1) =='':return
        #获取当前索引
        childint = t.parent().indexOfChild(t)
        if childint==0:
            QtWidgets.QMessageBox.warning(self, '提示', '已经到顶啦!')
            return
        
        t.setSelected(False)
        childints = t.parent().child(childint-1)
        #设置显示选中
        childints.setSelected(True)
        #设置显示选中的是当前项   (当前项不一定是选中项 所以需要指定显示项为当前项)
        self.treeWidget.setCurrentItem(childints)
        
        self.treeWidget_Clicked()

    
    def pushButton_6_click(self):
        if self.istree:
            self.treeWidget.setHidden(True)
            self.istree = False
        else:
            self.treeWidget.setVisible(True)
            self.istree = True

    def pushButton_7_click(self):
        self.treeWidget.clear()
        self.gettree()

    def pushButton_8_click(self):
        self.showMinimized()

    def pushButton_9_click(self):
        self.pushButton_9.setEnabled(False)
        self.isdownend = False
        self.progressBar.reset()

    def pushButton_11_click(self):
        
       # self.player.setPosition(10000)
        self.player.play()
        self.is_pause = False
        if self.player.duration() == self.horizontalSlider.value():
            self.is_pause = True
            self.horizontalSlider.setSliderPosition(1000)
        #duration = self.player.duration()
        #print(int(duration/1000/60))
        #self.horizontalSlider.setSliderPosition(50)

    def pushButton_12_click(self):
        self.is_pause = True
        self.player.pause()

    def pushButton_13_click(self):
        self.player.setPosition(self.horizontalSlider.value())
        #self.player.pause()
        #self.player.setCurPlaying()

    def pushButton_10_click(self):
        str = self.textEdit.toPlainText()
        if str!='':
            engine = pyttsx3.init() #初始化语音引擎
            engine.setProperty('rate', 125)   #设置语速
            engine.setProperty('volume',1)  #设置音量
            voices = engine.getProperty('voices') 
            engine.setProperty('voice',voices[0].id)   #设置第一个语音合成器
            engine.save_to_file(str,self.chapter+'.mp3')
            engine.runAndWait()
            engine.stop()
            self.ismp3 = True
            self.pushButton_10.setEnabled(False)
            self.pushButton_11.setEnabled(True)
            self.pushButton_12.setEnabled(True)

    # 根据播放模式自动播放,并刷新进度条
    def playByMode(self):
        # 刷新进度条
        if (not self.is_pause) :
            self.horizontalSlider.setMinimum(0)
            self.horizontalSlider.setMaximum(self.player.duration())
            self.horizontalSlider.setSliderPosition(self.horizontalSlider.value() + 1000)
        if self.ismp3:
            self.label_3.setText(time.strftime('%M:%S', time.localtime(self.player.position()/1000)))
            self.label_4.setText(time.strftime('%M:%S', time.localtime(self.player.duration()/1000)))
    def pushButton_down_click(self):
        if self.isdownend:return QtWidgets.QMessageBox.warning(self, '提示', '其他任务正在下载!')
            
        self.isdownend = True
        self.pushButton_9.setEnabled(True)
        #获取当前列
        #self.tableWidget.currentColumn()
        #获取当前行
        row = self.tableWidget.currentRow()
        self.bookurl = self.tableWidget.item(row,0).text()
        self.bookname = self.tableWidget.item(row,1).text()
        self.autoname = self.tableWidget.item(row,3).text()

       

        self.p.start()
        #self.getbook()
        #  #开启线程池
        # with ThreadPoolExecutor(50) as f:
        #     f.submit(self.getbook())
        #     f.shutdown()    

    def seachtext(self):
        header = {"User-Agent":'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/101.0.0.0 Safari/537.36'}
        #搜索书香
        url = "https://www.ibiquge.la/modules/article/waps.php"
        param = {"searchkey":self.content}
        response = requests.post(url,headers = header,params=param)
        response.encoding = 'utf-8'
        selector = parsel.Selector(response.text)
        trlist = selector.xpath('//table[@class="grid"]/tr')

        self.tableWidget.setColumnWidth(2, 200)
   
        data_table_current = 0
        for tr in trlist:
            
            self.bookname = tr.xpath('./td[1]/a/text()').get()
            chaptername = tr.xpath('./td[2]/a/text()').get()
            self.autoname = tr.xpath('./td[3]/text()').get()
            uptime = tr.xpath('./td[4]/text()').get()

            self.bookurl =  tr.xpath('./td[1]/a/@href').get()
            self.chapterurl =  tr.xpath('./td[2]/a/@href').get()
            if chaptername is None:continue

            self.tableWidget.setRowCount(data_table_current+1)
            #隐藏列
            #self.tableWidget.setColumnHidden(0, True)
            #展示行
            #self.tableWidget.setRowHidden(0, False)
            columns = [str(self.bookurl),self.bookname,chaptername,self.autoname,uptime]

            but = QtWidgets.QPushButton()
            #创建QPushButton控件
            but.setText('下载')
            self.tableWidget.setCellWidget(data_table_current,5,but)
            #绑定按钮
            but.clicked.connect(self.pushButton_down_click)
            #插入值
            for j in range(len(columns)):
                # 创建QTableWidgetItem对象,并设置值
                new_item = QtWidgets.QTableWidgetItem(columns[j])
                # 设置QTableWidgetItem对象启用、可以选中和可以编辑
                new_item.setFlags(QtCore.Qt.ItemIsSelectable | QtCore.Qt.ItemIsEnabled | QtCore.Qt.ItemIsEnabled)
                # 设置QTableWidgetItem对象里面的值水平,垂直居中
                new_item.setTextAlignment(QtCore.Qt.AlignHCenter | QtCore.Qt.AlignVCenter)
                # 将新建的QTableWidgetItem添加到tableWidget中,参数分别是(行索引,列索引,QTableWidgetItem对象)
                self.tableWidget.setItem(data_table_current, j, new_item)
            # 写数据的当前索引加1
            data_table_current += 1



    def getbook(self):
        books = str(self.bookurl).split('/')[4]
        self.sql.sqlquery = (books,)
        rows = self.sql.sql_select()
        print(len(rows))

        header = {"User-Agent":'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/101.0.0.0 Safari/537.36'}

        response = requests.get(self.bookurl,headers = header)
        response.encoding = 'utf-8'
        selector = parsel.Selector(response.text)

        dllist = selector.xpath('//div[@id="list"]/dl[1]//dd')

        cont = 0
        for dl in dllist:
            cont+=1
        self.progressBar.setMaximum(cont)

        con = 0
        for dl in dllist:
            if self.isdownend == False: return
            chapterurl = dl.xpath('./a/@href').get()
            sp = str(chapterurl).split('/')
            chapterid = sp[3].replace('.html','')
            exist = False
            con+=1
            for row in rows:
                if chapterid == row[1]:
                    exist = True

            if exist:continue
            response = requests.get('https://www.ibiquge.la/'+str(chapterurl),headers = header)
            response.encoding = 'utf-8'
            selector = parsel.Selector(response.text)
            chaptername = selector.xpath('//div[@class="bookname"]/h1/text()').get()
            #content = selector.xpath('//div[@id="content"]').extract()
            content = selector.xpath('//div[@id="content"]').getall()
            ss ='\n'+'  '+chaptername+'\n'+str(content).replace('\\xa0',' ').replace('\\r<br>\\r<br>','\n').replace('[','').replace(']','')
            
            soup = BeautifulSoup(ss[0:ss.index("亲,点击进去,给个好评呗")],'html.parser').get_text()
            
            
            self.sql.sqlquery = (str(uuid.uuid4()), self.bookname, self.autoname, chaptername,soup,sp[2],chapterid,self.date,self.date,con,len(soup),)
            #保存入库
            self.sql.sql_insert()
            self.progressBar.setValue(con)
            if con == cont:
                self.isdownend = False
                self.pushButton_9.setEnabled(False)
            self.label_2.setText(self.bookname+' '+chaptername+'下载成功!')


    def selectlose(self):
        loserows = self.sql.sql_selectlose()
        if loserows is not None:
            self.islose = 1
            for row in loserows:
                bookId = row[5]
                chapterId = row[6]
                catePid = row[7]
                self.getbookchapter(bookId,chapterId,catePid,None,None)


    def getbookchapter(self,bookId,chapterId,catePid,wordNum,createTime):
        header = {"User-Agent":'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/101.0.0.0 Safari/537.36'}
        url = "https://book.zongheng.com/chapter/"+str(bookId)+"/"+str(chapterId)+".html"
        response = requests.get(url,headers = header)
        time.sleep(0.1)
        selector = parsel.Selector(response.text)
        #获取书名
        warp = selector.xpath('//div[@id="reader_warp"]/div/a[3]/text()').get()
        #获取章节
        chapter = selector.xpath('//div[@class="title_txtbox"]/text()').get()
        #获取作者
        auto = selector.xpath('//div[@class="bookinfo"]/a[1]/text()').get()
        #获取内容
        readers = selector.xpath('//div[@class="reader_box"]/div[@class="content"]/p')
        
        reader = ''
        for reader_line in readers:
            readerl = reader_line.xpath('./text()').get()
            reader +=readerl+'\n'
            #print(reader)

        if self.islose == 0:
            self.sql.sqlquery = (str(uuid.uuid4()), warp, auto, chapter,reader,bookId,chapterId,createTime,self.date,catePid,wordNum,)
            #保存入库
            self.sql.sql_insert()
        elif self.islose == 1:
            self.sql.sqlquery = (warp,auto,chapter,reader,bookId,chapterId,)
            #补录数据
            self.sql.sql_update()



if __name__=='__main__':
    app = QtWidgets.QApplication(sys.argv)
    apply_stylesheet(app, theme='dark_teal.xml')
    # 实例化页面并展示
    demo_win = mainstart()
    demo_win.gettree()
    demo_win.show()

    sys.exit(app.exec_())
    app.sql.con.close()
        

bookQThread.py 多线程调用(下载功能)

由于图形页面需要一些耗时的操作,需要处理成异步任务否则页面就会卡死,此处使用了pyqt自带的多线程模块。

import PyQt5.QtCore as QtCore
import time

class downQThread(QtCore.QThread):  
    signal =QtCore.pyqtSignal(int)

    def __init__(self, *args, **kwargs):
        super(downQThread, self).__init__()
        self.main_win = kwargs.get('mainstart')
        self.signal.connect(self.refresh)

    def run(self):
        self.main_win.getbook()
       
        print('任务执行中'+self.main_win.bookname)

    def refresh(self, m):
        self.main_win.progressBar.setValue(m)

sqlFactory.py (sql文件)

这块没啥好说的就是简单的CRUD,数据库采用的轻量级sqlite。好处是迁移方便,直接把db文件拷走就可以读取。不熟悉的可以搜索下,安装包我也上传了。

import sqlite3
#数据库操作类
class sqlFactory:
    sqlquery = None
    def __init__(self):
        self.con = sqlite3.connect('book.db',timeout=10, check_same_thread=False)

    # dict_factoryの定義
    def dict_factory(cursor, row):
        d = {}
        for idx, col in enumerate(cursor.description):
            d[col[0]] = row[idx]
        return d
    
    def sql_insert(self):

        cursorObj = self.con.cursor()

        sql = '''INSERT INTO book(id,title,auto,chapter,content,bookId,chapterId,createTime,inserttime,catePid,wordNum) 
        VALUES(?,?,?,?,?,?,?,?,?,?,?);
        '''
        cursorObj.execute(sql,self.sqlquery)
        
        self.con.commit()
        #print(self.sqlquery[0])
        #print(self.sqlquery[3]+'添加成功!' if (self.sqlquery[3] is not None and self.sqlquery[3]!= '') else self.sqlquery[0]+'添加成功!')


    def sql_selectchapter(self):

        cursorObj = self.con.cursor()

        cursorObj.execute('SELECT * FROM book where bookId = ? and chapterId = ?',self.sqlquery)

        rows = cursorObj.fetchone()
        return rows
    
    def sql_selectbook(self):

        cursorObj = self.con.cursor()

        cursorObj.execute('SELECT bookId,title,auto FROM book group by bookId,title,auto ')

        rows = cursorObj.fetchall()
        return rows
    
    def sql_select(self):
        #self.con.row_factory = sqlFactory.dict_factory

        cursorObj = self.con.cursor()

        cursorObj.execute('SELECT chapter,chapterId,auto,title,content FROM book where bookId = ? order by catePid ',self.sqlquery)

        rows = cursorObj.fetchall()
        return rows
    
    
    def sql_selectlose(self):

        cursorObj = self.con.cursor()

        cursorObj.execute('SELECT * FROM book where title is null and auto is null')

        rows = cursorObj.fetchall()
        return rows
    
    def sql_update(self):

        cursorObj = self.con.cursor()

        cursorObj.execute('update book set title = ?,auto =?,chapter = ?,content = ? where  bookId = ? and chapterId = ?',self.sqlquery)

        self.con.commit()
        print(str(self.sqlquery[0])+str(self.sqlquery[2])+'补录成功!')


    def sql_delbook(self):
        cursorObj = self.con.cursor()

        sql = '''delete from book where bookId = ? 
        '''
        cursorObj.execute(sql,self.sqlquery)
        
        self.con.commit()
        print(str(self.sqlquery[0])+'删除成功!')

    def sql_delbookchapter(self):
        cursorObj = self.con.cursor()

        sql = '''delete from book where bookId = ?  and chapterId = ?
        '''
        cursorObj.execute(sql,self.sqlquery)
        
        self.con.commit()
        print(str(self.sqlquery[1])+'删除成功!')

    def sql_delorinert(self):
        cursorObj = self.con.cursor()

        sql = '''delete from book where bookId = ?  and chapterId =
            (select chapterId from book where bookId = ?  order by createTime DESC limit 1);
        
        '''
        cursorObj.execute(sql,self.sqlquery)
        
        self.con.commit()
        print(str(self.sqlquery[1])+'最新一篇删除成功!')


if __name__=='__main__':
     aa = sqlFactory()
     aa.sqlquery = ('1212','asdas',)
     aa.sql_select()
     print(aa)

Ui_rebook.py (ui页面)



from PyQt5 import QtCore, QtGui, QtWidgets


class Ui_MainWindow(object):
    def setupUi(self, MainWindow):
        MainWindow.setObjectName("MainWindow")
        MainWindow.setEnabled(True)
        MainWindow.resize(800, 600)
        MainWindow.setMinimumSize(QtCore.QSize(800, 2))
        MainWindow.setMaximumSize(QtCore.QSize(800, 600))
        MainWindow.setAutoFillBackground(False)
        self.centralwidget = QtWidgets.QWidget(MainWindow)
        self.centralwidget.setMinimumSize(QtCore.QSize(800, 600))
        self.centralwidget.setMaximumSize(QtCore.QSize(800, 600))
        self.centralwidget.setObjectName("centralwidget")
        self.verticalLayout_2 = QtWidgets.QVBoxLayout(self.centralwidget)
        self.verticalLayout_2.setContentsMargins(0, 0, 0, 0)
        self.verticalLayout_2.setSpacing(1)
        self.verticalLayout_2.setObjectName("verticalLayout_2")
        self.horizontalLayout = QtWidgets.QHBoxLayout()
        self.horizontalLayout.setSpacing(1)
        self.horizontalLayout.setObjectName("horizontalLayout")
        self.label = QtWidgets.QLabel(self.centralwidget)
        self.label.setAlignment(QtCore.Qt.AlignCenter)
        self.label.setObjectName("label")
        self.horizontalLayout.addWidget(self.label)
        self.pushButton_8 = QtWidgets.QPushButton(self.centralwidget)
        self.pushButton_8.setMaximumSize(QtCore.QSize(30, 30))
        self.pushButton_8.setObjectName("pushButton_8")
        self.horizontalLayout.addWidget(self.pushButton_8)
        self.pushButton = QtWidgets.QPushButton(self.centralwidget)
        self.pushButton.setEnabled(True)
        self.pushButton.setMaximumSize(QtCore.QSize(30, 30))
        self.pushButton.setIconSize(QtCore.QSize(10, 10))
        self.pushButton.setObjectName("pushButton")
        self.horizontalLayout.addWidget(self.pushButton)
        self.verticalLayout_2.addLayout(self.horizontalLayout)
        self.tabWidget = QtWidgets.QTabWidget(self.centralwidget)
        self.tabWidget.setEnabled(True)
        self.tabWidget.setMinimumSize(QtCore.QSize(0, 2))
        self.tabWidget.setTabBarAutoHide(False)
        self.tabWidget.setObjectName("tabWidget")
        self.tab = QtWidgets.QWidget()
        self.tab.setObjectName("tab")
        self.verticalLayout_5 = QtWidgets.QVBoxLayout(self.tab)
        self.verticalLayout_5.setContentsMargins(0, 0, 0, 11)
        self.verticalLayout_5.setSpacing(1)
        self.verticalLayout_5.setObjectName("verticalLayout_5")
        self.horizontalLayout_2 = QtWidgets.QHBoxLayout()
        self.horizontalLayout_2.setSpacing(0)
        self.horizontalLayout_2.setObjectName("horizontalLayout_2")
        self.comboBox_2 = QtWidgets.QComboBox(self.tab)
        self.comboBox_2.setCursor(QtGui.QCursor(QtCore.Qt.ArrowCursor))
        self.comboBox_2.setContextMenuPolicy(QtCore.Qt.ActionsContextMenu)
        self.comboBox_2.setObjectName("comboBox_2")
        self.comboBox_2.addItem("")
        self.comboBox_2.addItem("")
        self.horizontalLayout_2.addWidget(self.comboBox_2)
        self.lineEdit = QtWidgets.QLineEdit(self.tab)
        self.lineEdit.setObjectName("lineEdit")
        self.horizontalLayout_2.addWidget(self.lineEdit)
        self.pushButton_2 = QtWidgets.QPushButton(self.tab)
        self.pushButton_2.setMinimumSize(QtCore.QSize(60, 0))
        self.pushButton_2.setMaximumSize(QtCore.QSize(15, 25))
        self.pushButton_2.setObjectName("pushButton_2")
        self.horizontalLayout_2.addWidget(self.pushButton_2)
        self.pushButton_3 = QtWidgets.QPushButton(self.tab)
        self.pushButton_3.setMinimumSize(QtCore.QSize(60, 0))
        self.pushButton_3.setMaximumSize(QtCore.QSize(60, 25))
        self.pushButton_3.setObjectName("pushButton_3")
        self.horizontalLayout_2.addWidget(self.pushButton_3)
        self.verticalLayout_5.addLayout(self.horizontalLayout_2)
        self.tableWidget = QtWidgets.QTableWidget(self.tab)
        self.tableWidget.setLineWidth(1)
        self.tableWidget.setObjectName("tableWidget")
        self.tableWidget.setColumnCount(0)
        self.tableWidget.setRowCount(0)
        self.verticalLayout_5.addWidget(self.tableWidget)
        self.verticalLayout = QtWidgets.QVBoxLayout()
        self.verticalLayout.setSpacing(1)
        self.verticalLayout.setObjectName("verticalLayout")
        self.horizontalLayout_6 = QtWidgets.QHBoxLayout()
        self.horizontalLayout_6.setSpacing(1)
        self.horizontalLayout_6.setObjectName("horizontalLayout_6")
        self.progressBar = QtWidgets.QProgressBar(self.tab)
        self.progressBar.setProperty("value", 24)
        self.progressBar.setObjectName("progressBar")
        self.horizontalLayout_6.addWidget(self.progressBar)
        self.pushButton_9 = QtWidgets.QPushButton(self.tab)
        self.pushButton_9.setEnabled(False)
        self.pushButton_9.setMinimumSize(QtCore.QSize(100, 0))
        self.pushButton_9.setMaximumSize(QtCore.QSize(100, 25))
        self.pushButton_9.setObjectName("pushButton_9")
        self.horizontalLayout_6.addWidget(self.pushButton_9)
        self.verticalLayout.addLayout(self.horizontalLayout_6)
        self.verticalLayout_5.addLayout(self.verticalLayout)
        self.horizontalLayout_8 = QtWidgets.QHBoxLayout()
        self.horizontalLayout_8.setSpacing(1)
        self.horizontalLayout_8.setObjectName("horizontalLayout_8")
        spacerItem = QtWidgets.QSpacerItem(40, 20, QtWidgets.QSizePolicy.Expanding, QtWidgets.QSizePolicy.Minimum)
        self.horizontalLayout_8.addItem(spacerItem)
        self.label_2 = QtWidgets.QLabel(self.tab)
        self.label_2.setText("")
        self.label_2.setObjectName("label_2")
        self.horizontalLayout_8.addWidget(self.label_2)
        spacerItem1 = QtWidgets.QSpacerItem(40, 20, QtWidgets.QSizePolicy.Expanding, QtWidgets.QSizePolicy.Minimum)
        self.horizontalLayout_8.addItem(spacerItem1)
        self.verticalLayout_5.addLayout(self.horizontalLayout_8)
        self.tabWidget.addTab(self.tab, "")
        self.tab_2 = QtWidgets.QWidget()
        self.tab_2.setObjectName("tab_2")
        self.verticalLayout_6 = QtWidgets.QVBoxLayout(self.tab_2)
        self.verticalLayout_6.setObjectName("verticalLayout_6")
        self.horizontalLayout_3 = QtWidgets.QHBoxLayout()
        self.horizontalLayout_3.setSpacing(0)
        self.horizontalLayout_3.setObjectName("horizontalLayout_3")
        self.pushButton_6 = QtWidgets.QPushButton(self.tab_2)
        self.pushButton_6.setMaximumSize(QtCore.QSize(16777215, 20))
        self.pushButton_6.setObjectName("pushButton_6")
        self.horizontalLayout_3.addWidget(self.pushButton_6)
        self.pushButton_7 = QtWidgets.QPushButton(self.tab_2)
        self.pushButton_7.setMaximumSize(QtCore.QSize(16777215, 20))
        self.pushButton_7.setObjectName("pushButton_7")
        self.horizontalLayout_3.addWidget(self.pushButton_7)
        spacerItem2 = QtWidgets.QSpacerItem(40, 20, QtWidgets.QSizePolicy.Expanding, QtWidgets.QSizePolicy.Minimum)
        self.horizontalLayout_3.addItem(spacerItem2)
        self.comboBox = QtWidgets.QComboBox(self.tab_2)
        self.comboBox.setMaximumSize(QtCore.QSize(16777215, 20))
        self.comboBox.setCurrentText("")
        self.comboBox.setObjectName("comboBox")
        self.horizontalLayout_3.addWidget(self.comboBox)
        self.verticalLayout_6.addLayout(self.horizontalLayout_3)
        self.horizontalLayout_4 = QtWidgets.QHBoxLayout()
        self.horizontalLayout_4.setContentsMargins(-1, -1, -1, 10)
        self.horizontalLayout_4.setSpacing(1)
        self.horizontalLayout_4.setObjectName("horizontalLayout_4")
        self.treeWidget = QtWidgets.QTreeWidget(self.tab_2)
        self.treeWidget.setObjectName("treeWidget")
        self.treeWidget.headerItem().setText(0, "1")
        self.horizontalLayout_4.addWidget(self.treeWidget)
        self.verticalLayout_4 = QtWidgets.QVBoxLayout()
        self.verticalLayout_4.setSpacing(1)
        self.verticalLayout_4.setObjectName("verticalLayout_4")
        self.textEdit = QtWidgets.QTextEdit(self.tab_2)
        self.textEdit.setObjectName("textEdit")
        self.verticalLayout_4.addWidget(self.textEdit)
        self.horizontalLayout_5 = QtWidgets.QHBoxLayout()
        self.horizontalLayout_5.setSpacing(4)
        self.horizontalLayout_5.setObjectName("horizontalLayout_5")
        self.pushButton_5 = QtWidgets.QPushButton(self.tab_2)
        self.pushButton_5.setObjectName("pushButton_5")
        self.horizontalLayout_5.addWidget(self.pushButton_5)
        spacerItem3 = QtWidgets.QSpacerItem(40, 20, QtWidgets.QSizePolicy.Expanding, QtWidgets.QSizePolicy.Minimum)
        self.horizontalLayout_5.addItem(spacerItem3)
        self.pushButton_4 = QtWidgets.QPushButton(self.tab_2)
        self.pushButton_4.setObjectName("pushButton_4")
        self.horizontalLayout_5.addWidget(self.pushButton_4)
        self.verticalLayout_4.addLayout(self.horizontalLayout_5)
        self.horizontalLayout_4.addLayout(self.verticalLayout_4)
        self.horizontalLayout_4.setStretch(1, 2)
        self.verticalLayout_6.addLayout(self.horizontalLayout_4)
        self.verticalLayout_3 = QtWidgets.QVBoxLayout()
        self.verticalLayout_3.setSpacing(11)
        self.verticalLayout_3.setObjectName("verticalLayout_3")
        self.horizontalSlider = QtWidgets.QSlider(self.tab_2)
        self.horizontalSlider.setOrientation(QtCore.Qt.Horizontal)
        self.horizontalSlider.setObjectName("horizontalSlider")
        self.verticalLayout_3.addWidget(self.horizontalSlider)
        self.horizontalLayout_7 = QtWidgets.QHBoxLayout()
        self.horizontalLayout_7.setContentsMargins(-1, -1, -1, 20)
        self.horizontalLayout_7.setObjectName("horizontalLayout_7")
        self.label_3 = QtWidgets.QLabel(self.tab_2)
        self.label_3.setText("")
        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)
        self.pushButton_10 = QtWidgets.QPushButton(self.tab_2)
        self.pushButton_10.setEnabled(False)
        self.pushButton_10.setMaximumSize(QtCore.QSize(16777215, 25))
        self.pushButton_10.setObjectName("pushButton_10")
        self.horizontalLayout_7.addWidget(self.pushButton_10)
        self.pushButton_11 = QtWidgets.QPushButton(self.tab_2)
        self.pushButton_11.setEnabled(False)
        self.pushButton_11.setMaximumSize(QtCore.QSize(16777215, 25))
        self.pushButton_11.setObjectName("pushButton_11")
        self.horizontalLayout_7.addWidget(self.pushButton_11)
        self.pushButton_12 = QtWidgets.QPushButton(self.tab_2)
        self.pushButton_12.setEnabled(False)
        self.pushButton_12.setMaximumSize(QtCore.QSize(16777215, 25))
        self.pushButton_12.setObjectName("pushButton_12")
        self.horizontalLayout_7.addWidget(self.pushButton_12)
        spacerItem5 = QtWidgets.QSpacerItem(40, 20, QtWidgets.QSizePolicy.Expanding, QtWidgets.QSizePolicy.Minimum)
        self.horizontalLayout_7.addItem(spacerItem5)
        self.label_4 = QtWidgets.QLabel(self.tab_2)
        self.label_4.setText("")
        self.label_4.setObjectName("label_4")
        self.horizontalLayout_7.addWidget(self.label_4)
        self.verticalLayout_3.addLayout(self.horizontalLayout_7)
        self.verticalLayout_6.addLayout(self.verticalLayout_3)
        self.tabWidget.addTab(self.tab_2, "")
        self.verticalLayout_2.addWidget(self.tabWidget)
        MainWindow.setCentralWidget(self.centralwidget)
        self.statusbar = QtWidgets.QStatusBar(MainWindow)
        self.statusbar.setObjectName("statusbar")
        MainWindow.setStatusBar(self.statusbar)

        self.retranslateUi(MainWindow)
        self.tabWidget.setCurrentIndex(1)
        self.tabWidget.currentChanged['int'].connect(self.tabWidget.setCurrentIndex)
        QtCore.QMetaObject.connectSlotsByName(MainWindow)

    def retranslateUi(self, MainWindow):
        _translate = QtCore.QCoreApplication.translate
        MainWindow.setWindowTitle(_translate("MainWindow", "MainWindow"))
        self.label.setText(_translate("MainWindow", "小说搜索阅读器"))
        self.pushButton_8.setText(_translate("MainWindow", "-"))
        self.pushButton.setText(_translate("MainWindow", "X"))
        self.comboBox_2.setItemText(0, _translate("MainWindow", "线路一"))
        self.comboBox_2.setItemText(1, _translate("MainWindow", "线路二"))
        self.pushButton_2.setText(_translate("MainWindow", "搜索"))
        self.pushButton_3.setText(_translate("MainWindow", "重置"))
        self.pushButton_9.setText(_translate("MainWindow", "取消下载"))
        self.tabWidget.setTabText(self.tabWidget.indexOf(self.tab), _translate("MainWindow", "搜索小说"))
        self.pushButton_6.setText(_translate("MainWindow", "展示/收起"))
        self.pushButton_7.setText(_translate("MainWindow", "刷新"))
        self.pushButton_5.setText(_translate("MainWindow", "上一章"))
        self.pushButton_4.setText(_translate("MainWindow", "下一章"))
        self.pushButton_10.setText(_translate("MainWindow", "小说转语音"))
        self.pushButton_11.setText(_translate("MainWindow", "播放"))
        self.pushButton_12.setText(_translate("MainWindow", "暂停"))
        self.tabWidget.setTabText(self.tabWidget.indexOf(self.tab_2), _translate("MainWindow", "阅读小说"))

下载地址

        https://download.csdn.net/download/vnfgh4/87579164

  • 1
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值