impr: update when database changed, instead of showEvent

This commit is contained in:
283375 2023-09-17 00:40:08 +08:00
parent 51e713d4c6
commit b5aefb5f28
Signed by: 283375
SSH Key Fingerprint: SHA256:UcX0qg6ZOSDOeieKPGokA5h7soykG61nz2uxuQgVLSk
4 changed files with 35 additions and 14 deletions

View File

@ -1,6 +1,6 @@
from typing import Type from typing import Type
from PySide6.QtCore import QUrl from PySide6.QtCore import QObject, QUrl, Signal
from sqlalchemy import Engine from sqlalchemy import Engine
from sqlalchemy import create_engine as sa_create_engine from sqlalchemy import create_engine as sa_create_engine
from sqlalchemy.pool import NullPool, Pool from sqlalchemy.pool import NullPool, Pool
@ -9,3 +9,10 @@ from sqlalchemy.pool import NullPool, Pool
def create_engine(_url: str | QUrl, pool: Type[Pool] = NullPool) -> Engine: def create_engine(_url: str | QUrl, pool: Type[Pool] = NullPool) -> Engine:
url = _url.toString() if isinstance(_url, QUrl) else _url url = _url.toString() if isinstance(_url, QUrl) else _url
return sa_create_engine(url, poolclass=pool) return sa_create_engine(url, poolclass=pool)
class DatabaseUpdateSignals(QObject):
songDataUpdated = Signal()
databaseUpdateSignals = DatabaseUpdateSignals()

View File

@ -4,10 +4,10 @@ from arcaea_offline.database import Database
from arcaea_offline.models import Chart from arcaea_offline.models import Chart
from arcaea_offline.utils.rating import rating_class_to_text from arcaea_offline.utils.rating import rating_class_to_text
from PySide6.QtCore import Signal, Slot from PySide6.QtCore import Signal, Slot
from PySide6.QtGui import QShowEvent
from PySide6.QtWidgets import QWidget from PySide6.QtWidgets import QWidget
from ui.designer.components.chartSelector_ui import Ui_ChartSelector from ui.designer.components.chartSelector_ui import Ui_ChartSelector
from ui.extends.shared.database import databaseUpdateSignals
from ui.extends.shared.language import LanguageChangeEventFilter from ui.extends.shared.language import LanguageChangeEventFilter
logger = logging.getLogger(__name__) logger = logging.getLogger(__name__)
@ -30,6 +30,12 @@ class ChartSelector(Ui_ChartSelector, QWidget):
self.songIdSelector.valueChanged.connect(self.valueChanged) self.songIdSelector.valueChanged.connect(self.valueChanged)
self.ratingClassSelector.valueChanged.connect(self.valueChanged) self.ratingClassSelector.valueChanged.connect(self.valueChanged)
# handle `songIdSelector.updateDatabase` by this component
databaseUpdateSignals.songDataUpdated.disconnect(
self.songIdSelector.updateDatabase
)
databaseUpdateSignals.songDataUpdated.connect(self.updateDatabase)
def value(self): def value(self):
songId = self.songIdSelector.songId() songId = self.songIdSelector.songId()
ratingClass = self.ratingClassSelector.value() ratingClass = self.ratingClassSelector.value()
@ -38,13 +44,15 @@ class ChartSelector(Ui_ChartSelector, QWidget):
return self.db.get_chart(songId, ratingClass) return self.db.get_chart(songId, ratingClass)
return None return None
def showEvent(self, event: QShowEvent): def updateDatabase(self):
# remember selection and restore later # remember selection and restore later
ratingClass = self.ratingClassSelector.value() ratingClass = self.ratingClassSelector.value()
# wait `songIdSelector` finish
self.songIdSelector.updateDatabase()
if ratingClass is not None: if ratingClass is not None:
self.ratingClassSelector.select(ratingClass) self.ratingClassSelector.select(ratingClass)
return super().showEvent(event)
@Slot() @Slot()
def updateResultLabel(self): def updateResultLabel(self):

View File

@ -5,11 +5,11 @@ from typing import Literal
from arcaea_offline.database import Database from arcaea_offline.database import Database
from arcaea_offline.models import Chart from arcaea_offline.models import Chart
from PySide6.QtCore import QModelIndex, Qt, Signal, Slot from PySide6.QtCore import QModelIndex, Qt, Signal, Slot
from PySide6.QtGui import QShowEvent
from PySide6.QtWidgets import QCompleter, QWidget from PySide6.QtWidgets import QCompleter, QWidget
from ui.designer.components.songIdSelector_ui import Ui_SongIdSelector from ui.designer.components.songIdSelector_ui import Ui_SongIdSelector
from ui.extends.components.songIdSelector import SearchCompleterModel from ui.extends.components.songIdSelector import SearchCompleterModel
from ui.extends.shared.database import databaseUpdateSignals
from ui.extends.shared.delegates.descriptionDelegate import DescriptionDelegate from ui.extends.shared.delegates.descriptionDelegate import DescriptionDelegate
from ui.extends.shared.language import LanguageChangeEventFilter from ui.extends.shared.language import LanguageChangeEventFilter
@ -40,6 +40,8 @@ class SongIdSelector(Ui_SongIdSelector, QWidget):
lambda: self.quickSwitchSelection("next", "package") lambda: self.quickSwitchSelection("next", "package")
) )
databaseUpdateSignals.songDataUpdated.connect(self.updateDatabase)
self.fillPackComboBox() self.fillPackComboBox()
self.packComboBox.setCurrentIndex(-1) self.packComboBox.setCurrentIndex(-1)
self.songIdComboBox.setCurrentIndex(-1) self.songIdComboBox.setCurrentIndex(-1)
@ -93,8 +95,7 @@ class SongIdSelector(Ui_SongIdSelector, QWidget):
self.packComboBox.setCurrentIndex(-1) self.packComboBox.setCurrentIndex(-1)
self.songIdComboBox.setCurrentIndex(-1) self.songIdComboBox.setCurrentIndex(-1)
def showEvent(self, event: QShowEvent): def updateDatabase(self):
# update database results when widget visible
self.searchCompleterModel.updateSearcherSongs() self.searchCompleterModel.updateSearcherSongs()
# remember selection and restore later # remember selection and restore later
@ -107,7 +108,6 @@ class SongIdSelector(Ui_SongIdSelector, QWidget):
self.selectPack(pack) self.selectPack(pack)
if songId: if songId:
self.selectSongId(songId) self.selectSongId(songId)
return super().showEvent(event)
def fillPackComboBox(self): def fillPackComboBox(self):
self.packComboBox.clear() self.packComboBox.clear()

