1
0
Fork 0
mirror of synced 2024-06-26 18:20:50 +12:00

Update Games list to ui file

This commit is contained in:
Dummerle 2021-09-26 16:43:56 +02:00
parent 03c2ad77eb
commit a143971385
10 changed files with 592 additions and 583 deletions

View file

@ -36,17 +36,17 @@ class MainWindow(QMainWindow):
if not args.offline:
self.rpc = DiscordRPC(core)
# Discord RPC on game launch
self.tab_widget.games_tab.default_widget.game_list.game_started.connect(
lambda: self.rpc.set_discord_rpc(self.tab_widget.games_tab.default_widget.game_list.running_games[0]))
#self.tab_widget.games_tab.default_widget.game_list.game_started.connect(
# lambda: self.rpc.set_discord_rpc(self.tab_widget.games_tab.default_widget.game_list.running_games[0]))
# Remove RPC
self.tab_widget.delete_presence.connect(self.rpc.set_discord_rpc)
# Show RPC on changed rare_settings
self.tab_widget.settings.rare_settings.rpc.update_settings.connect(
lambda: self.rpc.changed_settings(self.tab_widget.games_tab.default_widget.game_list.running_games))
game = self.tab_widget.games_tab.default_widget.game_list.active_game
if game != ("", 0) and not args.offline:
self.rpc.set_discord_rpc(game[0]) # Appname
#game = self.tab_widget.games_tab.default_widget.game_list.active_game
#if game != ("", 0) and not args.offline:
# self.rpc.set_discord_rpc(game[0]) # Appname
if args.subparser == "launch":
logger.info("Launching " + self.core.get_installed_game(args.app_name).title)

View file

