mirror of
https://github.com/dcs-liberation/dcs_liberation.git
synced 2025-11-10 14:22:26 +00:00
Disconnect log signals on exit.
If we don't do this, the uvicorn server may log its shutdown after the Qt application has closed, and the signal this attempts to emit may not be valid. Disconnect the log signals when the application exits to prevent that. There's actually another solution that I thought would be better, but I couldn't get it to work: https://www.pyinstaller.org/en/stable/feature-notes.html#automatic-hiding-and-minimization-of-console-window-under-windows describes a way to have pyinstaller hide or minimize the console rather than disabling it entirely. I was never really fond of getting rid of the console window in the first place, but it did bother some users. If we could get the hide or minimize option working, that'd probably avoid bothering users, but also make the logs much easier to find, get us out of the trouble of maintaining our own log viewer, and fix the problem mentioned in the comment I add here (the log window only works if there's only one in memory log handler). Another option would be ditching our log window and instead just having that menu item open the log file or directory in whatever program the OS defaults to (probably notepad). It would still have the quirk of maybe needing to open more than one location, since logging is use configurable. Fixes https://github.com/dcs-liberation/dcs_liberation/issues/3278.
This commit is contained in:
parent
88591fd18c
commit
5ee3afeddb
@ -1,5 +1,8 @@
|
|||||||
|
from __future__ import annotations
|
||||||
|
|
||||||
import logging
|
import logging
|
||||||
import typing
|
import typing
|
||||||
|
from collections.abc import Iterator
|
||||||
|
|
||||||
LogHook = typing.Callable[[str], None]
|
LogHook = typing.Callable[[str], None]
|
||||||
|
|
||||||
@ -15,6 +18,16 @@ class HookableInMemoryHandler(logging.Handler):
|
|||||||
self._log = ""
|
self._log = ""
|
||||||
self._hook = None
|
self._hook = None
|
||||||
|
|
||||||
|
@staticmethod
|
||||||
|
def iter_registered_handlers(
|
||||||
|
logger: logging.Logger | None = None,
|
||||||
|
) -> Iterator[HookableInMemoryHandler]:
|
||||||
|
if logger is None:
|
||||||
|
logger = logging.getLogger()
|
||||||
|
for handler in logger.handlers:
|
||||||
|
if isinstance(handler, HookableInMemoryHandler):
|
||||||
|
yield handler
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def log(self) -> str:
|
def log(self) -> str:
|
||||||
return self._log
|
return self._log
|
||||||
|
|||||||
@ -27,6 +27,7 @@ from game.theater import ControlPoint, MissionTarget, TheaterGroundObject
|
|||||||
from game.turnstate import TurnState
|
from game.turnstate import TurnState
|
||||||
from qt_ui import liberation_install
|
from qt_ui import liberation_install
|
||||||
from qt_ui.dialogs import Dialog
|
from qt_ui.dialogs import Dialog
|
||||||
|
from qt_ui.logging_handler import HookableInMemoryHandler
|
||||||
from qt_ui.models import GameModel
|
from qt_ui.models import GameModel
|
||||||
from qt_ui.simcontroller import SimController
|
from qt_ui.simcontroller import SimController
|
||||||
from qt_ui.uiflags import UiFlags
|
from qt_ui.uiflags import UiFlags
|
||||||
@ -576,6 +577,10 @@ class QLiberationWindow(QMainWindow):
|
|||||||
self._cp_dialog = QBaseMenu2(None, cp, self.game_model)
|
self._cp_dialog = QBaseMenu2(None, cp, self.game_model)
|
||||||
self._cp_dialog.show()
|
self._cp_dialog.show()
|
||||||
|
|
||||||
|
def _disconnect_log_signals(self) -> None:
|
||||||
|
for handler in HookableInMemoryHandler.iter_registered_handlers():
|
||||||
|
handler.clearHook()
|
||||||
|
|
||||||
def _qsettings(self) -> QSettings:
|
def _qsettings(self) -> QSettings:
|
||||||
return QSettings("DCS Liberation", "Qt UI")
|
return QSettings("DCS Liberation", "Qt UI")
|
||||||
|
|
||||||
@ -597,6 +602,7 @@ class QLiberationWindow(QMainWindow):
|
|||||||
QMessageBox.Yes | QMessageBox.No,
|
QMessageBox.Yes | QMessageBox.No,
|
||||||
)
|
)
|
||||||
if result == QMessageBox.Yes:
|
if result == QMessageBox.Yes:
|
||||||
|
self._disconnect_log_signals()
|
||||||
self._save_window_geometry()
|
self._save_window_geometry()
|
||||||
super().closeEvent(event)
|
super().closeEvent(event)
|
||||||
self.dialog = None
|
self.dialog = None
|
||||||
|
|||||||
@ -1,14 +1,13 @@
|
|||||||
import logging
|
|
||||||
import typing
|
import typing
|
||||||
|
|
||||||
from PySide6.QtCore import Signal
|
from PySide6.QtCore import Signal
|
||||||
|
from PySide6.QtGui import QTextCursor, QIcon
|
||||||
from PySide6.QtWidgets import (
|
from PySide6.QtWidgets import (
|
||||||
QDialog,
|
QDialog,
|
||||||
QPlainTextEdit,
|
QPlainTextEdit,
|
||||||
QVBoxLayout,
|
QVBoxLayout,
|
||||||
QPushButton,
|
QPushButton,
|
||||||
)
|
)
|
||||||
from PySide6.QtGui import QTextCursor, QIcon
|
|
||||||
|
|
||||||
from qt_ui.logging_handler import HookableInMemoryHandler
|
from qt_ui.logging_handler import HookableInMemoryHandler
|
||||||
|
|
||||||
@ -50,12 +49,17 @@ class QLogsWindow(QDialog):
|
|||||||
|
|
||||||
self.appendLogSignal.connect(self.appendLog)
|
self.appendLogSignal.connect(self.appendLog)
|
||||||
|
|
||||||
self._logging_handler = None
|
try:
|
||||||
logger = logging.getLogger()
|
# This assumes that there's never more than one in memory handler. We don't
|
||||||
for handler in logger.handlers:
|
# configure more than one by default, but logging is customizable with
|
||||||
if isinstance(handler, HookableInMemoryHandler):
|
# resources/logging.yaml. If someone adds a second in-memory handler, only
|
||||||
self._logging_handler = handler
|
# the first one (in arbitrary order) will be shown.
|
||||||
break
|
self._logging_handler = next(
|
||||||
|
HookableInMemoryHandler.iter_registered_handlers()
|
||||||
|
)
|
||||||
|
except StopIteration:
|
||||||
|
self._logging_handler = None
|
||||||
|
|
||||||
if self._logging_handler is not None:
|
if self._logging_handler is not None:
|
||||||
self.textbox.setPlainText(self._logging_handler.log)
|
self.textbox.setPlainText(self._logging_handler.log)
|
||||||
self.textbox.moveCursor(QTextCursor.End)
|
self.textbox.moveCursor(QTextCursor.End)
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user