mirror of
https://github.com/tonquer/picacg-qt.git
synced 2025-01-09 04:17:41 +08:00
Fix bug
修复漫画名出现单引号下载错误 修复分类搜索只能第一页 优化滚动翻页bug 优化看大分辨率图片出现卡顿
This commit is contained in:
parent
fd197b12e8
commit
894e9e9bdf
6
.github/workflows/python-app.yml
vendored
6
.github/workflows/python-app.yml
vendored
@ -73,12 +73,16 @@ jobs:
|
||||
Copy-Item -Verbose -Recurse -Path models -Destination bika/
|
||||
Copy-Item -Verbose -Recurse -Path resources -Destination bika/
|
||||
Remove-Item bika/resources/*.py -r -fo
|
||||
cp LICENSE bika\
|
||||
cp README.md bika\
|
||||
mkdir ${{ env.PACKAGENAME }}
|
||||
mv bika ${{ env.PACKAGENAME }}
|
||||
# 7z a -r "$($Env:PACKAGENAME + '.zip')" "bika"
|
||||
- name: Upload
|
||||
uses: actions/upload-artifact@v2
|
||||
with:
|
||||
name: ${{ env.PACKAGENAME }}
|
||||
path: bika
|
||||
path: ${{ env.PACKAGENAME }}
|
||||
|
||||
|
||||
macos:
|
||||
|
@ -1,5 +1,5 @@
|
||||
# picacg-windows | [ehentai-windows](https://github.com/tonquer/ehentai-windows)
|
||||
- 哔咔漫画window客户端(现已支持Linux和macOS),界面使用QT。
|
||||
# picacg-windows(哔咔漫画) | [ehentai-windows(E绅士)](https://github.com/tonquer/ehentai-windows)
|
||||
- 哔咔漫画PC客户端(支持window、Linux和macOS),界面使用QT。
|
||||
- 该项目仅供技术研究使用,请勿用于其他用途。
|
||||
- 如果觉得本项目对你有所帮助,请点个star关注,感谢支持
|
||||
- 如有使用中遇到问题,欢迎提ISSUE
|
||||
@ -57,7 +57,8 @@
|
||||
- waifu2x是用来提高图片分辨率和去噪点的功能, 介绍 "https://github.com/nagadomi/waifu2x"
|
||||
- waifu2x-python,修改了waifu2x-ncnn-vulkan部分功能
|
||||
- 由于bika限制上传图片的大小,所以部分图片(尤其是彩图)放在电脑大屏幕上观看会非常糊,所有通过waifu2x功能让图片在电脑上有更好的观感。
|
||||
- waifu2x功能使用的是 "https://github.com/tonquer/waifu2x-ncnn-vulkan-python" 改进而来,打包成lib目录下的waifu2x.pyd。
|
||||
- waifu2x功能使用的是 "https://github.com/tonquer/waifu2x-ncnn-vulkan-python" 。
|
||||
- 显卡性能太弱的不建议开启此功能。
|
||||
|
||||
## 如何使用
|
||||
### Windows (测试使用win10)
|
||||
|
@ -34,5 +34,6 @@ class CateGoryMgr(Singleton):
|
||||
newInfo = CateGoryBase()
|
||||
ToolUtil.ParseFromData(newInfo, info)
|
||||
self.idToCateGoryBase.append(newInfo)
|
||||
print("\""+newInfo.title+"\",", )
|
||||
Log.Info("初始化目录成功。。。")
|
||||
return
|
||||
|
@ -72,8 +72,8 @@ class DownloadDb(object):
|
||||
"VALUES ('{0}', '{1}', {2}, {3}, '{4}', '{5}', '{6}', '{7}', '{8}') " \
|
||||
"ON CONFLICT(bookId) DO UPDATE SET downloadEpsIds='{1}', curDownloadEpsId={2}, curConvertEpsId={3}, " \
|
||||
"title = '{4}', savePath = '{5}', convertPath= '{6}', status = '{7}', convertStatus = '{8}'".\
|
||||
format(task.bookId, json.dumps(task.downloadEpsIds), task.curDownloadEpsId, task.curConvertEpsId, task.title.replace("'", "\""),
|
||||
task.savePath, task.convertPath, task.status, task.convertStatus)
|
||||
format(task.bookId, json.dumps(task.downloadEpsIds), task.curDownloadEpsId, task.curConvertEpsId, task.title.replace("'", "''"),
|
||||
task.savePath.replace("'", "''"), task.convertPath.replace("'", "''"), task.status, task.convertStatus)
|
||||
|
||||
suc = query.exec_(sql)
|
||||
if not suc:
|
||||
@ -87,7 +87,7 @@ class DownloadDb(object):
|
||||
"VALUES ('{0}', {1}, '{2}', {3}, {4}, {5}) " \
|
||||
"ON CONFLICT(bookId, epsId) DO UPDATE SET epsTitle='{2}', picCnt={3}, curPreDownloadIndex={4}, " \
|
||||
"curPreConvertId = {5}".\
|
||||
format(info.parent.bookId, info.epsId, info.epsTitle, info.picCnt, info.curPreDownloadIndex,
|
||||
format(info.parent.bookId, info.epsId, info.epsTitle.replace("'", "''"), info.picCnt, info.curPreDownloadIndex,
|
||||
info.curPreConvertId)
|
||||
|
||||
suc = query.exec_(sql)
|
||||
|
@ -31,6 +31,45 @@ class QtSearch(QtWidgets.QWidget, Ui_search, QtTaskBase):
|
||||
self.keywordList.itemClicked.connect(self.ClickKeywordListItem)
|
||||
self.SetSearch()
|
||||
|
||||
self.allCategorise = [
|
||||
"嗶咔漢化",
|
||||
"全彩",
|
||||
"長篇",
|
||||
"同人",
|
||||
"短篇",
|
||||
"圓神領域",
|
||||
"碧藍幻想",
|
||||
"CG雜圖",
|
||||
"英語 ENG",
|
||||
"生肉",
|
||||
"純愛",
|
||||
"百合花園",
|
||||
"耽美花園",
|
||||
"偽娘哲學",
|
||||
"後宮閃光",
|
||||
"扶他樂園",
|
||||
"單行本",
|
||||
"姐姐系",
|
||||
"妹妹系",
|
||||
"SM",
|
||||
"性轉換",
|
||||
"足の恋",
|
||||
"人妻",
|
||||
"NTR",
|
||||
"強暴",
|
||||
"非人類",
|
||||
"艦隊收藏",
|
||||
"Love Live",
|
||||
"SAO 刀劍神域",
|
||||
"Fate",
|
||||
"東方",
|
||||
"WEBTOON",
|
||||
"禁書目錄",
|
||||
"歐美",
|
||||
"Cosplay",
|
||||
"重口地帶",
|
||||
]
|
||||
|
||||
def UpdateDbInfo(self):
|
||||
self.AddSqlTask("book", "", SqlServer.TaskTypeSelectUpdate, self.UpdateDbInfoBack)
|
||||
|
||||
@ -188,10 +227,10 @@ class QtSearch(QtWidgets.QWidget, Ui_search, QtTaskBase):
|
||||
# TODO 搜索和分类检索不太一样,切页时会有点问题
|
||||
sort = ["dd", "da", "ld", "vd"]
|
||||
sortId = sort[self.comboBox.currentIndex()]
|
||||
if self.localBox.isChecked():
|
||||
if self.localBox.isChecked() and self.categories in self.allCategorise:
|
||||
QtOwner().owner.loadingForm.show()
|
||||
sql = SqlServer.Search(self.categories, False, False, False, False, True, 1, self.sortKey.currentIndex(), self.sortId.currentIndex())
|
||||
self.AddSqlTask("book", sql, SqlServer.TaskTypeSelectBook, callBack=self.SendLocalBack, backParam=1)
|
||||
self.AddSqlTask("book", sql, SqlServer.TaskTypeSelectBook, callBack=self.SendLocalBack, backParam=page)
|
||||
else:
|
||||
self.AddHttpTask(req.CategoriesSearchReq(page, self.categories, sortId), self.SendSearchBack)
|
||||
|
||||
|
@ -316,6 +316,8 @@ class BikaQtMainWindow(QtWidgets.QMainWindow, Ui_MainWindow):
|
||||
def Close(self):
|
||||
self.downloadForm.Close()
|
||||
SqlServer().Stop()
|
||||
from src.qt.util.qttask import QtTask
|
||||
QtTask().Stop()
|
||||
|
||||
def ParseBookInfo(self, rawList):
|
||||
infos = []
|
||||
|
@ -81,6 +81,7 @@ class QtReadImg(QtWidgets.QWidget, QtTaskBase):
|
||||
self.pictureData.clear()
|
||||
self.ClearTask()
|
||||
self.ClearConvert()
|
||||
self.ClearQImageTask()
|
||||
|
||||
def OpenPage(self, bookId, epsId, name, isLastEps=False):
|
||||
if not bookId:
|
||||
@ -253,46 +254,49 @@ class QtReadImg(QtWidgets.QWidget, QtTaskBase):
|
||||
self.AddDownload(index, picInfo)
|
||||
else:
|
||||
p.SetData(data, self.category)
|
||||
if index == self.curIndex:
|
||||
self.ShowImg()
|
||||
elif self.isStripModel and self.curIndex < index <= self.curIndex + 2:
|
||||
self.ShowOtherPage()
|
||||
self.CheckLoadPicture()
|
||||
else:
|
||||
self.CheckLoadPicture()
|
||||
self.AddQImageTask(data, self.ConvertQImageBack, index)
|
||||
self.CheckLoadPicture()
|
||||
# if index == self.curIndex:
|
||||
# # self.ShowImg()
|
||||
# pass
|
||||
# elif self.isStripModel and self.curIndex < index <= self.curIndex + 2:
|
||||
# # self.ShowOtherPage()
|
||||
# self.CheckLoadPicture()
|
||||
# else:
|
||||
# self.CheckLoadPicture()
|
||||
# return
|
||||
|
||||
def ConvertQImageBack(self, data, index):
|
||||
assert isinstance(data, QImage)
|
||||
p = self.pictureData.get(index)
|
||||
if not p:
|
||||
return
|
||||
assert isinstance(p, QtFileData)
|
||||
p.cacheImage = data
|
||||
if index == self.curIndex:
|
||||
self.ShowImg()
|
||||
elif self.isStripModel and self.curIndex < index <= self.curIndex + 2:
|
||||
self.ShowOtherPage()
|
||||
return
|
||||
|
||||
@time_me
|
||||
def ShowOtherPage(self, isShowWaifu=True):
|
||||
for index in range(self.curIndex+1, self.curIndex+3):
|
||||
p = self.pictureData.get(index)
|
||||
if not p or (not p.data):
|
||||
self.frame.SetPixIem(index-self.curIndex, None)
|
||||
return
|
||||
if not p or (not p.data) or (not p.cacheImage):
|
||||
self.frame.SetPixIem(index-self.curIndex, QPixmap())
|
||||
continue
|
||||
|
||||
assert isinstance(p, QtFileData)
|
||||
if not isShowWaifu:
|
||||
p2 = p.data
|
||||
if not p.cacheImage or p.cacheWaifu2x:
|
||||
p.cacheImage = QImage()
|
||||
p.cacheWaifu2x = False
|
||||
p.cacheImage.loadFromData(p2)
|
||||
p2 = p.cacheImage
|
||||
|
||||
elif p.waifuData:
|
||||
p2 = p.waifuData
|
||||
if not p.cacheImage or not p.cacheWaifu2x:
|
||||
p.cacheImage = QImage()
|
||||
p.cacheWaifu2x = True
|
||||
p.cacheImage.loadFromData(p2)
|
||||
elif p.cacheWaifu2xImage:
|
||||
p2 = p.cacheWaifu2xImage
|
||||
else:
|
||||
p2 = p.data
|
||||
if not p.cacheImage:
|
||||
p.cacheImage = QImage()
|
||||
p.cacheWaifu2x = False
|
||||
p.cacheImage.loadFromData(p2)
|
||||
|
||||
pixMap = QPixmap(p.cacheImage)
|
||||
p2 = p.cacheImage
|
||||
|
||||
pixMap = QPixmap(p2)
|
||||
self.frame.SetPixIem(index-self.curIndex, pixMap)
|
||||
# self.frame.ScalePicture()
|
||||
return True
|
||||
@ -301,9 +305,13 @@ class QtReadImg(QtWidgets.QWidget, QtTaskBase):
|
||||
def ShowImg(self, isShowWaifu=True):
|
||||
p = self.pictureData.get(self.curIndex)
|
||||
|
||||
if not p or (not p.data):
|
||||
self.qtTool.SetData(state=QtFileData.Downloading)
|
||||
self.frame.SetPixIem(0, None)
|
||||
if not p or (not p.data) or (not p.cacheImage):
|
||||
if not p or (not p.data):
|
||||
self.qtTool.SetData(state=QtFileData.Downloading)
|
||||
else:
|
||||
self.qtTool.SetData(state=QtFileData.Converting)
|
||||
|
||||
self.frame.SetPixIem(0, QPixmap())
|
||||
|
||||
self.qtTool.modelBox.setEnabled(False)
|
||||
self.frame.UpdateProcessBar(None)
|
||||
@ -315,41 +323,27 @@ class QtReadImg(QtWidgets.QWidget, QtTaskBase):
|
||||
self.qtTool.modelBox.setEnabled(True)
|
||||
assert isinstance(p, QtFileData)
|
||||
if not isShowWaifu:
|
||||
p2 = p.data
|
||||
self.frame.waifu2xProcess.hide()
|
||||
self.qtTool.SetData(waifuSize=QSize(0, 0), waifuDataLen=0)
|
||||
if not p.cacheImage or p.cacheWaifu2x:
|
||||
p.cacheImage = QImage()
|
||||
p.cacheWaifu2x = False
|
||||
p.cacheImage.loadFromData(p2)
|
||||
p2 = p.cacheImage
|
||||
|
||||
elif p.waifuData:
|
||||
p2 = p.waifuData
|
||||
elif p.cacheWaifu2xImage:
|
||||
p2 = p.cacheWaifu2xImage
|
||||
self.frame.waifu2xProcess.hide()
|
||||
self.qtTool.SetData(waifuSize=p.waifuQSize, waifuDataLen=p.waifuDataSize,
|
||||
waifuTick=p.waifuTick)
|
||||
if not p.cacheImage or not p.cacheWaifu2x:
|
||||
p.cacheImage = QImage()
|
||||
p.cacheWaifu2x = True
|
||||
p.cacheImage.loadFromData(p2)
|
||||
|
||||
else:
|
||||
p2 = p.data
|
||||
p2 = p.cacheImage
|
||||
if config.IsOpenWaifu:
|
||||
self.frame.waifu2xProcess.show()
|
||||
else:
|
||||
self.frame.waifu2xProcess.hide()
|
||||
if not p.cacheImage:
|
||||
p.cacheImage = QImage()
|
||||
p.cacheWaifu2x = False
|
||||
p.cacheImage.loadFromData(p2)
|
||||
|
||||
self.qtTool.SetData(pSize=p.qSize, dataLen=p.size, state=p.state, waifuState=p.waifuState)
|
||||
self.qtTool.UpdateText(p.model)
|
||||
t = CTime()
|
||||
pixMap = QPixmap(p.cacheImage)
|
||||
|
||||
t.Refresh(self.__class__.__name__)
|
||||
|
||||
pixMap = QPixmap(p2)
|
||||
self.frame.SetPixIem(0, pixMap)
|
||||
# self.graphicsView.setSceneRect(QRectF(QPointF(0, 0), QPointF(pixMap.width(), pixMap.height())))
|
||||
# self.frame.ScalePicture()
|
||||
@ -450,15 +444,29 @@ class QtReadImg(QtWidgets.QWidget, QtTaskBase):
|
||||
Log.Error("Not found waifu2xId :{}, index: {}".format(str(waifu2xId), str(index)))
|
||||
return
|
||||
p.SetWaifuData(data, round(tick, 2))
|
||||
self.AddQImageTask(data, self.ConvertQImageWaifu2xBack, index)
|
||||
if index == self.curIndex:
|
||||
self.qtTool.SetData(waifuState=p.waifuState)
|
||||
self.ShowImg()
|
||||
# self.ShowImg()
|
||||
elif self.isStripModel and self.curIndex < index <= self.curIndex + 2:
|
||||
self.ShowOtherPage()
|
||||
# self.ShowOtherPage()
|
||||
self.CheckLoadPicture()
|
||||
else:
|
||||
self.CheckLoadPicture()
|
||||
|
||||
def ConvertQImageWaifu2xBack(self, data, index):
|
||||
assert isinstance(data, QImage)
|
||||
p = self.pictureData.get(index)
|
||||
if not p:
|
||||
return
|
||||
assert isinstance(p, QtFileData)
|
||||
p.cacheWaifu2xImage = data
|
||||
if index == self.curIndex:
|
||||
self.ShowImg()
|
||||
elif self.isStripModel and self.curIndex < index <= self.curIndex + 2:
|
||||
self.ShowOtherPage()
|
||||
return
|
||||
|
||||
def AddCovertData(self, picInfo, i):
|
||||
info = self.pictureData.get(i)
|
||||
if not info and info.data:
|
||||
@ -479,4 +487,4 @@ class QtReadImg(QtWidgets.QWidget, QtTaskBase):
|
||||
if i not in self.pictureData:
|
||||
data = QtFileData()
|
||||
self.pictureData[i] = data
|
||||
self.qtTool.SetData(state=self.pictureData[i].state)
|
||||
self.qtTool.SetData(state=self.pictureData[i].state)
|
||||
|
@ -4,11 +4,12 @@ from PySide2 import QtWidgets
|
||||
from PySide2.QtCore import Qt, QSizeF, QRectF, QEvent, QPoint, QSize
|
||||
from PySide2.QtGui import QPainter, QColor, QPixmap
|
||||
from PySide2.QtWidgets import QGraphicsScene, QGraphicsPixmapItem, QFrame, QGraphicsItemGroup, QGraphicsItem, \
|
||||
QAbstractSlider, QAbstractItemView
|
||||
QAbstractSlider, QAbstractItemView, QScroller
|
||||
|
||||
from resources.resources import DataMgr
|
||||
from src.qt.com.DWaterProgress import DWaterProgress
|
||||
from src.qt.com.qt_git_label import QtGifLabel
|
||||
from src.qt.com.qtbubblelabel import QtBubbleLabel
|
||||
from src.qt.read.qtreadimg_tool import QtImgTool
|
||||
from src.util.tool import time_me
|
||||
|
||||
@ -76,6 +77,7 @@ class QtImgFrame(QFrame):
|
||||
self.downloadSize = 1
|
||||
self.downloadMaxSize = 1
|
||||
self.oldValue = -1
|
||||
QScroller.grabGesture(self, QScroller.LeftMouseButtonGesture)
|
||||
self.graphicsView.verticalScrollBar().actionTriggered.connect(self.OnActionTriggered)
|
||||
self.graphicsView.verticalScrollBar().setSingleStep(100)
|
||||
self.graphicsView.verticalScrollBar().setPageStep(100)
|
||||
@ -91,7 +93,7 @@ class QtImgFrame(QFrame):
|
||||
if ev.type() == QEvent.GraphicsSceneMousePress:
|
||||
# print(ev, ev.button())
|
||||
self.startPos = ev.screenPos()
|
||||
return ev.ignore()
|
||||
return False
|
||||
elif ev.type() == QEvent.GraphicsSceneWheel:
|
||||
return True
|
||||
elif ev.type() == QEvent.KeyPress:
|
||||
@ -131,7 +133,7 @@ class QtImgFrame(QFrame):
|
||||
elif curPos.x() <= self.width()/3:
|
||||
self.qtTool.LastPage()
|
||||
|
||||
return ev.ignore()
|
||||
return False
|
||||
return super(self.__class__, self).eventFilter(obj, ev)
|
||||
|
||||
def resizeEvent(self, event) -> None:
|
||||
@ -145,19 +147,11 @@ class QtImgFrame(QFrame):
|
||||
value = self.graphicsView.verticalScrollBar().value()
|
||||
# print(value)
|
||||
|
||||
if self.oldValue == value:
|
||||
return
|
||||
self.UpdateScrollBar(value)
|
||||
|
||||
def UpdateScrollBar(self, value):
|
||||
self.UpdatePos(value-self.oldValue)
|
||||
self.graphicsView.verticalScrollBar().setMinimum(-100)
|
||||
if self.readImg.curIndex >= self.readImg.maxPic - 1:
|
||||
self.graphicsView.verticalScrollBar().setMaximum(value)
|
||||
elif not self.qtTool.isStripModel:
|
||||
self.graphicsView.verticalScrollBar().setMaximum(self.graphicsItem1.pixmap().size().height()-100)
|
||||
else:
|
||||
self.graphicsView.verticalScrollBar().setMaximum(100000)
|
||||
self.ResetScrollBar()
|
||||
self.graphicsView.verticalScrollBar().setSingleStep(self.height()//5)
|
||||
self.graphicsView.verticalScrollBar().setPageStep(self.height()//5)
|
||||
self.oldValue = value
|
||||
@ -183,14 +177,18 @@ class QtImgFrame(QFrame):
|
||||
return
|
||||
self.ScaleGraphicsItem()
|
||||
|
||||
self.graphicsView.verticalScrollBar().setMinimum(-100)
|
||||
self.graphicsView.verticalScrollBar().setMaximum(100000)
|
||||
self.ResetScrollBar()
|
||||
self.graphicsView.verticalScrollBar().setSingleStep(self.height()//5)
|
||||
self.graphicsView.verticalScrollBar().setPageStep(self.height()//5)
|
||||
|
||||
def ResetScrollBar(self):
|
||||
width1 = self.graphicsItem1.pixmap().size().width()
|
||||
width2 = self.graphicsItem2.pixmap().size().width()
|
||||
width3 = self.graphicsItem3.pixmap().size().width()
|
||||
self.graphicsView.verticalScrollBar().setMinimum(-100)
|
||||
self.graphicsView.verticalScrollBar().setMaximum(width1 + width2 + 100)
|
||||
|
||||
def SetPixIem(self, index, data):
|
||||
if not data:
|
||||
return
|
||||
if not self.qtTool.isStripModel and index > 0:
|
||||
self.pixMapList[index] = QPixmap()
|
||||
self.graphicsItemList[index].setPixmap(None)
|
||||
@ -255,6 +253,11 @@ class QtImgFrame(QFrame):
|
||||
# scale = (1+self.scaleCnt*0.1)
|
||||
if not self.qtTool.isStripModel:
|
||||
return
|
||||
|
||||
if value >= 0 and self.readImg.curIndex >= self.readImg.maxPic - 1:
|
||||
QtBubbleLabel().ShowMsgEx(self.readImg, "已经到最后一页")
|
||||
return
|
||||
|
||||
height = self.graphicsItem1.pixmap().size().height()
|
||||
## 切换上一图片
|
||||
if value < 0 and self.graphicsView.verticalScrollBar().value() < 0:
|
||||
|
@ -3,7 +3,7 @@ import weakref
|
||||
from PySide2 import QtWidgets
|
||||
from PySide2.QtCore import QEvent, Qt
|
||||
from PySide2.QtCore import QSize
|
||||
from PySide2.QtGui import QPalette
|
||||
from PySide2.QtGui import QPalette, QPixmap
|
||||
from PySide2.QtGui import Qt
|
||||
from PySide2.QtWidgets import QLabel
|
||||
|
||||
@ -197,8 +197,8 @@ class QtImgTool(QtWidgets.QWidget, Ui_ReadImg):
|
||||
def SwitchPicture(self):
|
||||
if self.radioButton.isChecked():
|
||||
self.isStripModel = False
|
||||
self.imgFrame.SetPixIem(1, None)
|
||||
self.imgFrame.SetPixIem(2, None)
|
||||
self.imgFrame.SetPixIem(1, QPixmap())
|
||||
self.imgFrame.SetPixIem(2, QPixmap())
|
||||
self.zoomSlider.setValue(100)
|
||||
self.scaleCnt = 0
|
||||
else:
|
||||
@ -378,6 +378,7 @@ class QtImgTool(QtWidgets.QWidget, Ui_ReadImg):
|
||||
continue
|
||||
data.model = model
|
||||
data.waifuData = None
|
||||
data.cacheWaifu2xImage = None
|
||||
data.waifuState = data.WaifuWait
|
||||
data.waifuDataSize = 0
|
||||
data.scaleW, data.scaleH = 0, 0
|
||||
|
@ -7,6 +7,7 @@ from src.util import ToolUtil
|
||||
|
||||
class QtFileData(object):
|
||||
Downloading = "开始下载"
|
||||
Converting = "转换中"
|
||||
DownloadSuc = "下载完成"
|
||||
DownloadError = "下载错误"
|
||||
DownloadReset = "重新下载"
|
||||
@ -33,7 +34,7 @@ class QtFileData(object):
|
||||
self.model = {}
|
||||
|
||||
self.cacheImage = None
|
||||
self.cacheWaifu2x = False
|
||||
self.cacheWaifu2xImage = None
|
||||
|
||||
self.downloadSize = 0
|
||||
|
||||
|
@ -93,7 +93,7 @@ class QtHistory(QtWidgets.QWidget, Ui_History):
|
||||
sql = "INSERT INTO history(bookId, name, epsId, picIndex, url, path, tick) " \
|
||||
"VALUES ('{0}', '{1}', {2}, {3}, '{4}', '{5}', {6}) " \
|
||||
"ON CONFLICT(bookId) DO UPDATE SET name='{1}', epsId={2}, picIndex={3}, url = '{4}', path='{5}', tick={6}".\
|
||||
format(bookId, name.replace("'", "\""), epsId, index, url, path, tick)
|
||||
format(bookId, name.replace("'", "''"), epsId, index, url, path, tick)
|
||||
suc = query.exec_(sql)
|
||||
if not suc:
|
||||
Log.Warn(query.lastError().text())
|
||||
|
@ -6,7 +6,8 @@ import time
|
||||
from queue import Queue
|
||||
from types import FunctionType
|
||||
import json
|
||||
from PySide2.QtCore import Signal, QObject
|
||||
from PySide2.QtCore import Signal, QObject, QThread
|
||||
from PySide2.QtGui import QImage
|
||||
|
||||
from conf import config
|
||||
from src.util import Singleton, Log
|
||||
@ -19,6 +20,7 @@ class QtTaskQObject(QObject):
|
||||
downloadBack = Signal(int, int, bytes)
|
||||
convertBack = Signal(int)
|
||||
sqlBack = Signal(int, bytes)
|
||||
imageBack = Signal(int, QImage)
|
||||
|
||||
def __init__(self):
|
||||
super(self.__class__, self).__init__()
|
||||
@ -90,6 +92,9 @@ class QtTaskBase:
|
||||
def AddConvertTask(self, path, imgData, model, completeCallBack, backParam=None, filePath=""):
|
||||
return QtTask().AddConvertTask(path, imgData, model, completeCallBack, backParam, self.__taskFlagId, filePath)
|
||||
|
||||
def AddQImageTask(self, data, callBack=None, backParam=None):
|
||||
return QtTask().AddQImageTask(data, callBack, backParam, cleanFlag=self.__taskFlagId)
|
||||
|
||||
def ClearTask(self):
|
||||
return QtTask().CancelTasks(self.__taskFlagId)
|
||||
|
||||
@ -102,6 +107,9 @@ class QtTaskBase:
|
||||
def ClearWaitConvertIds(self, taskIds):
|
||||
return QtTask().ClearWaitConvertIds(taskIds)
|
||||
|
||||
def ClearQImageTask(self):
|
||||
return QtTask().CancelImageTasks(self.__taskFlagId)
|
||||
|
||||
|
||||
class QtTask(Singleton, threading.Thread):
|
||||
|
||||
@ -109,11 +117,18 @@ class QtTask(Singleton, threading.Thread):
|
||||
Singleton.__init__(self)
|
||||
threading.Thread.__init__(self)
|
||||
self._inQueue = Queue()
|
||||
self._imageQueue = Queue()
|
||||
self.taskObj = QtTaskQObject()
|
||||
self.taskObj.taskBack.connect(self.HandlerTask2)
|
||||
self.taskObj.downloadBack.connect(self.HandlerDownloadTask)
|
||||
self.taskObj.convertBack.connect(self.HandlerConvertTask)
|
||||
self.taskObj.sqlBack.connect(self.HandlerSqlTask)
|
||||
self.taskObj.imageBack.connect(self.HandlerImageTask)
|
||||
|
||||
self.imageThreadList = []
|
||||
self.imageThread = threading.Thread(target=self._RunConvertQImg)
|
||||
self.imageThread.setDaemon(True)
|
||||
self.imageThread.start()
|
||||
|
||||
self.convertThread = threading.Thread(target=self.RunLoad)
|
||||
self.convertThread.setDaemon(True)
|
||||
@ -127,10 +142,12 @@ class QtTask(Singleton, threading.Thread):
|
||||
self.tasks = {} # id: task
|
||||
|
||||
self.sqlTasks = {}
|
||||
self.imageTasks = {}
|
||||
|
||||
self.flagToIds = {} #
|
||||
self.convertFlag = {}
|
||||
self.sqlFlagToIds = {}
|
||||
self.imageFlagToIds = {}
|
||||
|
||||
@property
|
||||
def convertBack(self):
|
||||
@ -148,6 +165,10 @@ class QtTask(Singleton, threading.Thread):
|
||||
def downloadBack(self):
|
||||
return self.taskObj.downloadBack
|
||||
|
||||
@property
|
||||
def imageBack(self):
|
||||
return self.taskObj.imageBack
|
||||
|
||||
def GetDownloadData(self, downloadId):
|
||||
if downloadId not in self.downloadTask:
|
||||
return b""
|
||||
@ -384,6 +405,9 @@ class QtTask(Singleton, threading.Thread):
|
||||
while True:
|
||||
try:
|
||||
taskId = self._inQueue.get(False)
|
||||
if taskId < 0:
|
||||
break
|
||||
|
||||
if taskId not in self.convertLoad:
|
||||
continue
|
||||
task = self.convertLoad.get(taskId)
|
||||
@ -466,4 +490,71 @@ class QtTask(Singleton, threading.Thread):
|
||||
Log.Info("cancel wait convert taskId, {}".format(taskIds))
|
||||
if config.CanWaifu2x:
|
||||
import waifu2x
|
||||
waifu2x.removeWaitProc(list(taskIds))
|
||||
waifu2x.removeWaitProc(list(taskIds))
|
||||
|
||||
def _RunConvertQImg(self):
|
||||
while True:
|
||||
try:
|
||||
taskId, data = self._imageQueue.get(True)
|
||||
except Exception as es:
|
||||
continue
|
||||
self._imageQueue.task_done()
|
||||
|
||||
if taskId < 0:
|
||||
break
|
||||
|
||||
q = QImage()
|
||||
try:
|
||||
if not data:
|
||||
return
|
||||
q.loadFromData(data)
|
||||
except Exception as es:
|
||||
Log.Error(es)
|
||||
finally:
|
||||
self.imageBack.emit(taskId, q)
|
||||
|
||||
def AddQImageTask(self, data, callBack=None, backParam=None, cleanFlag=None):
|
||||
self.taskId += 1
|
||||
info = QtHttpTask(self.taskId)
|
||||
info.callBack = callBack
|
||||
info.backParam = backParam
|
||||
self.imageTasks[self.taskId] = info
|
||||
if cleanFlag:
|
||||
info.cleanFlag = cleanFlag
|
||||
taskIds = self.imageFlagToIds.setdefault(cleanFlag, set())
|
||||
taskIds.add(self.taskId)
|
||||
self._imageQueue.put((self.taskId, data))
|
||||
return
|
||||
|
||||
def HandlerImageTask(self, taskId, data):
|
||||
try:
|
||||
info = self.imageTasks.get(taskId)
|
||||
if not info:
|
||||
Log.Warn("[Task] not find taskId:{}, {}".format(taskId, data))
|
||||
return
|
||||
assert isinstance(info, QtHttpTask)
|
||||
if info.cleanFlag:
|
||||
taskIds = self.imageFlagToIds.get(info.cleanFlag, set())
|
||||
taskIds.discard(info.taskId)
|
||||
if info.callBack:
|
||||
if info.backParam is None:
|
||||
info.callBack(data)
|
||||
else:
|
||||
info.callBack(data, info.backParam)
|
||||
del info.callBack
|
||||
del self.imageTasks[taskId]
|
||||
except Exception as es:
|
||||
Log.Error(es)
|
||||
|
||||
def CancelImageTasks(self, cleanFlag):
|
||||
taskIds = self.imageFlagToIds.get(cleanFlag, set())
|
||||
if not taskIds:
|
||||
return
|
||||
for taskId in taskIds:
|
||||
if taskId in self.imageTasks:
|
||||
del self.imageTasks[taskId]
|
||||
self.imageFlagToIds.pop(cleanFlag)
|
||||
|
||||
def Stop(self):
|
||||
self._imageQueue.put((-1, None))
|
||||
self._inQueue .put(-1)
|
||||
|
@ -1,6 +1,7 @@
|
||||
import logging
|
||||
import os
|
||||
import time
|
||||
import traceback
|
||||
|
||||
from conf import config
|
||||
|
||||
@ -51,6 +52,7 @@ class Log(object):
|
||||
|
||||
@staticmethod
|
||||
def Warn(data):
|
||||
Log.logger.warning(traceback.extract_stack()[-2])
|
||||
Log.logger.warning(data)
|
||||
|
||||
@staticmethod
|
||||
@ -68,4 +70,5 @@ class Log(object):
|
||||
# message += ' local params:{}\n'.format(frame.f_locals)
|
||||
# cur_tb = cur_tb.tb_next
|
||||
# Log.logger.error(message)
|
||||
Log.logger.warning(traceback.extract_stack()[-2])
|
||||
Log.logger.error(es, exc_info=True)
|
9
start.py
9
start.py
@ -4,6 +4,8 @@ import sys
|
||||
import os
|
||||
|
||||
# macOS 修复
|
||||
import time
|
||||
|
||||
from PySide2.QtGui import QPalette, QColor
|
||||
|
||||
from qss.qss import QssDataMgr
|
||||
@ -39,7 +41,11 @@ if __name__ == "__main__":
|
||||
Log.Init()
|
||||
app = QtWidgets.QApplication(sys.argv) # 建立application对象
|
||||
# app.addLibraryPath("./resources")
|
||||
main = BikaQtMainWindow(app)
|
||||
try:
|
||||
main = BikaQtMainWindow(app)
|
||||
except Exception as es:
|
||||
print(es)
|
||||
exit(-111)
|
||||
# main.setPalette(QPalette(QColor("#464646")))
|
||||
# main.setStyleSheet(QssDataMgr().GetData("darkblack"))
|
||||
main.show() # 显示窗体
|
||||
@ -48,4 +54,5 @@ if __name__ == "__main__":
|
||||
main.Close()
|
||||
if config.CanWaifu2x:
|
||||
waifu2x.stop()
|
||||
time.sleep(1)
|
||||
sys.exit(sts) # 运行程序
|
Loading…
Reference in New Issue
Block a user