@ -1,134 +1,404 @@
from PyQt5.QtCore import QSettings, QSize, pyqtSignal
from PyQt5.QtWidgets import QWidget, QVBoxLayout, QHBoxLayout, QLineEdit, QPushButton, QStackedLayout, \
QLabel, QComboBox
from qtawesome import icon
from logging import getLogger
from legendary.models.game import Game
from PyQt5.QtCore import pyqtSignal, QSettings
from PyQt5.QtWidgets import QStackedWidget, QVBoxLayout, QWidget
from legendary.core import LegendaryCore
from legendary.models.game import GameAsset
from rare.components.tabs.games.game_info import InfoTabs
from rare.components.tabs.games.game_info.uninstalled_info import UninstalledInfo, UninstalledTabInfo
from rare.components.tabs.games.game_list import GameList
from rare.components.tabs.games.game_info.uninstalled_info import UninstalledTabInfo
from rare.components.tabs.games.game_widgets.base_installed_widget import BaseInstalledWidget
from rare.components.tabs.games.game_widgets.base_uninstalled_widget import BaseUninstalledWidget
from rare.components.tabs.games.game_widgets.installed_icon_widget import InstalledIconWidget
from rare.components.tabs.games.game_widgets.installed_list_widget import InstalledListWidget
from rare.components.tabs.games.game_widgets.installing_game_widget import InstallingGameWidget
from rare.components.tabs.games.game_widgets.uninstalled_icon_widget import IconWidgetUninstalled
from rare.components.tabs.games.game_widgets.uninstalled_list_widget import ListWidgetUninstalled
from rare.components.tabs.games.head_bar import GameListHeadBar
from rare.components.tabs.games.import_widget import ImportWidget
from rare.utils.extra_widgets import SelectViewWidget
from rare.ui.components.tabs.games.games_tab import Ui_GamesTab
from rare.utils.extra_widgets import FlowLayout
from rare.utils.utils import get_pixmap, download_image, get_uninstalled_pixmap
logger = getLogger("GamesTab")
class GameTab(QWidget):
def __init__(self, core, parent, offline):
super(GameTab, self).__init__(parent=parent)
self.setLayout(QStackedLayout())
self.default_widget = Games(core, self, offline)
# Signal to show info
self.default_widget.game_list.show_game_info.connect(self.show_info)
self.default_widget.head_bar.import_game.clicked.connect(lambda: self.layout().setCurrentIndex(2))
self.layout().addWidget(self.default_widget)
class GamesTab(QStackedWidget, Ui_GamesTab):
updates = []
widgets = {}
running_games = []
game_exited = pyqtSignal(str)
self.game_info = InfoTabs(core, self)
game_started = pyqtSignal(str)
def __init__(self, core: LegendaryCore, offline):
super(GamesTab, self).__init__()
self.setupUi(self)
self.core = core
self.offline = offline
self.settings = QSettings()
self.head_bar = GameListHeadBar()
self.games.layout().insertWidget(0, self.head_bar)
self.game_info = InfoTabs(self.core, self)
self.game_info.info.update_list.connect(self.update_list)
self.layout().addWidget(self.game_info)
self.default_widget.head_bar.refresh_list.clicked.connect(self.update_list)
self.addWidget(self.game_info)
self.import_widget = ImportWidget(core, self)
self.layout().addWidget(self.import_widget)
self.import_widget.back_button.clicked.connect(lambda: self.layout().setCurrentIndex(0))
self.import_widget.update_list.connect(self.update_list)
self.addWidget(self.import_widget)
self.uninstalled_info_widget = UninstalledTabInfo(core, self)
self.layout().addWidget(self.uninstalled_info_widget)
# self.uninstalled_info_widget.back.clicked.connect(lambda: self.layout().setCurrentIndex(0))
def update_list(self, app_name=None):
self.default_widget.game_list.update_list(app_name)
self.layout().setCurrentIndex(0)
# navigation
self.head_bar.import_game.clicked.connect(lambda: self.setCurrentIndex(2))
self.import_widget.back_button.clicked.connect(lambda: self.setCurrentIndex(0))
self.uninstalled_info_widget.tabBarClicked.connect(lambda x: self.setCurrentIndex(0) if x == 0 else None)
def show_uninstalled(self, game: Game):
self.uninstalled_info_widget.update_game(game)
self.uninstalled_info_widget.setCurrentIndex(1)
self.layout().setCurrentIndex(3)
def show_info(self, game: Game):
self.game_info.update_game(game, self.default_widget.game_list.dlcs)
self.game_info.setCurrentIndex(1)
self.layout().setCurrentIndex(1)
self.game_info.info.update_list.connect(self.update_list)
class Games(QWidget):
def __init__(self, core, parent, offline):
super(Games, self).__init__(parent=parent)
self.setLayout(QVBoxLayout())
self.head_bar = GameListHeadBar(self)
self.head_bar.setObjectName("head_bar")
self.setup_game_list()
self.game_list = GameList(core, self, offline)
if not self.settings.value("icon_view", True, bool):
self.scroll_widget.layout().insertWidget(1, self.list_view)
self.head_bar.view.list()
else:
self.scroll_widget.layout().insertWidget(1, self.icon_view)
self.head_bar.search_bar.textChanged.connect(
lambda: self.game_list.search(self.head_bar.search_bar.text()))
self.head_bar.filter_changed_signal.connect(self.game_list.filter)
self.head_bar.filter_changed(self.head_bar.filter.currentIndex())
self.layout().addWidget(self.head_bar)
self.layout().addWidget(self.game_list)
# self.layout().addStretch(1)
self.head_bar.search_bar.textChanged.connect(self.search)
self.head_bar.filter_changed_signal.connect(self.filter)
self.head_bar.refresh_list.clicked.connect(self.update_list)
self.head_bar.view.toggled.connect(self.toggle_view)
self.filter(["", "installed", "offline", "32bit", "installable"][self.settings.value("filter", 0, int)])
def show_game_info(self, game):
self.game_info.update_game(game, self.dlcs)
self.setCurrentIndex(1)
def show_uninstalled_info(self, game):
self.uninstalled_info_widget.update_game(game)
self.setCurrentIndex(3)
def setup_game_list(self):
self.icon_view = QWidget()
self.icon_view.setLayout(FlowLayout())
self.list_view = QWidget()
self.list_view.setLayout(QVBoxLayout())
# TODO move to seperate thread
if not self.offline:
self.game_list, self.dlcs = self.core.get_game_and_dlc_list(True)
self.bit32 = [i.app_name for i in self.core.get_game_and_dlc_list(True, "Win32")[0]]
self.mac_games = [i.app_name for i in self.core.get_game_and_dlc_list(True, "Mac")[0]]
self.core.lgd.assets = [GameAsset.from_egs_json(a) for a in self.core.egs.get_game_assets()]
no_assets = self.core.get_non_asset_library_items()[0]
self.no_assets = []
for game in no_assets:
self.no_assets.append(game)
self.no_asset_names = []
for game in self.no_assets:
self.no_asset_names.append(game.app_name)
else:
self.bit32 = []
self.mac_games = []
self.dlcs = []
self.installed = sorted(self.core.get_installed_list(), key=lambda x: x.title)
self.update_count_games_label()
# add installing game widget for icon view: List view not supported
self.installing_widget = InstallingGameWidget()
self.icon_view.layout().addWidget(self.installing_widget)
self.installing_widget.setVisible(False)
# add installed games
for igame in self.installed:
icon_widget, list_widget = self.add_installed_widget(self.core.get_game(igame.app_name))
self.icon_view.layout().addWidget(icon_widget)
self.list_view.layout().addWidget(list_widget)
for game in self.no_assets:
icon_widget, list_widget = self.add_installed_widget(game, is_origin=True)
self.icon_view.layout().addWidget(icon_widget)
self.list_view.layout().addWidget(list_widget)
if not self.offline:
self.uninstalled_games = []
installed = [i.app_name for i in self.core.get_installed_list()]
# get Uninstalled games
for game in self.game_list:
if game.app_name not in installed:
self.uninstalled_games.append(game)
for game in sorted(self.uninstalled_games, key=lambda x: x.app_title):
icon_widget, list_widget = self.add_uninstalled_widget(game)
self.icon_view.layout().addWidget(icon_widget)
self.list_view.layout().addWidget(list_widget)
def update_count_games_label(self):
self.count_games_label.setText(self.tr("Installed Games: {} Available Games: {}").format(
len(self.core.get_installed_list()),
len(self.game_list)))
def add_installed_widget(self, game, is_origin=False):
pixmap = get_pixmap(game.app_name)
if pixmap.isNull():
logger.info(game.app_title + " has a corrupt image.")
download_image(self.core.get_game(game.app_name), force=True)
pixmap = get_pixmap(game.app_name)
if game.app_name in self.no_asset_names:
igame = None
else:
igame = self.core.get_installed_game(game.app_name)
icon_widget = InstalledIconWidget(igame, self.core, pixmap, self.offline, is_origin, game)
list_widget = InstalledListWidget(igame, self.core, pixmap, self.offline, is_origin, game)
self.widgets[game.app_name] = (icon_widget, list_widget)
icon_widget.show_info.connect(self.show_game_info)
list_widget.show_info.connect(self.show_game_info)
icon_widget.launch_signal.connect(self.launch)
icon_widget.finish_signal.connect(self.finished)
icon_widget.update_list.connect(self.update_list)
list_widget.launch_signal.connect(self.launch)
list_widget.finish_signal.connect(self.finished)
list_widget.update_list.connect(self.update_list)
if icon_widget.update_available:
self.updates.append(igame)
return icon_widget, list_widget
def add_uninstalled_widget(self, game):
pixmap = get_uninstalled_pixmap(game.app_name)
if pixmap.isNull():
logger.info(game.app_title + " has a corrupt image. Reloading...")
download_image(game, force=True)
pixmap = get_uninstalled_pixmap(game.app_name)
icon_widget = IconWidgetUninstalled(game, self.core, pixmap)
icon_widget.show_uninstalled_info.connect(self.show_uninstalled_info)
list_widget = ListWidgetUninstalled(self.core, game, pixmap)
list_widget.show_uninstalled_info.connect(self.show_uninstalled_info)
self.widgets[game.app_name] = (icon_widget, list_widget)
return icon_widget, list_widget
def start_download(self, app_name):
self.installing_widget.set_game(self.core.get_game(app_name))
self.installing_widget.setVisible(True)
def finished(self, app_name):
self.running_games.remove(app_name)
self.active_game = ("", 0)
self.widgets[app_name][0].info_text = ""
self.widgets[app_name][0].info_label.setText("")
self.widgets[app_name][1].launch_button.setDisabled(False)
self.widgets[app_name][1].launch_button.setText(self.tr("Launch"))
if self.widgets[app_name][0].game.supports_cloud_saves:
if not self.settings.value(f"{app_name}/auto_sync_cloud", True, bool) \
and not self.settings.value("auto_sync_cloud", True, bool):
logger.info("Auto saves disabled")
return
self.widgets[app_name][0].info_text = self.tr("Sync CLoud saves")
self.widgets[app_name][0].info_label.setText(self.tr("Sync CLoud saves"))
self.widgets[app_name][1].info_label.setText(self.tr("Sync CLoud saves"))
self.game_exited.emit(app_name)
def launch(self, app_name):
self.running_games.append(app_name)
self.game_started.emit(app_name)
self.widgets[app_name][0].info_text = self.tr("Game running")
self.widgets[app_name][0].info_label.setText(self.tr("Game running"))
self.widgets[app_name][1].launch_button.setDisabled(True)
self.widgets[app_name][1].launch_button.setText(self.tr("Game running"))
def search(self, text: str):
for t in self.widgets.values():
for w in t:
if text.lower() in w.game.app_title.lower() + w.game.app_name.lower():
w.setVisible(True)
else:
w.setVisible(False)
def filter(self, filter_name="installed"):
for t in self.widgets.values():
# icon and list widget
for w in t:
if filter_name == "installed":
w.setVisible(self.core.is_installed(w.game.app_name))
elif filter_name == "offline":
if self.core.is_installed(w.game.app_name):
w.setVisible(w.igame.can_run_offline)
else:
w.setVisible(False)
elif filter_name == "32bit" and self.bit32:
w.setVisible(w.game.app_name in self.bit32)
elif filter_name == "mac":
w.setVisible(w.game.app_name in self.mac_games)
elif filter_name == "installable":
w.setVisible(w.game.app_name not in self.no_asset_names)
else:
# All visible
w.setVisible(True)
def update_list(self, app_name=None):
if app_name:
if widgets := self.widgets.get(app_name):
# from update
if self.core.is_installed(widgets[0].game.app_name) and isinstance(widgets[0], BaseInstalledWidget):
igame = self.core.get_installed_game(app_name)
for w in widgets:
w.igame = igame
w.update_available = self.core.get_asset(w.game.app_name, True).build_version != igame.version
widgets[0].info_label.setText("")
widgets[0].info_text = ""
# new installed
elif self.core.is_installed(app_name) and isinstance(widgets[0], BaseUninstalledWidget):
logger.debug("Update Gamelist: New installed " + app_name)
self.widgets[app_name][0].deleteLater()
self.widgets[app_name][1].deleteLater()
self.widgets.pop(app_name)
igame = self.core.get_installed_game(app_name)
self.add_installed_widget(self.core.get_game(igame.app_name))
self._update_games()
# uninstalled
elif not self.core.is_installed(widgets[0].game.app_name) and isinstance(widgets[0],
BaseInstalledWidget):
logger.debug("Update list: uninstall")
self.widgets[app_name][0].deleteLater()
self.widgets[app_name][1].deleteLater()
self.widgets.pop(app_name)
game = self.core.get_game(app_name, False)
self.add_uninstalled_widget(game)
self._update_games()
else:
installed_names = [i.app_name for i in self.core.get_installed_list()]
# get Uninstalled games
uninstalled_names = []
games = self.core.get_game_list(True)
for game in sorted(games, key=lambda x: x.app_title):
if not game.app_name in installed_names:
uninstalled_names.append(game.app_name)
new_installed_games = list(set(installed_names) - set([i.app_name for i in self.installed]))
new_uninstalled_games = list(set(uninstalled_names) - set([i.app_name for i in self.uninstalled_games]))
if (not new_uninstalled_games) and (not new_installed_games):
return
if new_installed_games:
for name in new_installed_games:
self.icon_view.layout().removeWidget(self.widgets[name][0])
self.list_view.layout().removeWidget(self.widgets[name][1])
self.widgets[name][0].deleteLater()
self.widgets[name][1].deleteLater()
self.widgets.pop(name)
igame = self.core.get_installed_game(name)
self.add_installed_widget(self.core.get_game(igame.app_name))
for name in new_uninstalled_games:
self.icon_view.layout().removeWidget(self.widgets[app_name][0])
self.list_view.layout().removeWidget(self.widgets[app_name][1])
self.widgets[name][0].deleteLater()
self.widgets[name][1].deleteLater()
self.widgets.pop(name)
game = self.core.get_game(name, True)
self.add_uninstalled_widget(game)
for igame in sorted(self.core.get_installed_list(), key=lambda x: x.title):
i_widget, list_widget = self.widgets[igame.app_name]
self.icon_view.layout().addWidget(i_widget)
self.list_view.layout().addWidget(list_widget)
# get Uninstalled games
games, self.dlcs = self.core.get_game_and_dlc_list()
for game in sorted(games, key=lambda x: x.app_title):
if not game.app_name in installed_names:
self.uninstalled_names.append(game)
for name in uninstalled_names:
i_widget, list_widget = self.widgets[name]
self.icon_view.layout().addWidget(i_widget)
self.list_view.layout().addWidget(list_widget)
self.installing_widget.setVisible(False)
self.update_count_games_label()
def _update_games(self):
icon_layout = FlowLayout()
list_layout = QVBoxLayout()
icon_layout.addWidget(self.installing_widget)
for igame in sorted(self.core.get_installed_list(), key=lambda x: x.title):
i_widget, l_widget = self.widgets[igame.app_name]
icon_layout.addWidget(i_widget)
list_layout.addWidget(l_widget)
for game in self.no_assets:
i_widget, l_widget = self.widgets[game.app_name]
icon_layout.addWidget(i_widget)
list_layout.addWidget(l_widget)
self.uninstalled_names = []
installed_names = [i.app_name for i in self.core.get_installed_list()]
# get Uninstalled games
games, self.dlcs = self.core.get_game_and_dlc_list(update_assets=False)
# add uninstalled games
for game in sorted(games, key=lambda x: x.app_title):
if game.app_name not in installed_names:
self.uninstalled_names.append(game)
for game in self.uninstalled_names:
i_widget, list_widget = self.widgets[game.app_name]
icon_layout.addWidget(i_widget)
list_layout.addWidget(list_widget)
QWidget().setLayout(self.icon_view.layout())
QWidget().setLayout(self.list_view.layout())
#self.icon_view.layout().deleteLater()
#self.list_view.layout().deleteLater()
self.icon_view.setLayout(icon_layout)
self.list_view.setLayout(list_layout)
self.icon_view.setParent(None)
self.list_view.setParent(None)
# insert widget in layout
self.scroll_widget.layout().insertWidget(1, self.icon_view if self.head_bar.view.isChecked() else self.list_view)
def toggle_view(self):
self.game_list.setCurrentIndex(1 if self.head_bar.view.isChecked() else 0)
settings = QSettings()
settings.setValue("icon_view", not self.head_bar.view.isChecked())
self.settings.setValue("icon_view", not self.head_bar.view.isChecked())
class GameListHeadBar(QWidget):
filter_changed_signal = pyqtSignal(str)
def __init__(self, parent):
super(GameListHeadBar, self).__init__(parent=parent)
self.setLayout(QHBoxLayout())
# self.installed_only = QCheckBox(self.tr("Installed only"))
self.settings = QSettings()
# self.installed_only.setChecked(self.settings.value("installed_only", False, bool))
# self.layout.addWidget(self.installed_only)
self.filter = QComboBox()
self.filter.addItems([self.tr("All"),
self.tr("Installed only"),
self.tr("Offline Games"),
self.tr("32 Bit Games"),
self.tr("Exclude Origin")])
self.layout().addWidget(self.filter)
try:
self.filter.setCurrentIndex(self.settings.value("filter", 0, int))
except TypeError:
self.settings.setValue("filter", 0)
self.filter.currentIndexChanged.connect(self.filter_changed)
self.layout().addStretch(1)
self.import_game = QPushButton(icon("mdi.import"), self.tr("Import Game"))
self.layout().addWidget(self.import_game)
self.layout().addStretch(1)
self.search_bar = QLineEdit()
self.search_bar.setObjectName("search_bar")
self.search_bar.setFrame(False)
icon_label = QLabel()
icon_label.setPixmap(icon("fa.search").pixmap(QSize(20, 20)))
self.layout().addWidget(icon_label)
self.search_bar.setMinimumWidth(200)
self.search_bar.setPlaceholderText(self.tr("Search Game"))
self.layout().addWidget(self.search_bar)
self.layout().addStretch(2)
checked = QSettings().value("icon_view", True, bool)
self.view = SelectViewWidget(checked)
self.layout().addWidget(self.view)
self.layout().addStretch(1)
self.refresh_list = QPushButton()
self.refresh_list.setIcon(icon("fa.refresh")) # Reload icon
self.layout().addWidget(self.refresh_list)
def filter_changed(self, i):
self.filter_changed_signal.emit(["", "installed", "offline", "32bit", "installable"][i])
self.settings.setValue("filter", i)
if not self.head_bar.view.isChecked():
self.scroll_widget.layout().replaceWidget(self.list_view, self.icon_view)
self.list_view.setParent(None)
else:
self.scroll_widget.layout().replaceWidget(self.icon_view, self.list_view)
self.icon_view.setParent(None)

