Home QT 로그 위젯 만들기
Post
Cancel

QT 로그 위젯 만들기

Python에서 제공하는 logging 모듈을 사용하여 로그가 작성되는 위젯을 만들 것이다.

이 모듈은 로그 메시지를 생성, 저장, 출력하는 기능을 제공하며 다양한 로그 레벨도 제공한다. 로그 레벨은 다음과 같다.

  • DEBUG
  • INFO
  • WARNING
  • ERROR
  • CRITICAL

각 레벨은 중요도에 따라 순서가 정해져 있으며, 높은 레벨일수록 중요하다. 따라서, 예를 들어 로그 레벨을 INFO로 설정하면, INFO, WARNING, ERROR, CRITICAL 레벨의 메시지가 출력되지만, DEBUG 레벨의 메시지는 출력되지 않는다.

로그 위젯 만들기

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
'''
logviewerwidget.py
'''
import logging
from PyQt5.QtWidgets import *
from PyQt5.QtGui import QTextCursor
from PyQt5 import uic

# UI 파일 로드
form_class = uic.loadUiType("logviewerwidget.ui")[0]

class QPlainTextEditLogger(logging.Handler):
    # QPlainTextEdit 위젯에 로그 메시지를 쓰는 사용자 지정 로깅 핸들러
    def __init__(self, text_edit):
        super().__init__()
        self.text_edit = text_edit

    # QPlainTextEdit 위젯에 로그를 작성
    def emit(self, record):
        msg = self.format(record)
        cursor = self.text_edit.textCursor()
        cursor.movePosition(QTextCursor.End)
        cursor.insertText(msg + '\n')
        self.text_edit.setTextCursor(cursor)

class LogViewerWidget(QWidget, form_class):
    def __init__(self, parent=None):
        super(LogViewerWidget, self).__init__(parent)
        self.setupUi(self)

        # 버튼에 대한 이벤트 처리
        self.btnClearLog.clicked.connect(self.clear_log)
        self.btnCopyLog.clicked.connect(self.copy_log)
        self.btnSaveLog.clicked.connect(self.save_log)

        self.cmbLogLevel.currentTextChanged.connect(self.change_log_level)

        # 콤보 박스에 로그 레벨을 아이템으로 추가
        self.cmbLogLevel.addItem("DEBUG", logging.DEBUG)
        self.cmbLogLevel.addItem("INFO", logging.INFO)
        self.cmbLogLevel.addItem("WARNING", logging.WARNING)
        self.cmbLogLevel.addItem("ERROR", logging.ERROR)
        self.cmbLogLevel.addItem("CRITICAL", logging.CRITICAL)

        # 기본값으로 DEBUG를 선택
        self.cmbLogLevel.setCurrentIndex(self.cmbLogLevel.findData(logging.DEBUG))

        # 로그 출력 포맷 설정
        formatter = logging.Formatter('%(asctime)s [%(levelname)s] %(message)s')

        # 로그 핸들러 생성
        handler = QPlainTextEditLogger(self.txtLog)
        handler.setFormatter(formatter)

        # 로거 생성
        logging.getLogger().addHandler(handler)

    def change_log_level(self):
        current_text = self.cmbLogLevel.currentText()
        current_index = self.cmbLogLevel.findText(current_text)
        logging.getLogger().setLevel(self.cmbLogLevel.itemData(current_index))

    def add_horizontal_line(self):
        cursor = self.txtLog.textCursor()
        cursor.movePosition(QTextCursor.End)
        cursor.insertText('-' * 70 + '\n')
        self.txtLog.setTextCursor(cursor)

    def clear_log(self):
        self.txtLog.clear()

    def copy_log(self):
        # 텍스트 클립보드에 복사
        clipboard = QApplication.clipboard()
        clipboard.setText(self.txtLog.toPlainText())

    def save_log(self):
        filename, _ = QFileDialog.getSaveFileName(self, "Save Log File", "", "Text Files (*.txt)")
        if filename:
            with open(filename, "w") as f:
                f.write(self.txtLog.toPlainText())

QPlainTextEditLogger 클래스는 logging 핸들러를 상속받아서 emit() 함수를 오버라이드하고 PlainTextEdit 위젯에 로그를 출력하는 기능을 한다.

emit() 메서드는 logging 레코드가 발생할 때마다 호출되는데, 이 때 PlainTextEdit 위젯에 로그를 추가한다. 이렇게 하면 logging 라이브러리를 사용해서 발생하는 로그를 QPlainTextEditLogger 클래스를 통해 PlainTextEdit 위젯에 출력할 수 있다.

로그 위젯 사용하기

빈 폼 위에 LogViewerWidget로 승격한 widget을 추가하고 버튼을 추가해준다. 이 버튼을 누르면 준비된 로그가 작성된다.

qt_log_1

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
'''
example_logviewer.py
'''
import sys
import logging
from PyQt5.QtWidgets import *
from PyQt5 import uic

# UI 파일 로드
form_class = uic.loadUiType("example_logviewer.ui")[0]

class MyWindow(QWidget, form_class):
    def __init__(self):
        super().__init__()
        self.setupUi(self)

        self.btnLogRun.clicked.connect(self.print_log)

    def print_log(self):
        logging.debug('this is debug')
        logging.info('this is info')
        logging.warning('this is warning')
        logging.error('this is error')
        logging.critical('this is critical')
        self.logWidget.add_horizontal_line()

if __name__ == "__main__":
    # QApplication 인스턴스 생성
    app = QApplication(sys.argv)
    myWindow = MyWindow()
    myWindow.show()
    app.exec_()
  
qt_log_2qt_log_3

버튼은 왼쪽부터 차례대로 Save, Copy, Clear 기능을 한다.

Icon Source

This post is licensed under CC BY 4.0 by the author.
Trending Tags