Как инициировать событие при изменении переменной, в которую записано исключение?
Исключения, которые появляются в процессе работы программы сейчас пишутся в текстбокс окна, мне нужно, чтобы при включенном чекбоксе (log_in_DB) они писались сразу и в таблицу бд (функция log_in_sql_server, подключение к бд работает). Я пытаюсь сейчас сделать это через слоты и сигналы.
- источник события - изменение self.msg в классе QTextEditLogger
- слот это функция log_in_sql_server в классе MainWindow
class QTextEditLogger(logging.Handler):
valueChanged = pyqtSignal(str)
def __init__(self, parent):
super().__init__()
self.widget = parent.ui.plainTextEdit
self.widget.setReadOnly(True)
def emit(self, record):
self.msg = self.format(record)
self.widget.appendPlainText(self.msg)
@property
def msg(self):
return self._msg
@msg.setter
def msg(self, value):
self._msg = value
self.valueChanged.emit(value)
class MainWindow(QtWidgets.QMainWindow):
def __init__(self):
super(MainWindow, self).__init__()
self.initUI()
self.log_text_box = QTextEditLogger(self)
self.log_text_box.setFormatter(logging.Formatter('%(asctime)s %(module)s.%(funcName)s((lineno)d)
%(levelname)s:%(message)s'))
logging.getLogger().addHandler(self.log_text_box)
logging.getLogger().setLevel(logging.DEBUG)
self.ui.plainTextEdit.setTextInteractionFlags(QtCore.Qt.TextSelectableByMouse)
self.log_text_box.valueChanged.connect(self.log_in_sql_server)
def initUI(self):
self.ui.log_in_DB.clicked.connect(self.log_in_sql_server)
def log_in_sql_server(self, msg):
try:
if self.ui.log_in_DB.isChecked():
Session = db.sessionmaker()
session = Session(bind=db.engine)
new_post = db.UserException(message="сообщение из форматтера",
target_site="место где произошло исключение",
date_time_exc='аскитайм из форматтера',
index_form=1)
session.add(new_post)
session.commit()
except ValueError as e:
logging.debug(e, exc_info=True)
Эта реализация дает ошибку: QTextEditLogger cannot be converted to PyQt5.QtCore.QObject in this context.
И еще, как после передачи self.msg разбить ее на нужные мне части? может есть что-то встроенное, потому что разбивать строку на строки между пробелами звучит не слишком хорошо.
Ответы (1 шт):
Класс, использующий сигналы-слоты должен быть наследником QObject. Надо немного переделать:
import logging
class LoggingHandler(logging.Handler):
def __init__(self, textLogger):
super().__init__()
self._textLogger = textLogger
@property
def msg(self):
return self._msg
@msg.setter
def msg(self, value):
self._msg = value
self._textLogger.valueChanged.emit(value)
class QTextEditLogger(QObject):
valueChanged = Signal(str)
def __init__(self, parent=None):
super().__init__(parent)
self.handler = LoggingHandler(textLogger=self)
def emit(self, record):
self.handler.msg = self.handler.format(record)
self.widget.appendPlainText(self.msg)
Теперь в окне:
class MainWindow(QtWidgets.QMainWindow):
def __init__(self):
super(MainWindow, self).__init__()
self.initUI()
self.log_text_box = QTextEditLogger(self)
...
logging.getLogger().addHandler(self.log_text_box.handler)