first commit

This commit is contained in:
2026-04-03 21:50:36 +08:00
commit 10843a5bc5
43 changed files with 3958 additions and 0 deletions
+222
View File
@@ -0,0 +1,222 @@
"""标准对话框(QMessageBox / QInputDialog / QFileDialog)与当前主题一致。"""
from __future__ import annotations
from PyQt6.QtWidgets import (
QFileDialog,
QInputDialog,
QMessageBox,
QWidget,
QDialog,
)
import ui.theme as theme
def stylesheet() -> str:
t = theme.current()
bg = t["menu_bg"]
fg = t["menu_color"]
border = t["menu_border"]
hover = t["menu_selected"]
inp = t["search_bg"]
inp_b = t["search_border"]
focus = t["search_focus"]
return f"""
QMessageBox {{
background-color: {bg};
color: {fg};
}}
QMessageBox QLabel {{
color: {fg};
background: transparent;
min-width: 160px;
}}
QMessageBox QPushButton {{
min-width: 64px;
padding: 6px 14px;
border: 1px solid {border};
border-radius: 5px;
background: {inp};
color: {fg};
}}
QMessageBox QPushButton:hover {{
background: {hover};
}}
QMessageBox QPushButton:default {{
border-color: {focus};
}}
QInputDialog {{
background-color: {bg};
color: {fg};
}}
QInputDialog QLabel {{
color: {fg};
background: transparent;
}}
QInputDialog QLineEdit {{
background: {inp};
border: 1px solid {inp_b};
border-radius: 5px;
padding: 6px 8px;
color: {fg};
min-width: 260px;
}}
QInputDialog QLineEdit:focus {{
border-color: {focus};
}}
QInputDialog QPushButton {{
min-width: 72px;
padding: 6px 14px;
border: 1px solid {border};
border-radius: 5px;
background: {inp};
color: {fg};
}}
QInputDialog QPushButton:hover {{
background: {hover};
}}
QFileDialog {{
background-color: {bg};
color: {fg};
}}
QFileDialog QLabel {{
color: {fg};
background: transparent;
}}
QFileDialog QLineEdit, QFileDialog QComboBox {{
background: {inp};
border: 1px solid {inp_b};
border-radius: 4px;
padding: 4px 6px;
color: {fg};
}}
QFileDialog QLineEdit:focus, QFileDialog QComboBox:focus {{
border-color: {focus};
}}
QFileDialog QTreeView, QFileDialog QListView, QFileDialog QTableView {{
background: {inp};
border: 1px solid {inp_b};
border-radius: 4px;
color: {fg};
outline: none;
}}
QFileDialog QTreeView::item:selected, QFileDialog QListView::item:selected {{
background: {hover};
}}
QFileDialog QPushButton {{
min-width: 72px;
padding: 6px 12px;
border: 1px solid {border};
border-radius: 5px;
background: {inp};
color: {fg};
}}
QFileDialog QPushButton:hover {{
background: {hover};
}}
QFileDialog QComboBox QAbstractItemView {{
background: {bg};
color: {fg};
border: 1px solid {border};
}}
"""
def _apply(w: QWidget | None) -> None:
if w is not None:
w.setStyleSheet(stylesheet())
def question(
parent: QWidget | None,
title: str,
text: str,
*,
buttons: QMessageBox.StandardButton = (
QMessageBox.StandardButton.Yes | QMessageBox.StandardButton.No
),
default_button: QMessageBox.StandardButton | None = None,
icon: QMessageBox.Icon = QMessageBox.Icon.Question,
) -> QMessageBox.StandardButton:
msg = QMessageBox(parent)
msg.setWindowTitle(title)
msg.setText(text)
msg.setIcon(icon)
msg.setStandardButtons(buttons)
if default_button is not None:
msg.setDefaultButton(default_button)
_apply(msg)
# 防止对话框因为文本长度/默认最小宽度变得过宽
msg.setFixedWidth(320)
return QMessageBox.StandardButton(msg.exec())
def warning(parent: QWidget | None, title: str, text: str) -> None:
msg = QMessageBox(parent)
msg.setWindowTitle(title)
msg.setText(text)
msg.setIcon(QMessageBox.Icon.Warning)
msg.setStandardButtons(QMessageBox.StandardButton.Ok)
_apply(msg)
msg.setFixedWidth(320)
msg.exec()
def information(parent: QWidget | None, title: str, text: str) -> None:
msg = QMessageBox(parent)
msg.setWindowTitle(title)
msg.setText(text)
msg.setIcon(QMessageBox.Icon.Information)
msg.setStandardButtons(QMessageBox.StandardButton.Ok)
_apply(msg)
msg.setFixedWidth(320)
msg.exec()
def get_text(
parent: QWidget | None,
title: str,
label: str,
text: str = "",
) -> tuple[str, bool]:
d = QInputDialog(parent)
d.setWindowTitle(title)
d.setLabelText(label)
d.setTextValue(text)
_apply(d)
ok = d.exec() == QDialog.DialogCode.Accepted
return d.textValue(), ok
def get_open_file_name(
parent: QWidget | None,
caption: str,
directory: str,
filter_str: str,
) -> tuple[str, str]:
fd = QFileDialog(parent, caption, directory, filter_str)
fd.setOption(QFileDialog.Option.DontUseNativeDialog, True)
fd.setFileMode(QFileDialog.FileMode.ExistingFile)
_apply(fd)
if fd.exec() == QDialog.DialogCode.Accepted:
files = fd.selectedFiles()
if files:
return files[0], fd.selectedNameFilter()
return "", ""
def get_existing_directory(
parent: QWidget | None,
caption: str,
directory: str = "",
) -> str:
fd = QFileDialog(parent, caption, directory)
fd.setOption(QFileDialog.Option.DontUseNativeDialog, True)
fd.setFileMode(QFileDialog.FileMode.Directory)
fd.setOption(QFileDialog.Option.ShowDirsOnly, True)
_apply(fd)
if fd.exec() == QDialog.DialogCode.Accepted:
files = fd.selectedFiles()
if files:
return files[0]
return ""