View file

@ -19,7 +19,7 @@ class InfoTabs(QTabWidget):
self.setTabPosition(QTabWidget.West)
self.addTab(QWidget(), icon("mdi.keyboard-backspace"), self.tr("Back"))
self.tabBarClicked.connect(lambda x: self.parent().layout().setCurrentIndex(0) if x == 0 else None)
self.tabBarClicked.connect(lambda x: self.parent().setCurrentIndex(0) if x == 0 else None)
self.info = GameInfo(core, self)
self.addTab(self.info, self.tr("Information"))
@ -32,7 +32,7 @@ class InfoTabs(QTabWidget):
self.addTab(self.dlc, self.tr("Downloadable Content"))
def update_game(self, game: Game, dlcs: list):
self.setCurrentIndex(1)
self.info.update_game(game)
self.settings.update_game(game)

View file

@ -25,8 +25,6 @@ class UninstalledTabInfo(QTabWidget):
self.setTabPosition(QTabWidget.West)
self.addTab(QWidget(), icon("mdi.keyboard-backspace"), self.tr("Back"))
self.tabBarClicked.connect(lambda x: self.parent().layout.setCurrentIndex(0) if x == 0 else None)
self.info = UninstalledInfo(core, self)
self.addTab(self.info, self.tr("Game Info"))
@ -42,17 +40,18 @@ class UninstalledTabInfo(QTabWidget):
# self.setTabEnabled(1, False)
self.setCurrentIndex(1)
def update_game(self, app_name):
def update_game(self, app_name: Game):
self.setCurrentIndex(1)
self.info.update_game(app_name)
self.model.clear()
try:
self.model.load(json.load(open(os.path.expanduser(f"~/.config/legendary/metadata/{app_name}.json"), "r")))
self.model.load(app_name.__dict__)
except: # ignore if no metadata
pass
def keyPressEvent(self, e: QKeyEvent):
if e.key() == Qt.Key_Escape:
self.parent().layout.setCurrentIndex(0)
self.parent().setCurrentIndex(0)
class UninstalledInfo(QWidget, Ui_GameInfo):

