最近在学习python,写了一款简单的小说下载器,基本功能都已经实现,废话不多说 直接上效果
简单说下功能把
1.支持在线阅读,翻页 键盘快捷键上下(阅读) 左右(翻页)。可以导出TXT到本地,默认是当前目录。
2.支持搜索,暂停下载,继续下载 。由于采用的是轻量化sqlite数据库存储。好处是方便迁移。
3.已经打成EXE文件 放到文末,所需要的安装文件都有,可以直接去下载享用。
目录
源代码:
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", "阅读小说"))