Update specialwidget.py

Update specialwidget.py

Update specialwidget.py

Update dialog_savedgame.py

Update dialog_savedgame.py
This commit is contained in:
恍兮惚兮 2024-04-13 22:03:02 +08:00
parent a5d7a92fd8
commit c2af20424a
4 changed files with 230 additions and 58 deletions

View File

@ -1,6 +1,6 @@
import functools, time, qtawesome import functools, time, qtawesome
from datetime import datetime, timedelta from datetime import datetime, timedelta
from gui.specialwidget import ScrollFlow, chartwidget from gui.specialwidget import ScrollFlow, chartwidget, lazyscrollflow
from PyQt5.QtWidgets import ( from PyQt5.QtWidgets import (
QPushButton, QPushButton,
QDialog, QDialog,
@ -114,24 +114,7 @@ class ItemWidget(QWidget):
def setimg(self, pixmap): def setimg(self, pixmap):
self._img.setimg(pixmap) self._img.setimg(pixmap)
def connectexepath(self, exe): def __init__(self, exe, pixmap, file) -> None:
self.exe = exe
self.latershowfileexits(exe)
@threader
def latershowfileexits(self, exe):
if os.path.exists(exe):
self.maskshowfileexists.setStyleSheet(
"QLabel { background-color: rgba(255,255,255, 0); }"
)
else:
self.maskshowfileexists.setStyleSheet(
"QLabel { background-color: "
+ globalconfig["dialog_savegame_layout"]["onfilenoexistscolor"]
+ "; }"
)
def __init__(self, pixmap, file) -> None:
super().__init__() super().__init__()
self.itemw = globalconfig["dialog_savegame_layout"]["itemw"] self.itemw = globalconfig["dialog_savegame_layout"]["itemw"]
self.itemh = globalconfig["dialog_savegame_layout"]["itemh"] self.itemh = globalconfig["dialog_savegame_layout"]["itemh"]
@ -166,6 +149,17 @@ class ItemWidget(QWidget):
self._lb.setAlignment(Qt.AlignCenter) self._lb.setAlignment(Qt.AlignCenter)
layout.addWidget(self._lb) layout.addWidget(self._lb)
self.setLayout(layout) self.setLayout(layout)
self.exe = exe
if os.path.exists(exe):
self.maskshowfileexists.setStyleSheet(
"QLabel { background-color: rgba(255,255,255, 0); }"
)
else:
self.maskshowfileexists.setStyleSheet(
"QLabel { background-color: "
+ globalconfig["dialog_savegame_layout"]["onfilenoexistscolor"]
+ "; }"
)
class IMGWidget(QLabel): class IMGWidget(QLabel):
@ -199,7 +193,6 @@ class IMGWidget(QLabel):
elif globalconfig["imagewrapmode"] == 3: elif globalconfig["imagewrapmode"] == 3:
return size return size
@threader
def setimg(self, pixmap): def setimg(self, pixmap):
if type(pixmap) != QPixmap: if type(pixmap) != QPixmap:
pixmap = pixmap() pixmap = pixmap()
@ -1505,10 +1498,10 @@ class dialog_savedgame_new(saveposwindow):
self.formLayout.removeWidget(self.flow) self.formLayout.removeWidget(self.flow)
self.flow.deleteLater() self.flow.deleteLater()
self.idxsave.clear() self.idxsave.clear()
self.flow = ScrollFlow() self.flow = lazyscrollflow()
self.flow.bgclicked.connect(ItemWidget.clearfocus) self.flow.bgclicked.connect(ItemWidget.clearfocus)
self.formLayout.insertWidget(self.formLayout.count() - 1, self.flow) self.formLayout.insertWidget(self.formLayout.count() - 1, self.flow)
QApplication.processEvents()
for k in savehook_new_list: for k in savehook_new_list:
if newtags != self.currtags: if newtags != self.currtags:
break break
@ -1542,7 +1535,9 @@ class dialog_savedgame_new(saveposwindow):
if notshow: if notshow:
continue continue
self.newline(k) self.newline(k)
self.flow.refreshscroll()
QApplication.processEvents()
self.flow.resizeandshow()
def showmenu(self, p): def showmenu(self, p):
menu = QMenu(self) menu = QMenu(self)
@ -1596,7 +1591,7 @@ class dialog_savedgame_new(saveposwindow):
self.currtags = tuple() self.currtags = tuple()
self.tagswidget.tagschanged.connect(self.tagschanged) self.tagswidget.tagschanged.connect(self.tagschanged)
formLayout.addWidget(self.tagswidget) formLayout.addWidget(self.tagswidget)
self.flow = ScrollFlow() self.flow = lazyscrollflow()
self.setContextMenuPolicy(Qt.CustomContextMenu) self.setContextMenuPolicy(Qt.CustomContextMenu)
self.customContextMenuRequested.connect(self.showmenu) self.customContextMenuRequested.connect(self.showmenu)
formLayout.addWidget(self.flow) formLayout.addWidget(self.flow)
@ -1678,11 +1673,9 @@ class dialog_savedgame_new(saveposwindow):
return _pix return _pix
def getagameitem(self, k): def getagameitem(self, k):
gameitem = ItemWidget( gameitem = ItemWidget(
functools.partial(self._getpixfunction, k), savehook_new_data[k]["title"] k, functools.partial(self._getpixfunction, k), savehook_new_data[k]["title"]
) )
gameitem.connectexepath(k)
gameitem.doubleclicked.connect(self.startgame) gameitem.doubleclicked.connect(self.startgame)
gameitem.focuschanged.connect(self.itemfocuschanged) gameitem.focuschanged.connect(self.itemfocuschanged)
return gameitem return gameitem
@ -1690,16 +1683,18 @@ class dialog_savedgame_new(saveposwindow):
def newline(self, k, first=False): def newline(self, k, first=False):
checkifnewgame(k) checkifnewgame(k)
itemw = globalconfig["dialog_savegame_layout"]["itemw"]
itemh = globalconfig["dialog_savegame_layout"]["itemh"]
if first: if first:
self.flow.insertwidget(0, self.getagameitem(k)) self.flow.insertwidget(
0, (functools.partial(self.getagameitem, k), QSize(itemw, itemh))
)
self.idxsave.insert(0, k) self.idxsave.insert(0, k)
else: else:
itemw = globalconfig["dialog_savegame_layout"]["itemw"] self.flow.addwidget(
itemh = globalconfig["dialog_savegame_layout"]["itemh"] (functools.partial(self.getagameitem, k), QSize(itemw, itemh))
self.flow.addwidgetlazy(
functools.partial(self.getagameitem, k), QSize(itemw, itemh)
) )
# self.flow.addwidget( self.getagameitem(k)) # self.flow.addwidget( self.getagameitem(k))
self.idxsave.append(k) self.idxsave.append(k)

View File

@ -1,6 +1,14 @@
from PyQt5.QtWidgets import QWidget, QSizePolicy, QLabel, QScrollArea,QApplication from PyQt5.QtWidgets import QWidget, QSizePolicy, QLabel, QScrollArea, QApplication
from PyQt5.QtGui import QMouseEvent, QPainter, QPen, QFont, QFontMetrics,QRegion from PyQt5.QtGui import (
from PyQt5.QtCore import Qt,QEvent QMouseEvent,
QPainter,
QPen,
QFont,
QFontMetrics,
QRegion,
QResizeEvent,
)
from PyQt5.QtCore import Qt, QEvent
from PyQt5.QtWidgets import ( from PyQt5.QtWidgets import (
QSpacerItem, QSpacerItem,
QWidgetItem, QWidgetItem,
@ -9,6 +17,8 @@ from PyQt5.QtCore import QPoint, QRect, QSize, Qt, pyqtSignal
from PyQt5.QtWidgets import QLayout from PyQt5.QtWidgets import QLayout
from traceback import print_exc from traceback import print_exc
from myutils.wrapper import trypass from myutils.wrapper import trypass
import threading
class chartwidget(QWidget): class chartwidget(QWidget):
def __init__(self) -> None: def __init__(self) -> None:
@ -119,10 +129,12 @@ class chartwidget(QWidget):
class ScrollArea(QScrollArea): class ScrollArea(QScrollArea):
scrolled=pyqtSignal(QRect) scrolled = pyqtSignal(QRect)
def __init__(self, parent=None): def __init__(self, parent=None):
super().__init__(parent) super().__init__(parent)
self.verticalScrollBar().valueChanged.connect(self.handleScroll) self.verticalScrollBar().valueChanged.connect(self.handleScroll)
def handleScroll(self, value): def handleScroll(self, value):
viewport_rect = self.viewport().rect() viewport_rect = self.viewport().rect()
@ -136,17 +148,22 @@ class ScrollArea(QScrollArea):
visible_rect = QRect(x, y, width, height) visible_rect = QRect(x, y, width, height)
self.scrolled.emit(visible_rect) self.scrolled.emit(visible_rect)
class lazynotify(QWidget): class lazynotify(QWidget):
def __init__(self,getrealwid) -> None: def __init__(self, getrealwid) -> None:
super().__init__() super().__init__()
self.done=False self.done = False
self.getrealwid=getrealwid self.getrealwid = getrealwid
def do(self): def do(self):
wid=self.getrealwid() wid = self.getrealwid()
wid.setParent(self) wid.setParent(self)
wid.adjustSize() wid.adjustSize()
wid.setVisible(True) wid.setVisible(True)
class ScrollFlow(QWidget): class ScrollFlow(QWidget):
bgclicked = pyqtSignal() bgclicked = pyqtSignal()
@ -163,8 +180,8 @@ class ScrollFlow(QWidget):
self.listWidget = qw(self) self.listWidget = qw(self)
# self.listWidget.setFixedWidth(600) # self.listWidget.setFixedWidth(600)
self.lazyitems=[] self.lazyitems = []
self.lazydoneidx=[] self.lazydoneidx = []
self.l = FlowLayout() self.l = FlowLayout()
self.listWidget.setLayout(self.l) self.listWidget.setLayout(self.l)
@ -173,15 +190,16 @@ class ScrollFlow(QWidget):
self.qscrollarea.setWidgetResizable(True) self.qscrollarea.setWidgetResizable(True)
self.qscrollarea.setWidget(self.listWidget) self.qscrollarea.setWidget(self.listWidget)
self.qscrollarea.scrolled.connect(self.doshowlazywidget) self.qscrollarea.scrolled.connect(self.doshowlazywidget)
@trypass @trypass
def doshowlazywidget(self,region:QRect): def doshowlazywidget(self, region: QRect):
for i,widget in enumerate(self.lazyitems): for i, widget in enumerate(self.lazyitems):
if i in self.lazydoneidx: if i in self.lazydoneidx:
continue continue
widget_rect = widget.geometry() #有可能已被delete必须try widget_rect = widget.geometry() # 有可能已被delete必须try
#print(widget_rect) # print(widget_rect)
if region.intersects(widget_rect): if region.intersects(widget_rect):
#print(i,widget_rect) # print(i,widget_rect)
self.lazydoneidx.append(i) self.lazydoneidx.append(i)
widget.do() widget.do()
QApplication.processEvents() QApplication.processEvents()
@ -189,25 +207,31 @@ class ScrollFlow(QWidget):
def refreshscroll(self): def refreshscroll(self):
QApplication.processEvents() QApplication.processEvents()
self.doshowlazywidget(self.geometry()) self.doshowlazywidget(self.geometry())
@trypass @trypass
def addwidgetlazy(self,wid,size): def addwidgetlazy(self, wid, size):
wid=lazynotify(wid) wid = lazynotify(wid)
self.lazyitems.append(wid) self.lazyitems.append(wid)
wid.setFixedSize(size) wid.setFixedSize(size)
self.l.addWidget(wid) self.l.addWidget(wid)
@trypass @trypass
def addwidget(self, wid): def addwidget(self, wid):
self.l.addWidget(wid) self.l.addWidget(wid)
@trypass @trypass
def insertwidget(self, idx, wid): def insertwidget(self, idx, wid):
self.l.insertWidget(idx, wid) self.l.insertWidget(idx, wid)
@trypass @trypass
def removeidx(self, index): def removeidx(self, index):
_ = self.l.takeAt(index) _ = self.l.takeAt(index)
_.widget().hide() _.widget().hide()
@trypass @trypass
def setfocus(self, idx): def setfocus(self, idx):
self.widget(idx).setFocus() self.widget(idx).setFocus()
@trypass @trypass
def widget(self, idx): def widget(self, idx):
idx = min(idx, len(self.l._item_list) - 1) idx = min(idx, len(self.l._item_list) - 1)
@ -286,7 +310,6 @@ class FlowLayout(QLayout):
x = effective_rect.x() x = effective_rect.x()
y = effective_rect.y() y = effective_rect.y()
line_height = 0 line_height = 0
for item in self._item_list: for item in self._item_list:
wid = item.widget() wid = item.widget()
@ -316,3 +339,152 @@ class FlowLayout(QLayout):
new_height = y + line_height - rect.y() new_height = y + line_height - rect.y()
self.heightChanged.emit(new_height) self.heightChanged.emit(new_height)
return new_height return new_height
class lazyscrollflow(QWidget):
bgclicked = pyqtSignal()
def mousePressEvent(self, _2) -> None:
self.bgclicked.emit()
def __init__(self):
super().__init__()
self.widgets = []
self.fakegeos = []
self._spacing = 6
self._margin = 9
self.lock = threading.Lock()
self.internalwid = QWidget(self)
self.qscrollarea = ScrollArea(self)
self.qscrollarea.setWidgetResizable(True)
self.qscrollarea.setWidget(self.internalwid)
self.qscrollarea.scrolled.connect(self.doshowlazywidget)
def resizeEvent(self, a0: QResizeEvent) -> None:
self.qscrollarea.resize(self.size())
self.resizeandshow()
return super().resizeEvent(a0)
@trypass
def doshowlazywidget(self, region: QRect):
needdos = []
with self.lock:
for i, geo in enumerate(self.fakegeos):
if isinstance(self.widgets[i], QWidget):
continue
if not region.intersects(geo):
continue
widfunc, _ = self.widgets[i]
if not widfunc:
continue
self.widgets[i] = (None, _)
needdos.append((i, widfunc))
for i, widfunc in needdos:
try:
with self.lock:
widfunc = widfunc()
widfunc.setParent(self.internalwid)
widfunc.adjustSize()
widfunc.setVisible(True)
widfunc.setGeometry(self.fakegeos[i])
self.widgets[i] = widfunc
QApplication.processEvents()
except:
pass
@trypass
def resizeandshow(self):
self.fakeresize()
self.doshowlazywidget(self.internalwid.visibleRegion())
def addwidget(self, widfunc):
self.insertwidget(-1, widfunc)
@trypass
def insertwidget(self, idx, widfunc):
refresh = True
with self.lock:
if idx == -1:
refresh = False
idx = len(self.widgets)
self.widgets.insert(idx, widfunc)
self.fakegeos.insert(idx, QRect())
if isinstance(widfunc, QWidget):
widfunc.setParent(self.internalwid)
widfunc.adjustSize()
widfunc.setVisible(True)
if refresh:
self.resizeandshow()
@trypass
def removeidx(self, idx):
with self.lock:
if idx >= 0 and idx < len(self.widgets):
w = self.widgets[idx]
w.setParent(None)
w.deleteLater()
self.widgets.pop(idx)
self.fakegeos.pop(idx)
self.resizeandshow()
@trypass
def setfocus(self, idx):
self.widget(idx).setFocus()
@trypass
def widget(self, idx):
with self.lock:
if idx > 0 or idx < len(self.widgets):
return self.widgets[idx]
else:
return None
def spacing(self):
return self._spacing
def fakeresize(self):
if self.qscrollarea.verticalScrollBar().isVisible():
scrollw = self.qscrollarea.verticalScrollBar().width()
else:
scrollw = 0
with self.lock:
# m = self.contentsMargins()
rect = QRect()
rect.setSize(self.size())
effective_rect = rect.adjusted(
self._margin, self._margin, -self._margin, -self._margin
) # (+m.left(), +m.top(), -m.right(), -m.bottom())
x = effective_rect.x()
y = effective_rect.y()
line_height = 0
for i, wid in enumerate(self.widgets):
space_x = self.spacing()
space_y = self.spacing()
if isinstance(wid, QWidget):
sz = wid.size()
resize = True
else:
_, sz = wid
resize = False
next_x = x + sz.width() + space_x
if next_x > effective_rect.right() - scrollw and line_height > 0:
x = effective_rect.x()
y = y + line_height + space_y
next_x = x + sz.width() + space_x
line_height = 0
if resize:
wid.setGeometry(QRect(QPoint(x, y), sz))
self.fakegeos[i] = QRect(QPoint(x, y), sz)
x = next_x
line_height = max(line_height, sz.height())
new_height = y + line_height - rect.y() + self._margin
self.internalwid.setFixedHeight(new_height)
return new_height

View File

@ -115,7 +115,13 @@ def dispatachtask(gamepath):
def everymethodsthread(): def everymethodsthread():
while True: while True:
gamepath, searchargs = searchvndbqueue.get() _ = searchvndbqueue.get()
if isinstance(_, tuple):
gamepath, searchargs = _
else:
gamepath = _
dispatachtask(gamepath)
continue
if checkneed(gamepath) == False: if checkneed(gamepath) == False:
continue continue
@ -175,8 +181,7 @@ def checkifnewgame(gamepath, title=None):
savehook_new_list.insert(0, gamepath) savehook_new_list.insert(0, gamepath)
if gamepath not in savehook_new_data: if gamepath not in savehook_new_data:
savehook_new_data[gamepath] = getdefaultsavehook(gamepath, title) savehook_new_data[gamepath] = getdefaultsavehook(gamepath, title)
if gamepath != "0": searchvndbqueue.put(gamepath)
dispatachtask(gamepath)
kanjichs2ja = str.maketrans(static_data["kanjichs2ja"]) kanjichs2ja = str.maketrans(static_data["kanjichs2ja"])

View File

@ -1,5 +1,5 @@
{ {
"version":"v2.45.3", "version":"v2.45.4",
"themes":{ "themes":{
"dark":[ "dark":[
{"file":"dark1.qss","name":"PyQtDarkTheme"}, {"file":"dark1.qss","name":"PyQtDarkTheme"},