View file

@ -1,440 +0,0 @@
from logging import getLogger
import psutil
from PyQt5.QtCore import Qt, pyqtSignal, QSettings, QTimer
from PyQt5.QtWidgets import QScrollArea, QWidget, QLabel, QVBoxLayout, QStackedWidget
from legendary.core import LegendaryCore
from legendary.models.game import Game, GameAsset
from rare.components.tabs.games.game_widgets.base_installed_widget import BaseInstalledWidget
from rare.components.tabs.games.game_widgets.installed_icon_widget import InstalledIconWidget
from rare.components.tabs.games.game_widgets.installed_list_widget import InstalledListWidget
from rare.components.tabs.games.game_widgets.installing_game_widget import InstallingGameWidget
from rare.components.tabs.games.game_widgets.uninstalled_icon_widget import IconWidgetUninstalled
from rare.components.tabs.games.game_widgets.uninstalled_list_widget import ListWidgetUninstalled
from rare.utils.extra_widgets import FlowLayout
from rare.utils.models import InstallOptionsModel
from rare.utils.utils import download_image, get_uninstalled_pixmap, get_pixmap
logger = getLogger("Game list")
class GameList(QStackedWidget):
install_game = pyqtSignal(InstallOptionsModel)
show_game_info = pyqtSignal(Game)
update_game = pyqtSignal()
game_exited = pyqtSignal(str)
game_started = pyqtSignal(str)
show_uninstalled_info = pyqtSignal(Game)
running_games = []
active_game = ("", 0)
def __init__(self, core: LegendaryCore, parent, offline):
super(GameList, self).__init__(parent=parent)
self.core = core
self.setObjectName("list_widget")
self.offline = offline
self.installing_widget = InstallingGameWidget()
self.settings = QSettings()
icon_view = self.settings.value("icon_view", True, bool)
self.procs = []
for proc in psutil.process_iter():
try:
self.procs.append((proc.name(), proc.pid))
except psutil.ZombieProcess:
continue
except psutil.NoSuchProcess:
continue
except Exception:
continue
self.init_ui(icon_view)
def init_ui(self, icon_view=True):
self.icon_scrollarea = QScrollArea(parent=self)
self.icon_widget = QWidget(parent=self.icon_scrollarea)
self.list_scrollarea = QScrollArea(parent=self)
self.list_widget = QWidget(parent=self.list_scrollarea)
self.icon_scrollarea.setWidgetResizable(True)
self.icon_scrollarea.setVerticalScrollBarPolicy(Qt.ScrollBarAsNeeded)
self.list_scrollarea.setWidgetResizable(True)
self.list_scrollarea.setVerticalScrollBarPolicy(Qt.ScrollBarAsNeeded)
self.info_text = self.tr("Installed Games: {} Available Games: {}").format(
len(self.core.get_installed_list()),
len(self.core.get_game_list(update_assets=True)))
self.icon_parent_layout = QVBoxLayout()
self.icon_parent_layout.addWidget(QLabel(self.info_text))
self.icon_layout = FlowLayout()
self.list_layout = QVBoxLayout()
self.list_layout.addWidget(QLabel(self.info_text))
self.updates = []
self.widgets = {}
# api calls
if not self.offline:
self.core.lgd.assets = [GameAsset.from_egs_json(a) for a in self.core.egs.get_game_assets()]
self.bit32 = [i.app_name for i in self.core.get_game_and_dlc_list(True, "Win32")[0]]
self.mac_games = [i.app_name for i in self.core.get_game_and_dlc_list(True, "Mac")[0]]
no_assets = self.core.get_non_asset_library_items()[0]
self.no_assets = {}
for game in no_assets:
self.no_assets[game.app_name] = game
self.no_asset_names = []
for key in self.no_assets.keys():
self.no_asset_names.append(key)
else:
self.bit32 = []
self.mac_games = []
self.installed = sorted(self.core.get_installed_list(), key=lambda x: x.title)
self.installing_widget = InstallingGameWidget()
self.icon_layout.addWidget(self.installing_widget)
self.installing_widget.setVisible(False)
# Installed Games
for igame in self.installed:
icon_widget, list_widget = self.add_installed_widget(self.core.get_game(igame.app_name))
self.icon_layout.addWidget(icon_widget)
self.list_layout.addWidget(list_widget)
for game in self.no_assets.values():
icon_widget, list_widget = self.add_installed_widget(game, True)
self.icon_layout.addWidget(icon_widget)
self.list_layout.addWidget(list_widget)
if not self.offline:
self.uninstalled_games = []
installed = [i.app_name for i in self.core.get_installed_list()]
# get Uninstalled games
games, self.dlcs = self.core.get_game_and_dlc_list(update_assets=not self.offline)
for game in games:
if not game.app_name in installed:
self.uninstalled_games.append(game)
# add uninstalled games
for game in sorted(self.uninstalled_games, key=lambda x: x.app_title):
icon_widget, list_widget = self.add_uninstalled_widget(game)
self.icon_layout.addWidget(icon_widget)
self.list_layout.addWidget(list_widget)
else:
self.dlcs = []
self.icon_parent_layout.addLayout(self.icon_layout)
self.icon_parent_layout.addStretch(1)
self.list_layout.addStretch(1)
self.icon_widget.setLayout(self.icon_parent_layout)
self.list_widget.setLayout(self.list_layout)
self.icon_scrollarea.setWidget(self.icon_widget)
self.list_scrollarea.setWidget(self.list_widget)
self.addWidget(self.icon_scrollarea)
self.addWidget(self.list_scrollarea)
if not icon_view:
self.setCurrentIndex(1)
if filter_games := self.settings.value("filter", "", str):
self.filter(filter_games)
def start_download(self, app_name):
self.installing_widget.set_game(self.core.get_game(app_name))
self.installing_widget.setVisible(True)
def add_uninstalled_widget(self, game):
pixmap = get_uninstalled_pixmap(game.app_name)
if pixmap.isNull():
logger.info(game.app_title + " has a corrupt image. Reloading...")
download_image(game, force=True)
pixmap = get_uninstalled_pixmap(game.app_name)
icon_widget = IconWidgetUninstalled(game, self.core, pixmap)
icon_widget.show_uninstalled_info.connect(self.show_install_info)
list_widget = ListWidgetUninstalled(self.core, game, pixmap)
list_widget.show_uninstalled_info.connect(self.show_install_info)
self.widgets[game.app_name] = (icon_widget, list_widget)
return icon_widget, list_widget
def add_installed_widget(self, game, is_origin=False):
pixmap = get_pixmap(game.app_name)
if pixmap.isNull():
logger.info(game.app_title + " has a corrupt image.")
download_image(self.core.get_game(game.app_name), force=True)
pixmap = get_pixmap(game.app_name)
if game.app_name in self.no_asset_names:
igame = None
else:
igame = self.core.get_installed_game(game.app_name)
icon_widget = InstalledIconWidget(igame, self.core, pixmap, self.offline, is_origin, game)
# self.icon_layout.addWidget(icon_widget)
list_widget = InstalledListWidget(igame, self.core, pixmap, self.offline, is_origin, game)
# self.list_layout.addWidget(list_widget)
self.widgets[game.app_name] = (icon_widget, list_widget)
icon_widget.show_info.connect(self.show_game_info.emit)
list_widget.show_info.connect(self.show_game_info.emit)
icon_widget.launch_signal.connect(self.launch)
icon_widget.finish_signal.connect(self.finished)
icon_widget.update_list.connect(self.update_list)
list_widget.launch_signal.connect(self.launch)
list_widget.finish_signal.connect(self.finished)
list_widget.update_list.connect(self.update_list)
if icon_widget.update_available:
self.updates.append(igame)
if igame:
active, pid = self.check_for_active_game(igame)
if active:
# Only one game works: Workaround for Satisfactory EA and Exp.
self.launch(igame.app_name)
icon_widget.game_running = True
list_widget.game_running = True
self.active_game = (igame.app_name, pid)
self.timer = QTimer()
self.timer.timeout.connect(self.is_finished)
self.timer.start(10000)
return icon_widget, list_widget
def is_finished(self):
if psutil.pid_exists(self.active_game[1]):
self.timer.start(10000)
else:
self.finished(self.active_game[0])
del self.timer
def check_for_active_game(self, igame):
executable = igame.executable.split("/")[-1].split("\\")[-1]
if executable.endswith(".exe"):
executable = executable[:-4] # remove .exe
for i, pid in self.procs:
if executable in i:
# Workaround for Satisfactory: Check Cmdline args
if igame.app_name in ["CrabEA", "CrabTest"]:
p = psutil.Process(pid)
if not igame.install_path.split("/")[-1].split("\\")[-1] in " ".join(p.cmdline()):
return False, 0
return True, pid
return False, 0
def show_install_info(self, game):
self.show_uninstalled_info.emit(game)
def finished(self, app_name):
self.running_games.remove(app_name)
self.active_game = ("", 0)
self.widgets[app_name][0].info_text = ""
self.widgets[app_name][0].info_label.setText("")
self.widgets[app_name][1].launch_button.setDisabled(False)
self.widgets[app_name][1].launch_button.setText(self.tr("Launch"))
if self.widgets[app_name][0].game.supports_cloud_saves:
if not self.settings.value(f"{app_name}/auto_sync_cloud", True, bool) \
and not self.settings.value("auto_sync_cloud", True, bool):
logger.info("Auto saves disabled")
return
self.widgets[app_name][0].info_text = self.tr("Sync CLoud saves")
self.widgets[app_name][0].info_label.setText(self.tr("Sync CLoud saves"))
self.widgets[app_name][1].info_label.setText(self.tr("Sync CLoud saves"))
self.game_exited.emit(app_name)
def launch(self, app_name):
self.running_games.append(app_name)
self.game_started.emit(app_name)
self.widgets[app_name][0].info_text = self.tr("Game running")
self.widgets[app_name][0].info_label.setText(self.tr("Game running"))
self.widgets[app_name][1].launch_button.setDisabled(True)
self.widgets[app_name][1].launch_button.setText(self.tr("Game running"))
def search(self, text: str):
for t in self.widgets.values():
for w in t:
if text.lower() in w.game.app_title.lower() + w.game.app_name.lower():
w.setVisible(True)
else:
w.setVisible(False)
def filter(self, filter="installed"):
for t in self.widgets.values():
for w in t:
if filter == "installed":
w.setVisible(self.core.is_installed(w.game.app_name))
elif filter == "offline":
if self.core.is_installed(w.game.app_name):
w.setVisible(w.igame.can_run_offline)
else:
w.setVisible(False)
elif filter == "32bit" and self.bit32:
w.setVisible(w.game.app_name in self.bit32)
elif filter == "mac":
w.setVisible(w.game.app_name in self.mac_games)
elif filter == "installable":
w.setVisible(w.game.app_name not in self.no_asset_names)
else:
# All visible
w.setVisible(True)
def update_list(self, app_name=None):
# self.settings.setValue("icon_view", icon_view)
if app_name:
if widgets := self.widgets.get(app_name):
# from update
if self.core.is_installed(widgets[0].game.app_name) and isinstance(widgets[0], BaseInstalledWidget):
igame = self.core.get_installed_game(app_name)
for w in widgets:
w.igame = igame
w.update_available = self.core.get_asset(w.game.app_name, True).build_version != igame.version
widgets[0].info_label.setText("")
widgets[0].info_text = ""
# new installed
elif self.core.is_installed(widgets[0].game.app_name) and not isinstance(widgets[0],
BaseInstalledWidget):
name = widgets[0].game.app_name
self.widgets[name][0].deleteLater()
self.widgets[name][1].deleteLater()
self.widgets.pop(name)
# QWidget().setLayout(self.icon_layout)
igame = self.core.get_installed_game(app_name)
self.add_installed_widget(self.core.get_game(igame.app_name))
self._update_games()
# uninstalled
elif not self.core.is_installed(widgets[0].game.app_name) and isinstance(widgets[0],
BaseInstalledWidget):
self.list_layout.removeWidget(widgets[1])
self.icon_layout.removeWidget(widgets[0])
widgets[0].deleteLater()
widgets[1].deleteLater()
self.widgets.pop(app_name)
game = self.core.get_game(app_name, True)
self.add_uninstalled_widget(game)
self._update_games()
else:
installed_names = [i.app_name for i in self.core.get_installed_list()]
# get Uninstalled games
uninstalled_names = []
games = self.core.get_game_list(True)
for game in sorted(games, key=lambda x: x.app_title):
if not game.app_name in installed_names:
uninstalled_names.append(game.app_name)
new_installed_games = list(set(installed_names) - set([i.app_name for i in self.installed]))
new_uninstalled_games = list(set(uninstalled_names) - set([i.app_name for i in self.uninstalled_games]))
if (not new_uninstalled_games) and (not new_installed_games):
return
if new_installed_games:
for name in new_installed_games:
self.icon_layout.removeWidget(self.widgets[app_name][0])
self.list_layout.removeWidget(self.widgets[app_name][1])
self.widgets[name][0].deleteLater()
self.widgets[name][1].deleteLater()
self.widgets.pop(name)
igame = self.core.get_installed_game(name)
self.add_installed_widget(self.core.get_game(igame.app_name))
for name in new_uninstalled_games:
self.icon_layout.removeWidget(self.widgets[app_name][0])
self.list_layout.removeWidget(self.widgets[app_name][1])
self.widgets[name][0].deleteLater()
self.widgets[name][1].deleteLater()
self.widgets.pop(name)
game = self.core.get_game(name, True)
self.add_uninstalled_widget(game)
for igame in sorted(self.core.get_installed_list(), key=lambda x: x.title):
i_widget, list_widget = self.widgets[igame.app_name]
self.icon_layout.addWidget(i_widget)
self.list_layout.addWidget(list_widget)
# get Uninstalled games
games, self.dlcs = self.core.get_game_and_dlc_list()
for game in sorted(games, key=lambda x: x.app_title):
if not game.app_name in installed_names:
self.uninstalled_names.append(game)
for name in uninstalled_names:
i_widget, list_widget = self.widgets[name]
self.icon_layout.addWidget(i_widget)
self.list_layout.addWidget(list_widget)
self.installing_widget.setVisible(False)
def _update_games(self):
# new layouts to remove from old layout
icon_layout = FlowLayout()
# QWidget().setLayout(self.list_layout)
list_layout = QVBoxLayout()
icon_layout.addWidget(self.installing_widget)
for igame in sorted(self.core.get_installed_list(), key=lambda x: x.title):
i_widget, l_widget = self.widgets[igame.app_name]
icon_layout.addWidget(i_widget)
list_layout.addWidget(l_widget)
self.uninstalled_names = []
installed_names = [i.app_name for i in self.core.get_installed_list()]
# get Uninstalled games
games, self.dlcs = self.core.get_game_and_dlc_list()
for game in sorted(games, key=lambda x: x.app_title):
if game.app_name not in installed_names:
self.uninstalled_names.append(game)
for game in self.uninstalled_names:
i_widget, list_widget = self.widgets[game.app_name]
icon_layout.addWidget(i_widget)
list_layout.addWidget(list_widget)
self.icon_layout.deleteLater()
self.list_layout.deleteLater()
self.icon_widget = QWidget()
self.list_widget = QWidget()
self.icon_widget.setLayout(icon_layout)
self.list_widget.setLayout(list_layout)
self.list_scrollarea.setWidget(QWidget())
self.icon_scrollarea.setWidget(QWidget())
self.icon_scrollarea.setWidget(self.icon_widget)
self.list_scrollarea.setWidget(self.list_widget)
self.icon_layout = icon_layout
self.list_layout = list_layout
self.icon_widget.setLayout(self.icon_layout)
self.list_widget.setLayout(self.list_layout)
self.update()

