Fix crash if log window is open when entering mission.

Use signal to append text to LogWindow to avoid crash from crossing thread boundaries.
Change modal flag to enable interacting with LogWindow while the mission is running

Fixes https://github.com/dcs-liberation/dcs_liberation/issues/1493
This commit is contained in:
Johan Aberg 2021-10-20 13:04:16 +13:00 committed by GitHub
parent 551ea728fc
commit 17011820de
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
4 changed files with 26 additions and 9 deletions

View File

@ -287,8 +287,8 @@ class QTopPanel(QFrame):
) )
unit_map = self.game.initiate_event(game_event) unit_map = self.game.initiate_event(game_event)
waiting = QWaitingForMissionResultWindow(game_event, self.game, unit_map) waiting = QWaitingForMissionResultWindow(game_event, self.game, unit_map, self)
waiting.show() waiting.exec_()
def budget_update(self, game: Game): def budget_update(self, game: Game):
self.budgetBox.setGame(game) self.budgetBox.setGame(game)

View File

@ -387,5 +387,6 @@ class QLiberationWindow(QMainWindow):
) )
if result == QMessageBox.Yes: if result == QMessageBox.Yes:
super().closeEvent(event) super().closeEvent(event)
self.dialog = None
else: else:
event.ignore() event.ignore()

View File

@ -2,11 +2,11 @@ from __future__ import annotations
import json import json
import os import os
from typing import Sized from typing import Sized, Optional
from PySide2 import QtCore from PySide2 import QtCore
from PySide2.QtCore import QObject, Qt, Signal from PySide2.QtCore import QObject, Qt, Signal
from PySide2.QtGui import QIcon, QMovie, QPixmap from PySide2.QtGui import QIcon, QMovie, QPixmap, QWindow
from PySide2.QtWidgets import ( from PySide2.QtWidgets import (
QDialog, QDialog,
QFileDialog, QFileDialog,
@ -17,6 +17,7 @@ from PySide2.QtWidgets import (
QMessageBox, QMessageBox,
QPushButton, QPushButton,
QTextBrowser, QTextBrowser,
QWidget,
) )
from jinja2 import Environment, FileSystemLoader, select_autoescape from jinja2 import Environment, FileSystemLoader, select_autoescape
@ -49,9 +50,15 @@ DebriefingFileWrittenSignal()
class QWaitingForMissionResultWindow(QDialog): class QWaitingForMissionResultWindow(QDialog):
def __init__(self, gameEvent: Event, game: Game, unit_map: UnitMap) -> None: def __init__(
super(QWaitingForMissionResultWindow, self).__init__() self,
self.setModal(True) gameEvent: Event,
game: Game,
unit_map: UnitMap,
parent: Optional[QWidget] = None,
) -> None:
super(QWaitingForMissionResultWindow, self).__init__(parent=parent)
self.setWindowModality(QtCore.Qt.WindowModal)
self.gameEvent = gameEvent self.gameEvent = gameEvent
self.game = game self.game = game
self.unit_map = unit_map self.unit_map = unit_map

View File

@ -1,18 +1,21 @@
import logging import logging
import typing import typing
from PySide2.QtCore import Signal
from PySide2.QtWidgets import ( from PySide2.QtWidgets import (
QDialog, QDialog,
QPlainTextEdit, QPlainTextEdit,
QVBoxLayout, QVBoxLayout,
QPushButton, QPushButton,
) )
from PySide2.QtGui import QTextCursor from PySide2.QtGui import QTextCursor, QIcon
from qt_ui.logging_handler import HookableInMemoryHandler from qt_ui.logging_handler import HookableInMemoryHandler
class QLogsWindow(QDialog): class QLogsWindow(QDialog):
appendLogSignal = Signal(str)
vbox: QVBoxLayout vbox: QVBoxLayout
textbox: QPlainTextEdit textbox: QPlainTextEdit
clear_button: QPushButton clear_button: QPushButton
@ -24,6 +27,7 @@ class QLogsWindow(QDialog):
self.setWindowTitle("Logs") self.setWindowTitle("Logs")
self.setMinimumSize(400, 100) self.setMinimumSize(400, 100)
self.resize(1000, 450) self.resize(1000, 450)
self.setWindowIcon(QIcon("./resources/icon.png"))
self.vbox = QVBoxLayout() self.vbox = QVBoxLayout()
self.setLayout(self.vbox) self.setLayout(self.vbox)
@ -44,6 +48,8 @@ class QLogsWindow(QDialog):
self.clear_button.clicked.connect(self.clearLogs) self.clear_button.clicked.connect(self.clearLogs)
self.vbox.addWidget(self.clear_button) self.vbox.addWidget(self.clear_button)
self.appendLogSignal.connect(self.appendLog)
self._logging_handler = None self._logging_handler = None
logger = logging.getLogger() logger = logging.getLogger()
for handler in logger.handlers: for handler in logger.handlers:
@ -53,7 +59,10 @@ class QLogsWindow(QDialog):
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)
self._logging_handler.setHook(self.appendLog) # The Handler might be called from a different thread,
# so use signal/slot to properly handle the event in the main thread.
# https://github.com/dcs-liberation/dcs_liberation/issues/1493
self._logging_handler.setHook(self.appendLogSignal.emit)
else: else:
self.textbox.setPlainText("WARNING: logging not initialized!") self.textbox.setPlainText("WARNING: logging not initialized!")