262 lines
9.2 KiB
Python
262 lines
9.2 KiB
Python
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;
|
||
}
|
||
""") |