App: Move legendary initialization to the singleton
App: Move tray to MainWindow Shared: Add destructor for singleton instances
This commit is contained in:
parent
4951743bbf
commit
afcdc1dea1
146
rare/app.py
146
rare/app.py
|
@ -13,14 +13,19 @@ from typing import Optional
|
|||
import legendary
|
||||
import requests.exceptions
|
||||
from PyQt5.QtCore import QThreadPool, QTimer, QT_VERSION_STR, PYQT_VERSION_STR
|
||||
from PyQt5.QtWidgets import QApplication, QSystemTrayIcon, QMessageBox
|
||||
from PyQt5.QtWidgets import QApplication, QMessageBox
|
||||
from requests import HTTPError
|
||||
|
||||
import rare
|
||||
from rare.components.dialogs.launch_dialog import LaunchDialog
|
||||
from rare.components.main_window import MainWindow
|
||||
from rare.components.tray_icon import TrayIcon
|
||||
from rare.shared import LegendaryCoreSingleton, GlobalSignalsSingleton, ArgumentsSingleton
|
||||
from rare.shared import (
|
||||
LegendaryCoreSingleton,
|
||||
GlobalSignalsSingleton,
|
||||
ArgumentsSingleton,
|
||||
ApiResultsSingleton,
|
||||
clear_singleton_instance
|
||||
)
|
||||
from rare.shared.image_manager import ImageManagerSingleton
|
||||
from rare.utils import legendary_utils, config_helper
|
||||
from rare.utils.paths import cache_dir, tmp_dir
|
||||
|
@ -54,64 +59,21 @@ def excepthook(exc_type, exc_value, exc_tb):
|
|||
|
||||
|
||||
class App(RareApp):
|
||||
mainwindow: Optional[MainWindow] = None
|
||||
tray_icon: Optional[QSystemTrayIcon] = None
|
||||
|
||||
def __init__(self, args: Namespace):
|
||||
super(App, self).__init__()
|
||||
self.core = LegendaryCoreSingleton()
|
||||
self.args = ArgumentsSingleton(args) # add some options
|
||||
self.window_launched = False
|
||||
|
||||
# init Legendary
|
||||
try:
|
||||
self.core = LegendaryCoreSingleton(init=True)
|
||||
except configparser.MissingSectionHeaderError as e:
|
||||
logger.warning(f"Config is corrupt: {e}")
|
||||
if config_path := os.environ.get("XDG_CONFIG_HOME"):
|
||||
path = os.path.join(config_path, "legendary")
|
||||
else:
|
||||
path = os.path.expanduser("~/.config/legendary")
|
||||
with open(os.path.join(path, "config.ini"), "w") as config_file:
|
||||
config_file.write("[Legendary]")
|
||||
self.core = LegendaryCoreSingleton(init=True)
|
||||
if "Legendary" not in self.core.lgd.config.sections():
|
||||
self.core.lgd.config.add_section("Legendary")
|
||||
self.core.lgd.save_config()
|
||||
|
||||
lang = self.settings.value("language", self.core.language_code, type=str)
|
||||
self.load_translator(lang)
|
||||
|
||||
config_helper.init_config_handler(self.core)
|
||||
|
||||
# workaround if egl sync enabled, but no programdata_path
|
||||
# programdata_path might be unset if logging in through the browser
|
||||
if self.core.egl_sync_enabled:
|
||||
if self.core.egl.programdata_path is None:
|
||||
self.core.lgd.config.remove_option("Legendary", "egl_sync")
|
||||
self.core.lgd.save_config()
|
||||
else:
|
||||
if not os.path.exists(self.core.egl.programdata_path):
|
||||
self.core.lgd.config.remove_option("Legendary", "egl_sync")
|
||||
self.core.lgd.save_config()
|
||||
|
||||
# set Application name for settings
|
||||
self.launch_dialog = None
|
||||
self.mainwindow: Optional[MainWindow] = None
|
||||
self.launch_dialog: Optional[LaunchDialog] = None
|
||||
|
||||
self.signals = GlobalSignalsSingleton(init=True)
|
||||
self.image_manager = ImageManagerSingleton(init=True)
|
||||
|
||||
self.signals.exit_app.connect(self.exit_app)
|
||||
self.signals.send_notification.connect(
|
||||
lambda title: self.tray_icon.showMessage(
|
||||
self.tr("Download finished"),
|
||||
self.tr("Download finished. {} is playable now").format(title),
|
||||
QSystemTrayIcon.Information,
|
||||
4000,
|
||||
)
|
||||
if self.settings.value("notification", True, bool)
|
||||
else None
|
||||
)
|
||||
|
||||
# launch app
|
||||
self.launch_dialog = LaunchDialog(parent=None)
|
||||
self.launch_dialog.quit_app.connect(self.launch_dialog.close)
|
||||
|
@ -140,12 +102,6 @@ class App(RareApp):
|
|||
td = abs(dt_exp - dt_now)
|
||||
self.timer.start(int(td.total_seconds() - 60) * 1000)
|
||||
|
||||
def show_mainwindow(self):
|
||||
if self.window_launched:
|
||||
self.mainwindow.show()
|
||||
else:
|
||||
self.mainwindow.show_window_centered()
|
||||
|
||||
def start_app(self):
|
||||
for igame in self.core.get_installed_list():
|
||||
if not os.path.exists(igame.install_path):
|
||||
|
@ -167,85 +123,27 @@ class App(RareApp):
|
|||
logger.info(f"{igame.title} needs verification")
|
||||
|
||||
self.mainwindow = MainWindow()
|
||||
self.tray_icon: TrayIcon = TrayIcon(self)
|
||||
self.tray_icon.exit_action.triggered.connect(self.exit_app)
|
||||
self.tray_icon.start_rare.triggered.connect(self.show_mainwindow)
|
||||
self.tray_icon.activated.connect(
|
||||
lambda r: self.show_mainwindow()
|
||||
if r == QSystemTrayIcon.DoubleClick
|
||||
else None
|
||||
)
|
||||
self.mainwindow.exit_app.connect(self.exit_app)
|
||||
|
||||
if not self.args.silent:
|
||||
self.mainwindow.show_window_centered()
|
||||
self.window_launched = True
|
||||
|
||||
if self.args.subparser == "launch":
|
||||
if self.args.app_name in [
|
||||
i.app_name for i in self.core.get_installed_list()
|
||||
]:
|
||||
logger.info(
|
||||
f"Launching {self.core.get_installed_game(self.args.app_name).title}"
|
||||
)
|
||||
self.mainwindow.tab_widget.games_tab.game_utils.prepare_launch(
|
||||
self.args.app_name
|
||||
)
|
||||
else:
|
||||
logger.error(
|
||||
f"Could not find {self.args.app_name} in Games or it is not installed"
|
||||
)
|
||||
QMessageBox.warning(
|
||||
self.mainwindow,
|
||||
"Warning",
|
||||
self.tr(
|
||||
"Could not find {} in installed games. Did you modify the shortcut? "
|
||||
).format(self.args.app_name),
|
||||
)
|
||||
self.mainwindow.show()
|
||||
|
||||
if self.args.test_start:
|
||||
self.exit_app(0)
|
||||
|
||||
def tray(self, reason):
|
||||
if reason == QSystemTrayIcon.DoubleClick:
|
||||
self.mainwindow.show()
|
||||
logger.info("Show App")
|
||||
|
||||
def exit_app(self, exit_code=0):
|
||||
# FIXME: Fix this with the download tab redesign
|
||||
if self.mainwindow is not None:
|
||||
if not self.args.offline and self.mainwindow.tab_widget.downloadTab.is_download_active:
|
||||
question = QMessageBox.question(
|
||||
self.mainwindow,
|
||||
self.tr("Close"),
|
||||
self.tr(
|
||||
"There is a download active. Do you really want to exit app?"
|
||||
),
|
||||
QMessageBox.Yes,
|
||||
QMessageBox.No,
|
||||
)
|
||||
if question == QMessageBox.No:
|
||||
return
|
||||
else:
|
||||
# clear queue
|
||||
self.mainwindow.tab_widget.downloadTab.queue_widget.update_queue([])
|
||||
self.mainwindow.tab_widget.downloadTab.stop_download()
|
||||
# FIXME: End of FIXME
|
||||
self.mainwindow.timer.stop()
|
||||
self.mainwindow.hide()
|
||||
threadpool = QThreadPool.globalInstance()
|
||||
threadpool.waitForDone()
|
||||
self.core.exit()
|
||||
if self.mainwindow is not None:
|
||||
self.mainwindow.close()
|
||||
self.mainwindow.deleteLater()
|
||||
self.mainwindow = None
|
||||
if self.tray_icon is not None:
|
||||
self.tray_icon.deleteLater()
|
||||
self.tray_icon = None
|
||||
if self.timer is not None:
|
||||
self.timer.stop()
|
||||
self.timer.deleteLater()
|
||||
self.timer = None
|
||||
if self.mainwindow is not None:
|
||||
self.mainwindow.close()
|
||||
self.mainwindow = None
|
||||
clear_singleton_instance(self.signals)
|
||||
clear_singleton_instance(self.args)
|
||||
clear_singleton_instance(ApiResultsSingleton())
|
||||
self.processEvents()
|
||||
shutil.rmtree(tmp_dir)
|
||||
os.makedirs(tmp_dir)
|
||||
|
@ -284,10 +182,16 @@ def start(args):
|
|||
logger.info(f"Operating System: {platform.system()}")
|
||||
|
||||
while True:
|
||||
core = LegendaryCoreSingleton(init=True)
|
||||
config_helper.init_config_handler(core)
|
||||
app = App(args)
|
||||
exit_code = app.exec_()
|
||||
# if not restart
|
||||
# restart app
|
||||
del app
|
||||
core.exit()
|
||||
clear_singleton_instance(core)
|
||||
if exit_code != -133742:
|
||||
break
|
||||
|
||||
|
||||
|
|
|
@ -1,18 +1,22 @@
|
|||
import os
|
||||
from logging import getLogger
|
||||
|
||||
from PyQt5.QtCore import Qt, QSettings, QTimer, QSize
|
||||
from PyQt5.QtCore import Qt, QSettings, QTimer, QSize, pyqtSignal, pyqtSlot
|
||||
from PyQt5.QtGui import QCloseEvent, QCursor
|
||||
from PyQt5.QtWidgets import QMainWindow, QApplication, QStatusBar, QScrollArea, QScroller, QComboBox
|
||||
from PyQt5.QtWidgets import QMainWindow, QApplication, QStatusBar, QScrollArea, QScroller, QComboBox, QMessageBox
|
||||
|
||||
from rare.components.tabs import TabWidget
|
||||
from rare.components.tray_icon import TrayIcon
|
||||
from rare.shared import LegendaryCoreSingleton, GlobalSignalsSingleton, ArgumentsSingleton
|
||||
from rare.utils.paths import data_dir
|
||||
|
||||
logger = getLogger("Window")
|
||||
logger = getLogger("MainWindow")
|
||||
|
||||
|
||||
class MainWindow(QMainWindow):
|
||||
# int: exit code
|
||||
exit_app: pyqtSignal = pyqtSignal(int)
|
||||
|
||||
def __init__(self, parent=None):
|
||||
super(MainWindow, self).__init__(parent=parent)
|
||||
self.setAttribute(Qt.WA_DeleteOnClose)
|
||||
|
@ -46,8 +50,42 @@ class MainWindow(QMainWindow):
|
|||
self.timer.timeout.connect(self.timer_finished)
|
||||
self.timer.start(1000)
|
||||
|
||||
def show_window_centered(self):
|
||||
self.show()
|
||||
self.signals.exit_app.connect(self.on_exit_app)
|
||||
self.exit_code = 0
|
||||
self.accept_close = False
|
||||
|
||||
self.tray_icon: TrayIcon = TrayIcon(self)
|
||||
self.tray_icon.exit_action.triggered.connect(self.on_exit_app)
|
||||
self.tray_icon.start_rare.triggered.connect(self.show)
|
||||
self.tray_icon.activated.connect(
|
||||
lambda r: self.toggle()
|
||||
if r == self.tray_icon.DoubleClick
|
||||
else None
|
||||
)
|
||||
|
||||
self.signals.send_notification.connect(
|
||||
lambda title: self.tray_icon.showMessage(
|
||||
self.tr("Download finished"),
|
||||
self.tr("Download finished. {} is playable now").format(title),
|
||||
self.tray_icon.Information,
|
||||
4000,
|
||||
)
|
||||
if self.settings.value("notification", True, bool)
|
||||
else None
|
||||
)
|
||||
|
||||
self.window_launched = False
|
||||
|
||||
# enable kinetic scrolling
|
||||
for scroll_area in self.findChildren(QScrollArea):
|
||||
if not scroll_area.property("no_kinetic_scroll"):
|
||||
QScroller.grabGesture(scroll_area.viewport(), QScroller.LeftMouseButtonGesture)
|
||||
|
||||
# fix scrolling
|
||||
for combo_box in scroll_area.findChildren(QComboBox):
|
||||
combo_box.wheelEvent = lambda e: e.ignore()
|
||||
|
||||
def center_window(self):
|
||||
# get the margins of the decorated window
|
||||
margins = self.windowHandle().frameMargins()
|
||||
# get the screen the cursor is on
|
||||
|
@ -68,14 +106,23 @@ class MainWindow(QMainWindow):
|
|||
- self.rect().adjusted(0, 0, decor_width, decor_height).center()
|
||||
)
|
||||
|
||||
# enable kinetic scrolling
|
||||
for scroll_area in self.findChildren(QScrollArea):
|
||||
if not scroll_area.property("no_kinetic_scroll"):
|
||||
QScroller.grabGesture(scroll_area.viewport(), QScroller.LeftMouseButtonGesture)
|
||||
def show(self) -> None:
|
||||
super(MainWindow, self).show()
|
||||
if not self.window_launched:
|
||||
self.center_window()
|
||||
self.window_launched = True
|
||||
|
||||
# fix scrolling
|
||||
for combo_box in scroll_area.findChildren(QComboBox):
|
||||
combo_box.wheelEvent = lambda e: e.ignore()
|
||||
def hide(self) -> None:
|
||||
if self.settings.value("save_size", False, bool):
|
||||
size = self.size().width(), self.size().height()
|
||||
self.settings.setValue("window_size", size)
|
||||
super(MainWindow, self).hide()
|
||||
|
||||
def toggle(self):
|
||||
if self.isHidden():
|
||||
self.show()
|
||||
else:
|
||||
self.hide()
|
||||
|
||||
def timer_finished(self):
|
||||
file_path = os.path.join(data_dir, "lockfile")
|
||||
|
@ -88,15 +135,43 @@ class MainWindow(QMainWindow):
|
|||
os.remove(file_path)
|
||||
self.timer.start(1000)
|
||||
|
||||
@pyqtSlot()
|
||||
@pyqtSlot(int)
|
||||
def on_exit_app(self, exit_code=0) -> None:
|
||||
# FIXME: Fix this with the download tab redesign
|
||||
if not self.args.offline and self.tab_widget.downloadTab.is_download_active:
|
||||
question = QMessageBox.question(
|
||||
self,
|
||||
self.tr("Close"),
|
||||
self.tr(
|
||||
"There is a download active. Do you really want to exit app?"
|
||||
),
|
||||
QMessageBox.Yes,
|
||||
QMessageBox.No,
|
||||
)
|
||||
if question == QMessageBox.No:
|
||||
return
|
||||
else:
|
||||
# clear queue
|
||||
self.tab_widget.downloadTab.queue_widget.update_queue([])
|
||||
self.tab_widget.downloadTab.stop_download()
|
||||
# FIXME: End of FIXME
|
||||
self.exit_code = exit_code
|
||||
self.close()
|
||||
|
||||
def close(self) -> bool:
|
||||
self.accept_close = True
|
||||
return super(MainWindow, self).close()
|
||||
|
||||
def closeEvent(self, e: QCloseEvent):
|
||||
if self.settings.value("save_size", False, bool):
|
||||
size = self.size().width(), self.size().height()
|
||||
self.settings.setValue("window_size", size)
|
||||
if self.settings.value("sys_tray", True, bool):
|
||||
self.hide()
|
||||
e.ignore()
|
||||
return
|
||||
elif self.args.offline:
|
||||
pass
|
||||
self.signals.exit_app.emit(0)
|
||||
e.ignore()
|
||||
if not self.accept_close:
|
||||
if self.settings.value("sys_tray", True, bool):
|
||||
self.hide()
|
||||
e.ignore()
|
||||
return
|
||||
self.timer.stop()
|
||||
self.tray_icon.deleteLater()
|
||||
self.hide()
|
||||
self.exit_app.emit(self.exit_code)
|
||||
super(MainWindow, self).closeEvent(e)
|
||||
e.accept()
|
||||
|
|
|
@ -13,7 +13,7 @@ logger = getLogger("TrayIcon")
|
|||
|
||||
class TrayIcon(QSystemTrayIcon):
|
||||
def __init__(self, parent):
|
||||
super(TrayIcon, self).__init__(parent)
|
||||
super(TrayIcon, self).__init__(parent=parent)
|
||||
self.core = LegendaryCoreSingleton()
|
||||
|
||||
self.setIcon(QIcon(":/images/Rare.png"))
|
||||
|
@ -33,7 +33,7 @@ class TrayIcon(QSystemTrayIcon):
|
|||
if len(installed := self.core.get_installed_list()) < 5:
|
||||
last_played = [GameMeta(i.app_name) for i in sorted(installed, key=lambda x: x.title)]
|
||||
elif games := sorted(
|
||||
parent.mainwindow.tab_widget.games_tab.game_utils.game_meta.get_games(),
|
||||
parent.tab_widget.games_tab.game_utils.game_meta.get_games(),
|
||||
key=lambda x: x.last_played, reverse=True):
|
||||
last_played: List[GameMeta] = games[0:5]
|
||||
else:
|
||||
|
@ -46,7 +46,7 @@ class TrayIcon(QSystemTrayIcon):
|
|||
a.setProperty("app_name", game.app_name)
|
||||
self.game_actions.append(a)
|
||||
a.triggered.connect(
|
||||
lambda: parent.mainwindow.tab_widget.games_tab.game_utils.prepare_launch(
|
||||
lambda: parent.tab_widget.games_tab.game_utils.prepare_launch(
|
||||
self.sender().property("app_name"))
|
||||
)
|
||||
|
||||
|
|
|
@ -5,14 +5,18 @@ Each of the objects in this module should be instantiated ONCE
|
|||
and only ONCE!
|
||||
"""
|
||||
|
||||
import configparser
|
||||
import logging
|
||||
import os
|
||||
from argparse import Namespace
|
||||
from typing import Optional
|
||||
from typing import Optional, Union
|
||||
|
||||
from rare.lgndr.core import LegendaryCore
|
||||
|
||||
from rare.models.apiresults import ApiResults
|
||||
from rare.models.signals import GlobalSignals
|
||||
|
||||
logger = logging.getLogger("Singleton")
|
||||
|
||||
_legendary_core_singleton: Optional[LegendaryCore] = None
|
||||
_global_signals_singleton: Optional[GlobalSignals] = None
|
||||
_arguments_singleton: Optional[Namespace] = None
|
||||
|
@ -23,8 +27,33 @@ def LegendaryCoreSingleton(init: bool = False) -> LegendaryCore:
|
|||
global _legendary_core_singleton
|
||||
if _legendary_core_singleton is None and not init:
|
||||
raise RuntimeError("Uninitialized use of LegendaryCoreSingleton")
|
||||
if _legendary_core_singleton is None:
|
||||
_legendary_core_singleton = LegendaryCore()
|
||||
if _legendary_core_singleton is not None and init:
|
||||
raise RuntimeError("LegendaryCore already initialized")
|
||||
if init:
|
||||
try:
|
||||
_legendary_core_singleton = LegendaryCore()
|
||||
except configparser.MissingSectionHeaderError as e:
|
||||
logger.warning(f"Config is corrupt: {e}")
|
||||
if config_path := os.environ.get("XDG_CONFIG_HOME"):
|
||||
path = os.path.join(config_path, "legendary")
|
||||
else:
|
||||
path = os.path.expanduser("~/.config/legendary")
|
||||
with open(os.path.join(path, "config.ini"), "w") as config_file:
|
||||
config_file.write("[Legendary]")
|
||||
_legendary_core_singleton = LegendaryCore()
|
||||
if "Legendary" not in _legendary_core_singleton.lgd.config.sections():
|
||||
_legendary_core_singleton.lgd.config.add_section("Legendary")
|
||||
_legendary_core_singleton.lgd.save_config()
|
||||
# workaround if egl sync enabled, but no programdata_path
|
||||
# programdata_path might be unset if logging in through the browser
|
||||
if _legendary_core_singleton.egl_sync_enabled:
|
||||
if _legendary_core_singleton.egl.programdata_path is None:
|
||||
_legendary_core_singleton.lgd.config.remove_option("Legendary", "egl_sync")
|
||||
_legendary_core_singleton.lgd.save_config()
|
||||
else:
|
||||
if not os.path.exists(_legendary_core_singleton.egl.programdata_path):
|
||||
_legendary_core_singleton.lgd.config.remove_option("Legendary", "egl_sync")
|
||||
_legendary_core_singleton.lgd.save_config()
|
||||
return _legendary_core_singleton
|
||||
|
||||
|
||||
|
@ -32,7 +61,9 @@ def GlobalSignalsSingleton(init: bool = False) -> GlobalSignals:
|
|||
global _global_signals_singleton
|
||||
if _global_signals_singleton is None and not init:
|
||||
raise RuntimeError("Uninitialized use of GlobalSignalsSingleton")
|
||||
if _global_signals_singleton is None:
|
||||
if _global_signals_singleton is not None and init:
|
||||
raise RuntimeError("GlobalSignals already initialized")
|
||||
if init:
|
||||
_global_signals_singleton = GlobalSignals()
|
||||
return _global_signals_singleton
|
||||
|
||||
|
@ -41,7 +72,9 @@ def ArgumentsSingleton(args: Namespace = None) -> Optional[Namespace]:
|
|||
global _arguments_singleton
|
||||
if _arguments_singleton is None and args is None:
|
||||
raise RuntimeError("Uninitialized use of ArgumentsSingleton")
|
||||
if _arguments_singleton is None:
|
||||
if _arguments_singleton is not None and args is not None:
|
||||
raise RuntimeError("Arguments already initialized")
|
||||
if args is not None:
|
||||
_arguments_singleton = args
|
||||
return _arguments_singleton
|
||||
|
||||
|
@ -50,7 +83,27 @@ def ApiResultsSingleton(res: ApiResults = None) -> Optional[ApiResults]:
|
|||
global _api_results_singleton
|
||||
if _api_results_singleton is None and res is None:
|
||||
raise RuntimeError("Uninitialized use of ApiResultsSingleton")
|
||||
if _api_results_singleton is None:
|
||||
if _api_results_singleton is not None and res is not None:
|
||||
raise RuntimeError("ApiResults already initialized")
|
||||
if res is not None:
|
||||
_api_results_singleton = res
|
||||
return _api_results_singleton
|
||||
|
||||
|
||||
def clear_singleton_instance(instance: Union[LegendaryCore, GlobalSignals, Namespace, ApiResults]):
|
||||
global _legendary_core_singleton, _global_signals_singleton, _arguments_singleton, _api_results_singleton
|
||||
if isinstance(instance, LegendaryCore):
|
||||
del instance
|
||||
_legendary_core_singleton = None
|
||||
elif isinstance(instance, GlobalSignals):
|
||||
instance.deleteLater()
|
||||
del instance
|
||||
_global_signals_singleton = None
|
||||
elif isinstance(instance, Namespace):
|
||||
del instance
|
||||
_arguments_singleton = None
|
||||
elif isinstance(instance, ApiResults):
|
||||
del instance
|
||||
_api_results_singleton = None
|
||||
else:
|
||||
raise RuntimeError(f"Instance is of unknown type \"{type(instance)}\"")
|
||||
|
|
|
@ -54,7 +54,6 @@ class IndicatorReasons:
|
|||
|
||||
class IndicatorLineEdit(QWidget):
|
||||
textChanged = pyqtSignal(str)
|
||||
is_valid = False
|
||||
reasons = IndicatorReasons()
|
||||
|
||||
def __init__(
|
||||
|
@ -97,9 +96,10 @@ class IndicatorLineEdit(QWidget):
|
|||
layout.addWidget(self.indicator_label)
|
||||
|
||||
if not placeholder:
|
||||
_translate = QCoreApplication.translate
|
||||
_translate = QCoreApplication.instance().translate
|
||||
self.line_edit.setPlaceholderText(_translate(self.__class__.__name__, "Default"))
|
||||
|
||||
self.is_valid = False
|
||||
self.edit_func = edit_func
|
||||
self.save_func = save_func
|
||||
self.line_edit.textChanged.connect(self.__edit)
|
||||
|
@ -107,7 +107,7 @@ class IndicatorLineEdit(QWidget):
|
|||
self.line_edit.textChanged.connect(self.__save)
|
||||
|
||||
# lk: this can be placed here to trigger __edit
|
||||
# lk: it going to save the input again if it is valid which
|
||||
# lk: it is going to save the input again if it is valid which
|
||||
# lk: is ok to do given the checks don't misbehave (they shouldn't)
|
||||
# lk: however it is going to edit any "understood" bad input to good input
|
||||
# lk: and we might not want that (but the validity check reports on the edited string)
|
||||
|
@ -185,9 +185,6 @@ class PathEditIconProvider(QFileIconProvider):
|
|||
|
||||
|
||||
class PathEdit(IndicatorLineEdit):
|
||||
completer = QCompleter()
|
||||
compl_model = QFileSystemModel()
|
||||
|
||||
def __init__(
|
||||
self,
|
||||
path: str = "",
|
||||
|
@ -200,6 +197,9 @@ class PathEdit(IndicatorLineEdit):
|
|||
horiz_policy: QSizePolicy = QSizePolicy.Expanding,
|
||||
parent=None,
|
||||
):
|
||||
self.completer = QCompleter()
|
||||
self.compl_model = QFileSystemModel()
|
||||
|
||||
try:
|
||||
self.compl_model.setOptions(
|
||||
QFileSystemModel.DontWatchForChanges
|
||||
|
@ -230,7 +230,7 @@ class PathEdit(IndicatorLineEdit):
|
|||
layout = self.layout()
|
||||
layout.addWidget(self.path_select)
|
||||
|
||||
_translate = QCoreApplication.translate
|
||||
_translate = QCoreApplication.instance().translate
|
||||
self.path_select.setText(_translate("PathEdit", "Browse..."))
|
||||
|
||||
self.type_filter = type_filter
|
||||
|
@ -414,7 +414,7 @@ class SelectViewWidget(QWidget):
|
|||
class ImageLabel(QLabel):
|
||||
image = None
|
||||
img_size = None
|
||||
name = str()
|
||||
name = ""
|
||||
|
||||
def __init__(self):
|
||||
super(ImageLabel, self).__init__()
|
||||
|
|
Loading…
Reference in a new issue