fix(ui): prevent segfault by validating widget existence in async callbacks
All checks were successful
Code check / Check code (push) Successful in 1m26s
All checks were successful
Code check / Check code (push) Successful in 1m26s
Signed-off-by: Boris Yumankulov <boria138@altlinux.org>
This commit is contained in:
@@ -2314,6 +2314,7 @@ class MainWindow(QMainWindow):
|
|||||||
|
|
||||||
def openGameDetailPage(self, name, description, cover_path=None, appid="", exec_line="", controller_support="", last_launch="", formatted_playtime="", protondb_tier="", game_source="", anticheat_status=""):
|
def openGameDetailPage(self, name, description, cover_path=None, appid="", exec_line="", controller_support="", last_launch="", formatted_playtime="", protondb_tier="", game_source="", anticheat_status=""):
|
||||||
detailPage = QWidget()
|
detailPage = QWidget()
|
||||||
|
if not hasattr(self, '_animations'):
|
||||||
self._animations = {}
|
self._animations = {}
|
||||||
imageLabel = QLabel()
|
imageLabel = QLabel()
|
||||||
imageLabel.setFixedSize(300, 450)
|
imageLabel.setFixedSize(300, 450)
|
||||||
@@ -2322,25 +2323,34 @@ class MainWindow(QMainWindow):
|
|||||||
|
|
||||||
# Функция загрузки изображения и обновления стилей
|
# Функция загрузки изображения и обновления стилей
|
||||||
def load_image_and_restore_effect():
|
def load_image_and_restore_effect():
|
||||||
if not detailPage or detailPage.isHidden():
|
# Check if detail page still exists and is valid
|
||||||
logger.warning("Detail page is None or hidden, skipping image load")
|
if not detailPage or detailPage.isHidden() or detailPage.parent() is None:
|
||||||
|
logger.warning("Detail page is None, hidden, or no longer valid, skipping image load")
|
||||||
return
|
return
|
||||||
|
|
||||||
|
try:
|
||||||
detailPage.setWindowOpacity(1.0)
|
detailPage.setWindowOpacity(1.0)
|
||||||
|
except RuntimeError:
|
||||||
|
logger.warning("Detail page already deleted, skipping opacity set")
|
||||||
|
return
|
||||||
|
|
||||||
if cover_path:
|
if cover_path:
|
||||||
def on_pixmap_ready(pixmap):
|
def on_pixmap_ready(pixmap):
|
||||||
if not detailPage or detailPage.isHidden():
|
# Check if detail page still exists and is valid
|
||||||
logger.warning("Detail page is None or hidden, skipping pixmap update")
|
if not detailPage or detailPage.isHidden() or detailPage.parent() is None:
|
||||||
|
logger.warning("Detail page is None, hidden, or no longer valid, skipping pixmap update")
|
||||||
return
|
return
|
||||||
|
try:
|
||||||
rounded = round_corners(pixmap, 10)
|
rounded = round_corners(pixmap, 10)
|
||||||
imageLabel.setPixmap(rounded)
|
imageLabel.setPixmap(rounded)
|
||||||
logger.debug("Pixmap set for imageLabel")
|
logger.debug("Pixmap set for imageLabel")
|
||||||
|
|
||||||
def on_palette_ready(palette):
|
def on_palette_ready(palette):
|
||||||
if not detailPage or detailPage.isHidden():
|
# Check if detail page still exists and is valid
|
||||||
logger.warning("Detail page is None or hidden, skipping palette update")
|
if not detailPage or detailPage.isHidden() or detailPage.parent() is None:
|
||||||
|
logger.warning("Detail page is None, hidden, or no longer valid, skipping palette update")
|
||||||
return
|
return
|
||||||
|
try:
|
||||||
dark_palette = [self.darkenColor(color, factor=200) for color in palette]
|
dark_palette = [self.darkenColor(color, factor=200) for color in palette]
|
||||||
stops = ",\n".join(
|
stops = ",\n".join(
|
||||||
[f"stop:{i/(len(dark_palette)-1):.2f} {dark_palette[i].name()}" for i in range(len(dark_palette))]
|
[f"stop:{i/(len(dark_palette)-1):.2f} {dark_palette[i].name()}" for i in range(len(dark_palette))]
|
||||||
@@ -2348,12 +2358,18 @@ class MainWindow(QMainWindow):
|
|||||||
detailPage.setStyleSheet(self.theme.detail_page_style(stops))
|
detailPage.setStyleSheet(self.theme.detail_page_style(stops))
|
||||||
detailPage.update()
|
detailPage.update()
|
||||||
logger.debug("Stylesheet updated with palette")
|
logger.debug("Stylesheet updated with palette")
|
||||||
|
except RuntimeError:
|
||||||
|
logger.warning("Detail page already deleted, skipping palette stylesheet update")
|
||||||
self.getColorPalette_async(cover_path, num_colors=5, callback=on_palette_ready)
|
self.getColorPalette_async(cover_path, num_colors=5, callback=on_palette_ready)
|
||||||
|
except RuntimeError:
|
||||||
|
logger.warning("Detail page already deleted, skipping pixmap update")
|
||||||
load_pixmap_async(cover_path, 300, 450, on_pixmap_ready)
|
load_pixmap_async(cover_path, 300, 450, on_pixmap_ready)
|
||||||
else:
|
else:
|
||||||
|
try:
|
||||||
detailPage.setStyleSheet(self.theme.DETAIL_PAGE_NO_COVER_STYLE)
|
detailPage.setStyleSheet(self.theme.DETAIL_PAGE_NO_COVER_STYLE)
|
||||||
detailPage.update()
|
detailPage.update()
|
||||||
|
except RuntimeError:
|
||||||
|
logger.warning("Detail page already deleted, skipping no-cover stylesheet update")
|
||||||
|
|
||||||
def cleanup_animation():
|
def cleanup_animation():
|
||||||
if detailPage in self._animations:
|
if detailPage in self._animations:
|
||||||
@@ -2594,6 +2610,9 @@ class MainWindow(QMainWindow):
|
|||||||
return
|
return
|
||||||
if not self._current_detail_page or self._current_detail_page.isHidden() or not self._current_detail_page.parent():
|
if not self._current_detail_page or self._current_detail_page.isHidden() or not self._current_detail_page.parent():
|
||||||
return
|
return
|
||||||
|
# Additional check: make sure the detail page in the stacked widget is still our current detail page
|
||||||
|
if self.stackedWidget.currentWidget() != self._current_detail_page and self._current_detail_page not in [self.stackedWidget.widget(i) for i in range(self.stackedWidget.count())]:
|
||||||
|
return
|
||||||
|
|
||||||
if results:
|
if results:
|
||||||
game = results[0] # Берем первый результат
|
game = results[0] # Берем первый результат
|
||||||
@@ -2617,6 +2636,7 @@ class MainWindow(QMainWindow):
|
|||||||
has_data = False
|
has_data = False
|
||||||
|
|
||||||
if main_story_time is not None:
|
if main_story_time is not None:
|
||||||
|
try:
|
||||||
mainStoryTitle = QLabel(_("MAIN STORY"))
|
mainStoryTitle = QLabel(_("MAIN STORY"))
|
||||||
mainStoryTitle.setStyleSheet(self.theme.LAST_LAUNCH_TITLE_STYLE)
|
mainStoryTitle.setStyleSheet(self.theme.LAST_LAUNCH_TITLE_STYLE)
|
||||||
mainStoryValue = QLabel(main_story_time)
|
mainStoryValue = QLabel(main_story_time)
|
||||||
@@ -2625,8 +2645,11 @@ class MainWindow(QMainWindow):
|
|||||||
hltbLayout.addWidget(mainStoryValue)
|
hltbLayout.addWidget(mainStoryValue)
|
||||||
hltbLayout.addSpacing(30)
|
hltbLayout.addSpacing(30)
|
||||||
has_data = True
|
has_data = True
|
||||||
|
except RuntimeError:
|
||||||
|
logger.warning("Detail page already deleted, skipping main story time update")
|
||||||
|
|
||||||
if main_extra_time is not None:
|
if main_extra_time is not None:
|
||||||
|
try:
|
||||||
mainExtraTitle = QLabel(_("MAIN + SIDES"))
|
mainExtraTitle = QLabel(_("MAIN + SIDES"))
|
||||||
mainExtraTitle.setStyleSheet(self.theme.PLAY_TIME_TITLE_STYLE)
|
mainExtraTitle.setStyleSheet(self.theme.PLAY_TIME_TITLE_STYLE)
|
||||||
mainExtraValue = QLabel(main_extra_time)
|
mainExtraValue = QLabel(main_extra_time)
|
||||||
@@ -2635,8 +2658,11 @@ class MainWindow(QMainWindow):
|
|||||||
hltbLayout.addWidget(mainExtraValue)
|
hltbLayout.addWidget(mainExtraValue)
|
||||||
hltbLayout.addSpacing(30)
|
hltbLayout.addSpacing(30)
|
||||||
has_data = True
|
has_data = True
|
||||||
|
except RuntimeError:
|
||||||
|
logger.warning("Detail page already deleted, skipping main extra time update")
|
||||||
|
|
||||||
if completionist_time is not None:
|
if completionist_time is not None:
|
||||||
|
try:
|
||||||
completionistTitle = QLabel(_("COMPLETIONIST"))
|
completionistTitle = QLabel(_("COMPLETIONIST"))
|
||||||
completionistTitle.setStyleSheet(self.theme.LAST_LAUNCH_TITLE_STYLE)
|
completionistTitle.setStyleSheet(self.theme.LAST_LAUNCH_TITLE_STYLE)
|
||||||
completionistValue = QLabel(completionist_time)
|
completionistValue = QLabel(completionist_time)
|
||||||
@@ -2644,6 +2670,8 @@ class MainWindow(QMainWindow):
|
|||||||
hltbLayout.addWidget(completionistTitle)
|
hltbLayout.addWidget(completionistTitle)
|
||||||
hltbLayout.addWidget(completionistValue)
|
hltbLayout.addWidget(completionistValue)
|
||||||
has_data = True
|
has_data = True
|
||||||
|
except RuntimeError:
|
||||||
|
logger.warning("Detail page already deleted, skipping completionist time update")
|
||||||
|
|
||||||
# Если есть данные, добавляем layout во вторую строку
|
# Если есть данные, добавляем layout во вторую строку
|
||||||
if has_data:
|
if has_data:
|
||||||
|
|||||||
Reference in New Issue
Block a user