View file

@ -0,0 +1,62 @@
from PyQt5.QtCore import QSize, QSettings, pyqtSignal
from PyQt5.QtWidgets import QLineEdit, QLabel, QPushButton, QWidget, QHBoxLayout, QComboBox
from qtawesome import icon
from rare.utils.extra_widgets import SelectViewWidget
class GameListHeadBar(QWidget):
filter_changed_signal = pyqtSignal(str)
def __init__(self):
super(GameListHeadBar, self).__init__()
self.setLayout(QHBoxLayout())
# self.installed_only = QCheckBox(self.tr("Installed only"))
self.settings = QSettings()
# self.installed_only.setChecked(self.settings.value("installed_only", False, bool))
# self.layout.addWidget(self.installed_only)
self.filter = QComboBox()
self.filter.addItems([self.tr("All"),
self.tr("Installed only"),
self.tr("Offline Games"),
self.tr("32 Bit Games"),
self.tr("Exclude Origin")])
self.layout().addWidget(self.filter)
try:
self.filter.setCurrentIndex(self.settings.value("filter", 0, int))
except TypeError:
self.settings.setValue("filter", 0)
self.filter.currentIndexChanged.connect(self.filter_changed)
self.layout().addStretch(1)
self.import_game = QPushButton(icon("mdi.import"), self.tr("Import Game"))
self.layout().addWidget(self.import_game)
self.layout().addStretch(1)
self.search_bar = QLineEdit()
self.search_bar.setObjectName("search_bar")
self.search_bar.setFrame(False)
icon_label = QLabel()
icon_label.setPixmap(icon("fa.search").pixmap(QSize(20, 20)))
self.layout().addWidget(icon_label)
self.search_bar.setMinimumWidth(200)
self.search_bar.setPlaceholderText(self.tr("Search Game"))
self.layout().addWidget(self.search_bar)
self.layout().addStretch(2)
checked = QSettings().value("icon_view", True, bool)
self.view = SelectViewWidget(checked)
self.layout().addWidget(self.view)
self.layout().addStretch(1)
self.refresh_list = QPushButton()
self.refresh_list.setIcon(icon("fa.refresh")) # Reload icon
self.layout().addWidget(self.refresh_list)
def filter_changed(self, i):
self.filter_changed_signal.emit(["", "installed", "offline", "32bit", "installable"][i])
self.settings.setValue("filter", i)

