WeChatMsg_NY/newYear/ui/version_compare.py

262 lines
9.2 KiB
Python
Raw Permalink Normal View History

2025-01-22 17:22:20 +08:00
from PyQt5.QtWidgets import (QDialog, QVBoxLayout, QHBoxLayout, QLabel,
QComboBox, QPushButton, QTextEdit, QFrame,
QScrollArea, QWidget)
from PyQt5.QtCore import Qt
from PyQt5.QtGui import QColor, QTextCharFormat, QTextCursor
import difflib
class VersionCompareDialog(QDialog):
"""版本比较对话框"""
def __init__(self, versions, parent=None):
super().__init__(parent)
# 按联系人分组版本
self.contact_versions = self.group_versions_by_contact(versions)
self.init_ui()
self.apply_style()
def group_versions_by_contact(self, versions):
"""将版本按联系人分组
Returns:
Dict[str, List[Dict]]: 以联系人wxid为键版本列表为值的字典
"""
grouped = {}
for version in versions:
contact = version['contact']
wxid = contact['wxid']
if wxid not in grouped:
grouped[wxid] = []
grouped[wxid].append(version)
return grouped
def init_ui(self):
"""初始化UI"""
self.setWindowTitle("版本比较")
self.setMinimumSize(800, 600)
layout = QVBoxLayout(self)
# 联系人选择
contact_layout = QHBoxLayout()
contact_layout.addWidget(QLabel("选择联系人:"))
self.contact_combo = QComboBox()
self.contact_combo.currentIndexChanged.connect(self.on_contact_changed)
contact_layout.addWidget(self.contact_combo)
layout.addLayout(contact_layout)
# 版本选择区域
select_layout = QHBoxLayout()
# 版本A选择
version_a_layout = QVBoxLayout()
version_a_layout.addWidget(QLabel("版本A"))
self.version_a_combo = QComboBox()
self.version_a_combo.currentIndexChanged.connect(self.compare_versions)
version_a_layout.addWidget(self.version_a_combo)
select_layout.addLayout(version_a_layout)
# 版本B选择
version_b_layout = QVBoxLayout()
version_b_layout.addWidget(QLabel("版本B"))
self.version_b_combo = QComboBox()
self.version_b_combo.currentIndexChanged.connect(self.compare_versions)
version_b_layout.addWidget(self.version_b_combo)
select_layout.addLayout(version_b_layout)
layout.addLayout(select_layout)
# 比较结果区域
scroll = QScrollArea()
scroll.setWidgetResizable(True)
scroll.setObjectName("compare-scroll")
content_widget = QWidget()
self.content_layout = QVBoxLayout(content_widget)
# 各部分内容比较
self.add_compare_section("新年祝福语", "greeting")
self.add_compare_section("美好祝愿", "wishes")
self.add_compare_section("祝福成语", "idioms")
self.add_compare_section("新年图片提示词", "image_prompt")
scroll.setWidget(content_widget)
layout.addWidget(scroll)
# 底部按钮
button_layout = QHBoxLayout()
close_btn = QPushButton("关闭")
close_btn.setObjectName("close-btn")
close_btn.clicked.connect(self.accept)
button_layout.addStretch()
button_layout.addWidget(close_btn)
layout.addLayout(button_layout)
# 初始化联系人列表
self.init_contacts()
def init_contacts(self):
"""初始化联系人列表"""
self.contact_combo.clear()
for wxid, versions in self.contact_versions.items():
if versions: # 确保有版本数据
contact_name = versions[0]['contact']['name'] # 使用第一个版本中的联系人名称
self.contact_combo.addItem(contact_name, wxid) # 使用wxid作为用户数据
def on_contact_changed(self, index):
"""联系人选择改变时的处理"""
if index < 0:
return
# 获取选中联系人的wxid
wxid = self.contact_combo.currentData()
versions = self.contact_versions.get(wxid, [])
# 更新版本选择框
self.version_a_combo.clear()
self.version_b_combo.clear()
contact_name = versions[0]['contact']['name']
for version in versions:
version_text = f"{contact_name} - 版本{version['version_number']} ({version['create_time']})"
self.version_a_combo.addItem(version_text, version)
self.version_b_combo.addItem(version_text, version)
# 默认选择最新的两个版本
if len(versions) >= 2:
self.version_a_combo.setCurrentIndex(len(versions) - 2)
self.version_b_combo.setCurrentIndex(len(versions) - 1)
def add_compare_section(self, title, content_key):
"""添加比较部分"""
section = QWidget()
layout = QVBoxLayout(section)
# 标题
title_label = QLabel(title)
title_label.setObjectName("title")
layout.addWidget(title_label)
# 内容比较区域
content_layout = QHBoxLayout()
# 版本A内容
text_a = QTextEdit()
text_a.setReadOnly(True)
setattr(self, f"{content_key}_a", text_a)
content_layout.addWidget(text_a)
# 版本B内容
text_b = QTextEdit()
text_b.setReadOnly(True)
setattr(self, f"{content_key}_b", text_b)
content_layout.addWidget(text_b)
layout.addLayout(content_layout)
self.content_layout.addWidget(section)
def compare_versions(self):
"""比较选中的两个版本"""
if self.version_a_combo.currentIndex() < 0 or self.version_b_combo.currentIndex() < 0:
return
version_a = self.version_a_combo.currentData()
version_b = self.version_b_combo.currentData()
if version_a and version_b:
self.compare_content("greeting", version_a, version_b)
self.compare_content("wishes", version_a, version_b)
self.compare_content("idioms", version_a, version_b)
self.compare_content("image_prompt", version_a, version_b)
def compare_content(self, content_key, version_a, version_b):
"""比较特定内容"""
text_a = version_a.get(content_key, '')
text_b = version_b.get(content_key, '')
# 获取文本框引用
text_edit_a = getattr(self, f"{content_key}_a")
text_edit_b = getattr(self, f"{content_key}_b")
# 清空文本框
text_edit_a.clear()
text_edit_b.clear()
# 计算差异
differ = difflib.Differ()
diff = list(differ.compare(text_a.splitlines(), text_b.splitlines()))
# 设置差异高亮格式
add_format = QTextCharFormat()
add_format.setBackground(QColor(200, 255, 200)) # 浅绿色背景
del_format = QTextCharFormat()
del_format.setBackground(QColor(255, 200, 200)) # 浅红色背景
# 显示差异
cursor_a = text_edit_a.textCursor()
cursor_b = text_edit_b.textCursor()
for line in diff:
if line.startswith('- '):
cursor_a.insertText(line[2:] + '\n', del_format)
cursor_b.insertText('\n')
elif line.startswith('+ '):
cursor_a.insertText('\n')
cursor_b.insertText(line[2:] + '\n', add_format)
else:
cursor_a.insertText(line[2:] + '\n')
cursor_b.insertText(line[2:] + '\n')
# 滚动到顶部
text_edit_a.verticalScrollBar().setValue(0)
text_edit_b.verticalScrollBar().setValue(0)
def apply_style(self):
"""应用样式"""
self.setStyleSheet("""
QDialog {
background-color: #F9F4E6;
min-width: 800px;
min-height: 600px;
}
QLabel {
color: #333333;
}
QLabel#title {
font-size: 18px;
font-weight: bold;
color: #D4341F;
padding: 10px;
}
QLabel#version-label {
font-size: 16px;
font-weight: bold;
color: #D4341F;
padding: 5px;
}
QTextEdit {
background-color: white;
border: 1px solid #E8C06F;
border-radius: 4px;
padding: 8px;
font-size: 14px;
}
QPushButton {
background-color: #E8C06F;
color: #333333;
border: none;
padding: 8px 16px;
border-radius: 4px;
min-width: 80px;
}
QPushButton:hover {
background-color: #D4B05F;
}
QPushButton#close-btn {
background-color: #D4341F;
color: white;
}
QPushButton#close-btn:hover {
background-color: #A61F14;
}
""")