diff --git a/components/main_interface.py b/components/main_interface.py index 173980e..0d6eb52 100644 --- a/components/main_interface.py +++ b/components/main_interface.py @@ -1,9 +1,9 @@ from datetime import datetime, timezone from zoneinfo import ZoneInfo from PySide6.QtWidgets import QWidget, QVBoxLayout, QHBoxLayout, QAbstractItemView -from PySide6.QtCore import QAbstractTableModel, QModelIndex, Qt +from PySide6.QtCore import QAbstractTableModel, QModelIndex, Qt, QSortFilterProxyModel from qfluentwidgets import ( - PushButton, TableView, FluentIcon as Fi, + PushButton, TableView, FluentIcon as Fi, PillPushButton ) from common.utils import SAFE_MAP_ICON, SAFE_MAP @@ -79,6 +79,22 @@ class ExtensionsDataTable(QAbstractTableModel): return dt.strftime(custom_format) +class SafeFilterProxyModel(QSortFilterProxyModel): + + def __init__(self, parent=None): + super().__init__(parent) + self.accepted_status = set() + + def set_accepted_status(self, status: list[int]): + self.accepted_status = set(status) + self.invalidateFilter() + + def filterAcceptsRow(self, source_row: int, source_parent, /): + index = self.sourceModel().index(source_row, 2, source_parent) + ext_d: dict[str, str | int] = self.sourceModel().data(index, Qt.ItemDataRole.UserRole) + return ext_d["SAFE"] in self.accepted_status + + class MainInterface(QWidget): def __init__(self, ext_data: list[dict[str, str | int]] = None, parent=None): @@ -92,15 +108,33 @@ class MainInterface(QWidget): self.pbn_add = PushButton(Fi.ADD, "添加", self) self.pbn_delete = PushButton(Fi.DELETE, "删除", self) + safe_checks = [ + ("安全", 1), ("未知", 0), ("不安全", -1), ("未记录", -2), + ] + self.safe_switches: list[PillPushButton] = [] + for text, m in safe_checks: + c = PillPushButton(self) + c.setText(text) + c.setIcon(SAFE_MAP_ICON[m]) + c.setProperty("mark", m) + c.toggled.connect(self.update_filter) + self.safe_switches.append(c) + self.hly_top.addWidget(self.pbn_refresh) self.hly_top.addWidget(self.pbn_add) self.hly_top.addWidget(self.pbn_delete) self.hly_top.addStretch(1) + for c in self.safe_switches: + self.hly_top.addWidget(c) self.vly_m.addLayout(self.hly_top) self.tbv_m = TableView(self) self.ext_model = ExtensionsDataTable(ext_data, self) - self.tbv_m.setModel(self.ext_model) + self.fil_model = SafeFilterProxyModel(self) + self.fil_model.setSourceModel(self.ext_model) + + self.tbv_m.setModel(self.fil_model) + self.tbv_m.setSortingEnabled(True) self.tbv_m.setEditTriggers(QAbstractItemView.EditTrigger.NoEditTriggers) self.tbv_m.setSelectionBehavior(QAbstractItemView.SelectionBehavior.SelectRows) # 整行选中 self.tbv_m.setSelectionMode(QAbstractItemView.SelectionMode.SingleSelection) # 只允许单选 @@ -113,4 +147,16 @@ class MainInterface(QWidget): self.tbv_m.setColumnWidth(1, 200) self.tbv_m.setColumnWidth(3, 180) - self.vly_m.addWidget(self.tbv_m) \ No newline at end of file + self.vly_m.addWidget(self.tbv_m) + + # 放到最后 + for c in self.safe_switches: + c.setChecked(True) + + def update_filter(self, checked: bool): + accepted_status = [] + for c in self.safe_switches: + if c.isChecked(): + accepted_status.append(c.property("mark")) + + self.fil_model.set_accepted_status(accepted_status) diff --git a/components/main_window.py b/components/main_window.py index 6de72e0..37b01dd 100644 --- a/components/main_window.py +++ b/components/main_window.py @@ -1,7 +1,7 @@ from PySide6.QtWidgets import QApplication from PySide6.QtCore import Qt, QThread, QModelIndex from PySide6.QtGui import QIcon -from qfluentwidgets import MSFluentWindow, setTheme, Theme, InfoBar, FluentIcon as Fi +from qfluentwidgets import MSFluentWindow, setTheme, Theme, InfoBar, FluentIcon as Fi, InfoBarPosition from common.utils import show_quick_tip, accept_warning from common.api_worker import ApiWorker @@ -59,7 +59,8 @@ class MainWindow(MSFluentWindow): def handle_operation_finished(self, result: dict): """添加/更新/删除成功后的通用处理器""" - InfoBar.success("", "操作已成功完成。", duration=2000, parent=self.window()) + InfoBar.success("", "操作已成功完成。", duration=2000, + position=InfoBarPosition.BOTTOM_RIGHT, parent=self.window()) self.worker.do_query_all() # 重新加载数据 def handle_error(self, error_message: str):