View file

@ -1,15 +1,15 @@
from PyQt5.QtCore import QSize, pyqtSignal
from PyQt5.QtCore import QSize, pyqtSignal, QObject
from PyQt5.QtWidgets import QMenu, QTabWidget, QWidget, QWidgetAction, QShortcut
from qtawesome import icon
from legendary.core import LegendaryCore
from rare.components.dialogs.install_dialog import InstallDialog
from rare.components.dialogs.uninstall_dialog import UninstallDialog
from rare.components.tabs.games.__init__ import GamesTab
from rare.components.tabs.tab_utils import TabBar, TabButtonWidget
from rare.components.tabs.account import MiniWidget
from rare.components.tabs.cloud_saves import SyncSaves
from rare.components.tabs.downloads import DownloadTab
from rare.components.tabs.games import GameTab
from rare.components.tabs.settings import SettingsTab
from rare.components.tabs.settings.debug_settings import DebugSettings
from rare.components.tabs.shop import Shop
@ -28,12 +28,12 @@ class TabWidget(QTabWidget):
self.core = core
self.setTabBar(TabBar(disabled_tab))
# Generate Tabs
self.games_tab = GameTab(core, self, offline)
self.games_tab = GamesTab(core, self)
self.addTab(self.games_tab, self.tr("Games"))
if not offline:
updates = self.games_tab.default_widget.game_list.updates
self.downloadTab = DownloadTab(core, updates, self)
self.addTab(self.downloadTab, "Downloads" + (" (" + str(len(updates)) + ")" if len(updates) != 0 else ""))
# updates = self.games_tab.default_widget.game_list.updates
self.downloadTab = DownloadTab(core, [], self)
self.addTab(self.downloadTab, "Downloads" + (" (" + str(len([])) + ")" if len([]) != 0 else ""))
self.cloud_saves = SyncSaves(core, self)
self.addTab(self.cloud_saves, "Cloud Saves")
self.store = Shop(self.core)
@ -65,7 +65,7 @@ class TabWidget(QTabWidget):
# Signals
# open download tab
self.games_tab.default_widget.game_list.update_game.connect(lambda: self.setCurrentIndex(1))
# self.games_tab.update_game.connect(lambda: self.setCurrentIndex(1))
# uninstall
self.games_tab.game_info.info.uninstall_game.connect(self.uninstall_game)
@ -76,8 +76,6 @@ class TabWidget(QTabWidget):
if not offline:
# Download finished
self.downloadTab.finished.connect(self.dl_finished)
# show uninstalled info
self.games_tab.default_widget.game_list.show_uninstalled_info.connect(self.games_tab.show_uninstalled)
# install dlc
self.games_tab.game_info.dlc.install_dlc.connect(
lambda app_name, update: self.install_game(
@ -100,7 +98,7 @@ class TabWidget(QTabWidget):
# Finished sync
self.cloud_saves.finished.connect(self.finished_sync)
# Game finished
self.games_tab.default_widget.game_list.game_exited.connect(self.game_finished)
self.games_tab.game_exited.connect(self.game_finished)
# Open game list on click on Games tab button
self.tabBarClicked.connect(self.mouse_clicked)
@ -113,7 +111,7 @@ class TabWidget(QTabWidget):
QShortcut("Alt+4", self).activated.connect(lambda: self.setCurrentIndex(5))
self.downloadTab.dl_status.connect(
self.games_tab.default_widget.game_list.installing_widget.image_widget.set_status)
self.games_tab.installing_widget.image_widget.set_status)
def mouse_clicked(self, tab_num):
if tab_num == 0:
@ -141,7 +139,7 @@ class TabWidget(QTabWidget):
self.setTabText(1, "Downloads" + ((" (" + str(downloads) + ")") if downloads != 0 else ""))
self.setCurrentIndex(1)
self.downloadTab.install_game(download_item)
self.games_tab.default_widget.game_list.start_download(download_item.options.app_name)
self.games_tab.start_download(download_item.options.app_name)
def game_imported(self, app_name: str):
igame = self.core.get_installed_game(app_name)
@ -149,8 +147,8 @@ class TabWidget(QTabWidget):
self.downloadTab.add_update(igame)
downloads = len(self.downloadTab.dl_queue) + len(self.downloadTab.update_widgets.keys())
self.setTabText(1, "Downloads" + ((" (" + str(downloads) + ")") if downloads != 0 else ""))
self.games_tab.default_widget.game_list.update_list(app_name)
self.games_tab.layout().setCurrentIndex(0)
self.games_tab.update_list(app_name)
self.games_tab.setCurrentIndex(0)
# Sync game and delete dc rpc
def game_finished(self, app_name):
@ -165,6 +163,7 @@ class TabWidget(QTabWidget):
if infos == 0:
return
legendary_utils.uninstall(game.app_name, self.core, infos)
self.games_tab.setCurrentIndex(0)
if app_name in self.downloadTab.update_widgets.keys():
self.downloadTab.update_layout.removeWidget(self.downloadTab.update_widgets[app_name])
self.downloadTab.update_widgets.pop(app_name)
@ -175,9 +174,9 @@ class TabWidget(QTabWidget):
# Update gamelist and set text of Downloads to "Downloads"
def dl_finished(self, update_list):
if update_list[0]:
self.games_tab.default_widget.game_list.update_list(update_list[1])
self.games_tab.update_list(update_list[1])
self.cloud_saves.reload(update_list[1])
self.games_tab.default_widget.game_list.installing_widget.setVisible(False)
self.games_tab.installing_widget.setVisible(False)
downloads = len(self.downloadTab.dl_queue) + len(self.downloadTab.update_widgets.keys())
self.setTabText(1, "Downloads" + ((" (" + str(downloads) + ")") if downloads != 0 else ""))
@ -187,6 +186,7 @@ class TabWidget(QTabWidget):
# Remove text "sync game"
def finished_sync(self, app_name):
self.games_tab.default_widget.game_list.widgets[app_name][0].info_text = ""
self.games_tab.default_widget.game_list.widgets[app_name][0].info_label.setText("")
self.games_tab.default_widget.game_list.widgets[app_name][1].info_label.setText("")
if self.core.is_installed(app_name):
self.games_tab.widgets[app_name][0].info_text = ""
self.games_tab.widgets[app_name][0].info_label.setText("")
self.games_tab.widgets[app_name][1].info_label.setText("")

View file

@ -0,0 +1,55 @@
# -*- coding: utf-8 -*-
# Form implementation generated from reading ui file 'rare/ui/components/tabs/games/games_tab.ui'
#
# Created by: PyQt5 UI code generator 5.15.4
#
# WARNING: Any manual changes made to this file will be lost when pyuic5 is
# run again. Do not edit this file unless you know what you are doing.
from PyQt5 import QtCore, QtGui, QtWidgets
class Ui_GamesTab(object):
def setupUi(self, GamesTab):
GamesTab.setObjectName("GamesTab")
GamesTab.resize(1071, 678)
self.games = QtWidgets.QWidget()
self.games.setObjectName("games")
self.verticalLayout = QtWidgets.QVBoxLayout(self.games)
self.verticalLayout.setObjectName("verticalLayout")
self.game_list_scroll_area = QtWidgets.QScrollArea(self.games)
self.game_list_scroll_area.setWidgetResizable(True)
self.game_list_scroll_area.setObjectName("game_list_scroll_area")
self.scroll_widget = QtWidgets.QWidget()
self.scroll_widget.setGeometry(QtCore.QRect(0, 0, 1051, 658))
self.scroll_widget.setObjectName("scroll_widget")
self.verticalLayout_4 = QtWidgets.QVBoxLayout(self.scroll_widget)
self.verticalLayout_4.setObjectName("verticalLayout_4")
self.count_games_label = QtWidgets.QLabel(self.scroll_widget)
self.count_games_label.setText("")
self.count_games_label.setObjectName("count_games_label")
self.verticalLayout_4.addWidget(self.count_games_label)
spacerItem = QtWidgets.QSpacerItem(20, 40, QtWidgets.QSizePolicy.Minimum, QtWidgets.QSizePolicy.Expanding)
self.verticalLayout_4.addItem(spacerItem)
self.game_list_scroll_area.setWidget(self.scroll_widget)
self.verticalLayout.addWidget(self.game_list_scroll_area)
GamesTab.addWidget(self.games)
self.retranslateUi(GamesTab)
QtCore.QMetaObject.connectSlotsByName(GamesTab)
def retranslateUi(self, GamesTab):
_translate = QtCore.QCoreApplication.translate
GamesTab.setWindowTitle(_translate("GamesTab", "StackedWidget"))
if __name__ == "__main__":
import sys
app = QtWidgets.QApplication(sys.argv)
GamesTab = QtWidgets.QStackedWidget()
ui = Ui_GamesTab()
ui.setupUi(GamesTab)
GamesTab.show()
sys.exit(app.exec_())

View file

@ -0,0 +1,62 @@
<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
<class>GamesTab</class>
<widget class="QStackedWidget" name="GamesTab">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>1071</width>
<height>678</height>
</rect>
</property>
<property name="windowTitle">
<string>StackedWidget</string>
</property>
<widget class="QWidget" name="games">
<layout class="QVBoxLayout" name="verticalLayout">
<item>
<widget class="QScrollArea" name="game_list_scroll_area">
<property name="widgetResizable">
<bool>true</bool>
</property>
<widget class="QWidget" name="scroll_widget">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>1051</width>
<height>658</height>
</rect>
</property>
<layout class="QVBoxLayout" name="verticalLayout_4">
<item>
<widget class="QLabel" name="count_games_label">
<property name="text">
<string/>
</property>
</widget>
</item>
<item>
<spacer name="verticalSpacer">
<property name="orientation">
<enum>Qt::Vertical</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>20</width>
<height>40</height>
</size>
</property>
</spacer>
</item>
</layout>
</widget>
</widget>
</item>
</layout>
</widget>
</widget>
<resources/>
<connections/>
</ui>

View file

@ -154,7 +154,8 @@ class PathEdit(QWidget, Ui_PathEdit):
self.text_edit.setText(text)
def save(self):
self.save_func()
if self.save_func:
self.save_func()
def set_path(self):
dlg_path = self.text_edit.text()