View File

@ -12,10 +12,12 @@ from arcaea_offline.external.arcaea import (
) )
from arcaea_offline.external.arcaea.common import ArcaeaParser from arcaea_offline.external.arcaea.common import ArcaeaParser
from arcaea_offline.external.arcsong import ArcsongDbParser from arcaea_offline.external.arcsong import ArcsongDbParser
from arcaea_offline.models import Difficulty, Pack, Song
from PySide6.QtCore import QDir, Slot from PySide6.QtCore import QDir, Slot
from PySide6.QtWidgets import QFileDialog, QMessageBox, QWidget from PySide6.QtWidgets import QFileDialog, QMessageBox, QWidget
from ui.designer.tabs.tabDb.tabDb_Manage_ui import Ui_TabDb_Manage from ui.designer.tabs.tabDb.tabDb_Manage_ui import Ui_TabDb_Manage
from ui.extends.shared.database import databaseUpdateSignals
logger = logging.getLogger(__name__) logger = logging.getLogger(__name__)
@ -40,6 +42,7 @@ class TabDb_Manage(Ui_TabDb_Manage, QWidget):
with db.sessionmaker() as session: with db.sessionmaker() as session:
parser.write_database(session) parser.write_database(session)
session.commit() session.commit()
databaseUpdateSignals.songDataUpdated.emit()
QMessageBox.information(self, None, "OK") QMessageBox.information(self, None, "OK")
except Exception as e: except Exception as e:
logging.exception("Sync arcsong.db error") logging.exception("Sync arcsong.db error")
@ -47,28 +50,31 @@ class TabDb_Manage(Ui_TabDb_Manage, QWidget):
self, "Sync Error", "\n".join(traceback.format_exception(e)) self, "Sync Error", "\n".join(traceback.format_exception(e))
) )
def importFromArcaeaParser(self, parser: ArcaeaParser, logName, path) -> int: def importFromArcaeaParser(
self, parser: ArcaeaParser, instance, logName, path
) -> int:
# extracted by sourcery # extracted by sourcery
db = Database() db = Database()
with db.sessionmaker() as session: with db.sessionmaker() as session:
parser.write_database(session) parser.write_database(session)
session.commit() session.commit()
itemNum = len(parser.parse()) databaseUpdateSignals.songDataUpdated.emit()
itemNum = len([item for item in parser.parse() if isinstance(item, instance)])
logger.info(f"updated {itemNum} {logName} from {path}") logger.info(f"updated {itemNum} {logName} from {path}")
return itemNum return itemNum
def importPacklist(self, packlistPath): def importPacklist(self, packlistPath):
packlistParser = PacklistParser(packlistPath) packlistParser = PacklistParser(packlistPath)
return self.importFromArcaeaParser(packlistParser, "packs", packlistPath) return self.importFromArcaeaParser(packlistParser, Pack, "packs", packlistPath)
def importSonglist(self, songlistPath): def importSonglist(self, songlistPath):
songlistParser = SonglistParser(songlistPath) songlistParser = SonglistParser(songlistPath)
return self.importFromArcaeaParser(songlistParser, "songs", songlistPath) return self.importFromArcaeaParser(songlistParser, Song, "songs", songlistPath)
def importSonglistDifficulties(self, songlistPath): def importSonglistDifficulties(self, songlistPath):
songlistDifficultiesParser = SonglistDifficultiesParser(songlistPath) songlistDifficultiesParser = SonglistDifficultiesParser(songlistPath)
return self.importFromArcaeaParser( return self.importFromArcaeaParser(
songlistDifficultiesParser, "difficulties", songlistPath songlistDifficultiesParser, Difficulty, "difficulties", songlistPath
) )
@Slot() @Slot()
@ -190,7 +196,7 @@ class TabDb_Manage(Ui_TabDb_Manage, QWidget):
exportLocation, _filter = QFileDialog.getSaveFileName( exportLocation, _filter = QFileDialog.getSaveFileName(
self, self,
"Save your scores to...", "Export arcsong.json",
QDir.current().filePath("arcsong.json"), QDir.current().filePath("arcsong.json"),
"JSON (*.json);;*", "JSON (*.json);;*",
) )