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

View File

@ -1,6 +1,14 @@
from PyQt5.QtWidgets import QWidget, QSizePolicy, QLabel, QScrollArea,QApplication
from PyQt5.QtGui import QMouseEvent, QPainter, QPen, QFont, QFontMetrics,QRegion
from PyQt5.QtCore import Qt,QEvent
from PyQt5.QtWidgets import QWidget, QSizePolicy, QLabel, QScrollArea, QApplication
from PyQt5.QtGui import (
QMouseEvent,
QPainter,
QPen,
QFont,
QFontMetrics,
QRegion,
QResizeEvent,
)
from PyQt5.QtCore import Qt, QEvent
from PyQt5.QtWidgets import (
QSpacerItem,
QWidgetItem,
@ -9,6 +17,8 @@ from PyQt5.QtCore import QPoint, QRect, QSize, Qt, pyqtSignal
from PyQt5.QtWidgets import QLayout
from traceback import print_exc
from myutils.wrapper import trypass
import threading
class chartwidget(QWidget):
def __init__(self) -> None:
@ -119,10 +129,12 @@ class chartwidget(QWidget):
class ScrollArea(QScrollArea):
scrolled=pyqtSignal(QRect)
scrolled = pyqtSignal(QRect)
def __init__(self, parent=None):
super().__init__(parent)
self.verticalScrollBar().valueChanged.connect(self.handleScroll)
def handleScroll(self, value):
viewport_rect = self.viewport().rect()
@ -136,17 +148,22 @@ class ScrollArea(QScrollArea):
visible_rect = QRect(x, y, width, height)
self.scrolled.emit(visible_rect)
class lazynotify(QWidget):
def __init__(self,getrealwid) -> None:
def __init__(self, getrealwid) -> None:
super().__init__()
self.done=False
self.getrealwid=getrealwid
self.done = False
self.getrealwid = getrealwid
def do(self):
wid=self.getrealwid()
wid = self.getrealwid()
wid.setParent(self)
wid.adjustSize()
wid.setVisible(True)
class ScrollFlow(QWidget):
bgclicked = pyqtSignal()
@ -163,8 +180,8 @@ class ScrollFlow(QWidget):
self.listWidget = qw(self)
# self.listWidget.setFixedWidth(600)
self.lazyitems=[]
self.lazydoneidx=[]
self.lazyitems = []
self.lazydoneidx = []
self.l = FlowLayout()
self.listWidget.setLayout(self.l)
@ -173,15 +190,16 @@ class ScrollFlow(QWidget):
self.qscrollarea.setWidgetResizable(True)
self.qscrollarea.setWidget(self.listWidget)
self.qscrollarea.scrolled.connect(self.doshowlazywidget)
@trypass
def doshowlazywidget(self,region:QRect):
for i,widget in enumerate(self.lazyitems):
def doshowlazywidget(self, region: QRect):
for i, widget in enumerate(self.lazyitems):
if i in self.lazydoneidx:
continue
widget_rect = widget.geometry() #有可能已被delete必须try
#print(widget_rect)
widget_rect = widget.geometry() # 有可能已被delete必须try
# print(widget_rect)
if region.intersects(widget_rect):
#print(i,widget_rect)
# print(i,widget_rect)
self.lazydoneidx.append(i)
widget.do()
QApplication.processEvents()
@ -189,25 +207,31 @@ class ScrollFlow(QWidget):
def refreshscroll(self):
QApplication.processEvents()
self.doshowlazywidget(self.geometry())
@trypass
def addwidgetlazy(self,wid,size):
wid=lazynotify(wid)
def addwidgetlazy(self, wid, size):
wid = lazynotify(wid)
self.lazyitems.append(wid)
wid.setFixedSize(size)
self.l.addWidget(wid)
@trypass
def addwidget(self, wid):
self.l.addWidget(wid)
@trypass
def insertwidget(self, idx, wid):
self.l.insertWidget(idx, wid)
@trypass
def removeidx(self, index):
_ = self.l.takeAt(index)
_.widget().hide()
@trypass
def setfocus(self, idx):
self.widget(idx).setFocus()
@trypass
def widget(self, idx):
idx = min(idx, len(self.l._item_list) - 1)
@ -286,7 +310,6 @@ class FlowLayout(QLayout):
x = effective_rect.x()
y = effective_rect.y()
line_height = 0
for item in self._item_list:
wid = item.widget()
@ -316,3 +339,152 @@ class FlowLayout(QLayout):
new_height = y + line_height - rect.y()
self.heightChanged.emit(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():
while True:
gamepath, searchargs = searchvndbqueue.get()
_ = searchvndbqueue.get()
if isinstance(_, tuple):
gamepath, searchargs = _
else:
gamepath = _
dispatachtask(gamepath)
continue
if checkneed(gamepath) == False:
continue
@ -175,8 +181,7 @@ def checkifnewgame(gamepath, title=None):
savehook_new_list.insert(0, gamepath)
if gamepath not in savehook_new_data:
savehook_new_data[gamepath] = getdefaultsavehook(gamepath, title)
if gamepath != "0":
dispatachtask(gamepath)
searchvndbqueue.put(gamepath)
kanjichs2ja = str.maketrans(static_data["kanjichs2ja"])

View File

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