完成日志界面的制作
This commit is contained in:
		@@ -1,25 +1,224 @@
 | 
			
		||||
from PySide6.QtWidgets import QWidget, QLabel
 | 
			
		||||
from PySide6.QtWidgets import QWidget, QLabel, QMessageBox, QVBoxLayout, QTreeWidget, QHBoxLayout, QPushButton, QFrame, QLineEdit, QCheckBox, QTreeWidgetItem, QDialog
 | 
			
		||||
from PySide6.QtCore import Qt, Signal
 | 
			
		||||
from PySide6.QtGui import QColor, QIcon, QFont, QKeySequence, QIntValidator, QShortcut
 | 
			
		||||
 | 
			
		||||
from codes.common.signal_bus import signal_bus
 | 
			
		||||
from codes.common import db_operation
 | 
			
		||||
from codes.common import clibs
 | 
			
		||||
 | 
			
		||||
class PageNumberInput(QDialog):
 | 
			
		||||
    def __init__(self, parent=None):
 | 
			
		||||
        super().__init__(parent)
 | 
			
		||||
        self.init_ui()
 | 
			
		||||
        self.setup_slot()
 | 
			
		||||
 | 
			
		||||
    def setup_slot(self):
 | 
			
		||||
        QShortcut(QKeySequence("Esc"), self).activated.connect(self.reject)
 | 
			
		||||
        self.le_page_number.returnPressed.connect(self.accept)
 | 
			
		||||
        self.le_page_number.returnPressed.connect(self.get_page_number)
 | 
			
		||||
 | 
			
		||||
    def init_ui(self):
 | 
			
		||||
        self.setMinimumSize(300,100)
 | 
			
		||||
        self.setMaximumSize(400,120)
 | 
			
		||||
        self.resize(300, 100)
 | 
			
		||||
        self.setWindowIcon(QIcon(clibs.icon))
 | 
			
		||||
        self.setWindowTitle("输入页码")
 | 
			
		||||
        layout_h = QHBoxLayout()
 | 
			
		||||
        layout_h.addStretch(1)
 | 
			
		||||
        self.le_page_number = QLineEdit(self)
 | 
			
		||||
        self.le_page_number.setText("1")
 | 
			
		||||
        self.le_page_number.selectAll()
 | 
			
		||||
        self.le_page_number.setFont(QFont('Consolas', 14))
 | 
			
		||||
        self.le_page_number.setValidator(QIntValidator(0, 9999999, self))
 | 
			
		||||
        layout_h.addWidget(self.le_page_number, stretch=4)
 | 
			
		||||
        layout_h.addStretch(1)
 | 
			
		||||
        self.setLayout(layout_h)
 | 
			
		||||
 | 
			
		||||
    def get_page_number(self):
 | 
			
		||||
        text = self.le_page_number.text()
 | 
			
		||||
        return 1 if text == 0 else int(text)
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
class ClickableLabel(QLabel):
 | 
			
		||||
    clicked = Signal()
 | 
			
		||||
 | 
			
		||||
    def mousePressEvent(self, event):
 | 
			
		||||
        if event.button() == Qt.MouseButton.LeftButton:
 | 
			
		||||
            self.clicked.emit()
 | 
			
		||||
        super().mousePressEvent(event)
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
class W08Log(QWidget):
 | 
			
		||||
    def __init__(self, parent=None):
 | 
			
		||||
        super().__init__(parent)
 | 
			
		||||
 | 
			
		||||
        self.predos()
 | 
			
		||||
        self.ui_init()
 | 
			
		||||
        self.setup_slot()
 | 
			
		||||
        self.setup_sc()
 | 
			
		||||
 | 
			
		||||
    def predos(self):
 | 
			
		||||
        ...
 | 
			
		||||
        self.records, self.len_records = "", ""
 | 
			
		||||
        self.is_searching = False
 | 
			
		||||
        self.max_item_number = clibs.config["log_number_per_page"]
 | 
			
		||||
 | 
			
		||||
    def ui_init(self):
 | 
			
		||||
        self.lb_test = QLabel(f"testing text on widget: \n{__file__}", parent=self)
 | 
			
		||||
        layout_v = QVBoxLayout(self)
 | 
			
		||||
        self.treeW = QTreeWidget()
 | 
			
		||||
        self.treeW.setHeaderLabels(["ID", "时间戳", "告警级别", "模块信息", "告警内容"])
 | 
			
		||||
        layout_v.addWidget(self.treeW, stretch=9)
 | 
			
		||||
 | 
			
		||||
        layout_h = QHBoxLayout()
 | 
			
		||||
        self.pb_previous = QPushButton("上一页")
 | 
			
		||||
        layout_h.addWidget(self.pb_previous, stretch=1)
 | 
			
		||||
 | 
			
		||||
        self.lb_page = ClickableLabel("999999/999999")
 | 
			
		||||
        self.lb_page.setAlignment(Qt.AlignmentFlag.AlignCenter)
 | 
			
		||||
        self.lb_page.setMinimumWidth(144)
 | 
			
		||||
        layout_h.addWidget(self.lb_page, stretch=2)
 | 
			
		||||
 | 
			
		||||
        self.pb_next = QPushButton("下一页")
 | 
			
		||||
        layout_h.addWidget(self.pb_next, stretch=1)
 | 
			
		||||
 | 
			
		||||
        layout_h.addStretch(9)
 | 
			
		||||
 | 
			
		||||
        self.frame_checkbox = QFrame()
 | 
			
		||||
        layout_h_checkbox = QHBoxLayout()
 | 
			
		||||
        self.box_info = QCheckBox("通知", parent=self.frame_checkbox)
 | 
			
		||||
        self.box_info.setChecked(True)
 | 
			
		||||
        layout_h_checkbox.addWidget(self.box_info, stretch=1)
 | 
			
		||||
        self.box_warning = QCheckBox("告警", parent=self.frame_checkbox)
 | 
			
		||||
        self.box_warning.setChecked(True)
 | 
			
		||||
        layout_h_checkbox.addWidget(self.box_warning, stretch=1)
 | 
			
		||||
        self.box_error = QCheckBox("错误", parent=self.frame_checkbox)
 | 
			
		||||
        self.box_error.setChecked(True)
 | 
			
		||||
        layout_h_checkbox.addWidget(self.box_error, stretch=1)
 | 
			
		||||
        self.box_exception = QCheckBox("异常", parent=self.frame_checkbox)
 | 
			
		||||
        self.box_exception.setChecked(True)
 | 
			
		||||
        layout_h_checkbox.addWidget(self.box_exception, stretch=1)
 | 
			
		||||
        self.box_unknown = QCheckBox("未知", parent=self.frame_checkbox)
 | 
			
		||||
        self.box_unknown.setChecked(True)
 | 
			
		||||
        layout_h_checkbox.addWidget(self.box_unknown, stretch=1)
 | 
			
		||||
        layout_h.addLayout(layout_h_checkbox, stretch=4)
 | 
			
		||||
 | 
			
		||||
        self.le_search = QLineEdit()
 | 
			
		||||
        self.le_search.setPlaceholderText("告警内容")
 | 
			
		||||
        self.le_search.setMinimumWidth(300)
 | 
			
		||||
        layout_h.addWidget(self.le_search, stretch=5)
 | 
			
		||||
 | 
			
		||||
        self.pb_search = QPushButton("查找")
 | 
			
		||||
        layout_h.addWidget(self.pb_search, stretch=1)
 | 
			
		||||
 | 
			
		||||
        layout_v.addLayout(layout_h, stretch=1)
 | 
			
		||||
 | 
			
		||||
        self.setLayout(layout_v)
 | 
			
		||||
 | 
			
		||||
    def setup_slot(self):
 | 
			
		||||
        ...
 | 
			
		||||
        self.pb_previous.clicked.connect(self.previous_page)
 | 
			
		||||
        self.pb_next.clicked.connect(self.next_page)
 | 
			
		||||
        self.pb_search.clicked.connect(self.search_page)
 | 
			
		||||
        self.le_search.returnPressed.connect(self.search_page)
 | 
			
		||||
        self.lb_page.clicked.connect(self.goto_page)
 | 
			
		||||
        signal_bus.stacked_page_switch_log.connect(self.show_latest_page)
 | 
			
		||||
 | 
			
		||||
    def setup_sc(self):
 | 
			
		||||
        ...
 | 
			
		||||
 | 
			
		||||
    def previous_page(self):
 | 
			
		||||
        if not self.is_searching:
 | 
			
		||||
            self.records, self.len_records = db_operation.db_query_logs(True)
 | 
			
		||||
        current, total = self.lb_page.text().split("/")
 | 
			
		||||
        page_number = int(current) - 1
 | 
			
		||||
        self.show_page(self.records, self.len_records, page_number=page_number)
 | 
			
		||||
 | 
			
		||||
    def next_page(self):
 | 
			
		||||
        if not self.is_searching:
 | 
			
		||||
            self.records, self.len_records = db_operation.db_query_logs(True)
 | 
			
		||||
        current, total = self.lb_page.text().split("/")
 | 
			
		||||
        page_number = int(current) + 1
 | 
			
		||||
        self.show_page(self.records, self.len_records, page_number=page_number)
 | 
			
		||||
 | 
			
		||||
    def search_page(self):
 | 
			
		||||
        filters = {"info": self.box_info.isChecked(), "warning": self.box_warning.isChecked(), "error": self.box_error.isChecked(), "exception": self.box_exception.isChecked(), "unknown": self.box_unknown.isChecked()}
 | 
			
		||||
        search_text = self.le_search.text().strip()
 | 
			
		||||
        flag, levels = False, []
 | 
			
		||||
        for level, enable in filters.items():
 | 
			
		||||
            if not enable:
 | 
			
		||||
                continue
 | 
			
		||||
            flag = True
 | 
			
		||||
            levels.append(level)
 | 
			
		||||
 | 
			
		||||
        if not flag:
 | 
			
		||||
            QMessageBox().warning(None, "警告", "至少选择一个过滤器!")
 | 
			
		||||
            return
 | 
			
		||||
 | 
			
		||||
        self.records, self.len_records = db_operation.db_query_logs(levels=levels)
 | 
			
		||||
        if search_text:
 | 
			
		||||
            # ids = [_[0] for _ in self.records]
 | 
			
		||||
            # placeholder = ",".join(ids)
 | 
			
		||||
            # clibs.cursor.execute(f"SELECT * FROM logs WHERE id IN ({placeholder}) and content like ?", (ids + [search_text, ]))
 | 
			
		||||
            self.records, self.len_records = db_operation.db_query_logs(search_text, self.records)
 | 
			
		||||
 | 
			
		||||
        self.is_searching = True
 | 
			
		||||
        self.show_page(self.records, self.len_records, page_number=None)
 | 
			
		||||
 | 
			
		||||
    def goto_page(self):
 | 
			
		||||
        dlg = PageNumberInput()
 | 
			
		||||
        if dlg.exec() != 1:
 | 
			
		||||
            return
 | 
			
		||||
 | 
			
		||||
        page_number = dlg.get_page_number()
 | 
			
		||||
        if not self.is_searching:
 | 
			
		||||
            self.records, self.len_records = db_operation.db_query_logs(True)
 | 
			
		||||
        self.show_page(self.records, self.len_records, page_number=page_number)
 | 
			
		||||
 | 
			
		||||
    def show_latest_page(self):
 | 
			
		||||
        self.records, self.len_records = db_operation.db_query_logs(True)
 | 
			
		||||
        self.is_searching = False
 | 
			
		||||
        self.box_info.setChecked(True)
 | 
			
		||||
        self.box_warning.setChecked(True)
 | 
			
		||||
        self.box_error.setChecked(True)
 | 
			
		||||
        self.box_exception.setChecked(True)
 | 
			
		||||
        self.box_unknown.setChecked(True)
 | 
			
		||||
        self.le_search.clear()
 | 
			
		||||
        self.show_page(self.records, self.len_records, page_number=None)
 | 
			
		||||
 | 
			
		||||
    def show_page(self, records, len_records, page_number: int | None):
 | 
			
		||||
        if len_records == 0:
 | 
			
		||||
            self.treeW.clear()
 | 
			
		||||
            return
 | 
			
		||||
 | 
			
		||||
        remainder = len_records % self.max_item_number
 | 
			
		||||
        total = len_records // self.max_item_number + 1 if remainder else len_records // self.max_item_number
 | 
			
		||||
        if page_number is None:
 | 
			
		||||
            current = total
 | 
			
		||||
        elif page_number <= 0:
 | 
			
		||||
            current = 1
 | 
			
		||||
        elif page_number < total:
 | 
			
		||||
            current = page_number
 | 
			
		||||
        else:
 | 
			
		||||
            current = total
 | 
			
		||||
        self.lb_page.setText(f"{current}/{total}")
 | 
			
		||||
 | 
			
		||||
        if current == 1:
 | 
			
		||||
            idx_start = 0
 | 
			
		||||
            idx_end = self.max_item_number if len_records >= self.max_item_number else len_records
 | 
			
		||||
        elif current == total:
 | 
			
		||||
            remainder = len_records % self.max_item_number
 | 
			
		||||
            idx_start = len_records - remainder if remainder else len_records - self.max_item_number
 | 
			
		||||
            idx_end = len_records
 | 
			
		||||
        else:
 | 
			
		||||
            idx_start = self.max_item_number * (current-1)
 | 
			
		||||
            idx_end = self.max_item_number * current
 | 
			
		||||
 | 
			
		||||
        self.treeW.clear()
 | 
			
		||||
        for record in records[idx_start:idx_end]:
 | 
			
		||||
            record = [str(_) for _ in record]
 | 
			
		||||
            item = QTreeWidgetItem(self.treeW, record)
 | 
			
		||||
            self.treeW.addTopLevelItem(item)
 | 
			
		||||
            colors = {"info": QColor(144, 238, 144), "warning": QColor(255, 240, 210), "error": QColor(255, 220, 220), "exception": QColor(255, 220, 220), "unknown": QColor(255, 220, 220)}
 | 
			
		||||
            color = colors[record[2]]
 | 
			
		||||
            for col in range(5):
 | 
			
		||||
                item.setBackground(col, color)
 | 
			
		||||
        self.treeW.scrollToBottom()
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
		Reference in New Issue
	
	Block a user