You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

343 lines
12 KiB
Python

import sys
from PyQt5 import QtCore
from PyQt5.QtCore import QAbstractTableModel, QModelIndex, pyqtSignal, QSize
from PyQt5.QtGui import QFont, QBrush, QColor
from PyQt5.QtWidgets import (QWidget, QVBoxLayout, QHBoxLayout, QTableView,
QPushButton, QLabel, QLineEdit, QComboBox,
QDialog, QFormLayout, QDialogButtonBox, QMessageBox,
QHeaderView, QMenu, QAction, QToolBar, QSpinBox)
import qtawesome as qta
from datetime import datetime
class KeywordTableModel(QAbstractTableModel):
"""关键词表格模型"""
columns = ['ID', '关键词', '操作类型', '描述', '创建时间']
def __init__(self, dbManager):
super().__init__()
self.dbManager = dbManager
self.keywordData = []
self.loadData()
def loadData(self):
"""加载数据"""
self.beginResetModel()
self.keywordData = self.dbManager.getStepKeywords()
# 按ID排序确保顺序正确
if self.keywordData:
self.keywordData.sort(key=lambda x: x[0]) # 按第一列(ID)排序
self.endResetModel()
def rowCount(self, parent=QModelIndex()):
return len(self.keywordData)
def columnCount(self, parent=QModelIndex()):
return len(self.columns)
def data(self, index, role=QtCore.Qt.DisplayRole):
if not index.isValid():
return None
row = index.row()
col = index.column()
if row >= len(self.keywordData):
return None
keywordInfo = self.keywordData[row]
if role == QtCore.Qt.DisplayRole:
if col == 0:
return str(row + 1) # 显示行号作为ID
elif col == 1:
return keywordInfo[1] # 关键词
elif col == 2:
return keywordInfo[2] # 操作类型
elif col == 3:
return keywordInfo[3] or "" # 描述
elif col == 4:
return keywordInfo[4] # 创建时间
elif role == QtCore.Qt.BackgroundRole:
if row % 2 == 0:
return QBrush(QColor(245, 245, 245))
else:
return QBrush(QColor(255, 255, 255))
elif role == QtCore.Qt.FontRole:
font = QFont()
if col == 1: # 关键词列加粗
font.setBold(True)
return font
return None
def headerData(self, section, orientation, role):
if role == QtCore.Qt.DisplayRole and orientation == QtCore.Qt.Horizontal:
return self.columns[section]
return None
def getKeywordInfo(self, row):
"""获取指定行的关键词信息"""
if 0 <= row < len(self.keywordData):
return {
'id': self.keywordData[row][0],
'keyword': self.keywordData[row][1],
'operationType': self.keywordData[row][2],
'description': self.keywordData[row][3],
'createdAt': self.keywordData[row][4]
}
return None
class KeywordEditDialog(QDialog):
"""关键词编辑对话框"""
def __init__(self, parent=None, keywordInfo=None):
super().__init__(parent)
self.keywordInfo = keywordInfo
self.isEdit = keywordInfo is not None
self.setWindowTitle("编辑关键词" if self.isEdit else "添加关键词")
self.setFixedSize(500, 300)
self.setupUi()
if self.isEdit:
self.loadKeywordInfo()
def setupUi(self):
"""设置界面"""
layout = QVBoxLayout()
formLayout = QFormLayout()
self.keywordEdit = QLineEdit()
self.keywordEdit.setPlaceholderText("请输入关键词")
formLayout.addRow("关键词:", self.keywordEdit)
self.operationTypeCombo = QComboBox()
self.operationTypeCombo.addItems(['set', 'check', 'wait', 'deltaT'])
formLayout.addRow("操作类型:", self.operationTypeCombo)
self.descriptionEdit = QLineEdit()
self.descriptionEdit.setPlaceholderText("请输入描述(可选)")
formLayout.addRow("描述:", self.descriptionEdit)
layout.addLayout(formLayout)
buttonBox = QDialogButtonBox(QDialogButtonBox.Ok | QDialogButtonBox.Cancel)
buttonBox.accepted.connect(self.accept)
buttonBox.rejected.connect(self.reject)
layout.addWidget(buttonBox)
self.setLayout(layout)
def loadKeywordInfo(self):
"""加载关键词信息"""
if self.keywordInfo:
self.keywordEdit.setText(self.keywordInfo['keyword'])
self.operationTypeCombo.setCurrentText(self.keywordInfo['operationType'])
self.descriptionEdit.setText(self.keywordInfo['description'] or "")
def getKeywordData(self):
"""获取关键词数据"""
return {
'keyword': self.keywordEdit.text().strip(),
'operationType': self.operationTypeCombo.currentText(),
'description': self.descriptionEdit.text().strip()
}
class KeywordManagerWidget(QWidget):
"""关键词字段库管理界面"""
def __init__(self, dbManager, parent=None):
super().__init__(parent)
self.dbManager = dbManager
self.setupUi()
self.setupToolbar()
self.setupContextMenu()
def setupUi(self):
"""设置界面"""
layout = QVBoxLayout()
# 创建工具栏
self.toolbar = QToolBar("关键词管理工具栏")
self.toolbar.setIconSize(QSize(24, 24))
layout.addWidget(self.toolbar)
# 创建表格
self.tableModel = KeywordTableModel(self.dbManager)
self.tableView = QTableView()
self.tableView.setModel(self.tableModel)
self.tableView.setSelectionBehavior(QTableView.SelectRows)
self.tableView.setSelectionMode(QTableView.SingleSelection)
self.tableView.setContextMenuPolicy(QtCore.Qt.CustomContextMenu)
self.tableView.customContextMenuRequested.connect(self.showContextMenu)
# 设置表格样式
self.setupTableStyle()
layout.addWidget(self.tableView)
# 创建状态栏
self.statusLabel = QLabel("就绪")
layout.addWidget(self.statusLabel)
self.setLayout(layout)
def setupToolbar(self):
"""设置工具栏"""
# 添加关键词
addAction = QAction(qta.icon('fa5s.plus', color='green'), "添加关键词", self)
addAction.triggered.connect(self.addKeyword)
self.toolbar.addAction(addAction)
# 编辑关键词
editAction = QAction(qta.icon('fa5s.edit', color='blue'), "编辑关键词", self)
editAction.triggered.connect(self.editKeyword)
self.toolbar.addAction(editAction)
# 删除关键词
deleteAction = QAction(qta.icon('fa5s.trash', color='red'), "删除关键词", self)
deleteAction.triggered.connect(self.deleteKeyword)
self.toolbar.addAction(deleteAction)
self.toolbar.addSeparator()
# 刷新
refreshAction = QAction(qta.icon('fa5s.sync', color='orange'), "刷新", self)
refreshAction.triggered.connect(self.refreshData)
self.toolbar.addAction(refreshAction)
def setupTableStyle(self):
"""设置表格样式"""
header = self.tableView.horizontalHeader()
if header:
header.setSectionResizeMode(0, QHeaderView.ResizeToContents) # ID
header.setSectionResizeMode(1, QHeaderView.Stretch) # 关键词
header.setSectionResizeMode(2, QHeaderView.ResizeToContents) # 操作类型
header.setSectionResizeMode(3, QHeaderView.Stretch) # 描述
header.setSectionResizeMode(4, QHeaderView.ResizeToContents) # 创建时间
# 设置交替行颜色
self.tableView.setAlternatingRowColors(False)
# 设置表格不可编辑
self.tableView.setEditTriggers(QTableView.NoEditTriggers)
def setupContextMenu(self):
"""设置右键菜单"""
self.tableView.customContextMenuRequested.connect(self.showContextMenu)
def showContextMenu(self, pos):
"""显示右键菜单"""
index = self.tableView.indexAt(pos)
if not index.isValid():
return
menu = QMenu()
editAction = menu.addAction("编辑关键词")
editAction.triggered.connect(self.editKeyword)
deleteAction = menu.addAction("删除关键词")
deleteAction.triggered.connect(self.deleteKeyword)
if hasattr(self.tableView, 'viewport') and hasattr(self.tableView.viewport(), 'mapToGlobal'):
menu.exec_(self.tableView.viewport().mapToGlobal(pos))
def addKeyword(self):
"""添加关键词"""
dialog = KeywordEditDialog(self)
if dialog.exec_() == QDialog.Accepted:
keywordData = dialog.getKeywordData()
if not keywordData['keyword']:
QMessageBox.warning(self, "输入错误", "关键词不能为空")
return
keywordId = self.dbManager.addStepKeyword(
keywordData['keyword'],
keywordData['operationType'],
keywordData['description']
)
if keywordId:
self.tableModel.loadData()
self.statusLabel.setText(f"成功添加关键词: {keywordData['keyword']}")
else:
QMessageBox.warning(self, "添加失败", "关键词已存在或添加失败")
def editKeyword(self):
"""编辑关键词"""
currentRow = self.tableView.currentIndex().row()
if currentRow < 0:
QMessageBox.information(self, "提示", "请先选择要编辑的关键词")
return
keywordInfo = self.tableModel.getKeywordInfo(currentRow)
if not keywordInfo:
return
dialog = KeywordEditDialog(self, keywordInfo)
if dialog.exec_() == QDialog.Accepted:
keywordData = dialog.getKeywordData()
if not keywordData['keyword']:
QMessageBox.warning(self, "输入错误", "关键词不能为空")
return
success = self.dbManager.updateStepKeyword(
keywordInfo['id'],
keywordData['keyword'],
keywordData['operationType'],
keywordData['description']
)
if success:
self.tableModel.loadData()
self.statusLabel.setText(f"成功更新关键词: {keywordData['keyword']}")
else:
QMessageBox.warning(self, "更新失败", "关键词已存在或更新失败")
def deleteKeyword(self):
"""删除关键词"""
currentRow = self.tableView.currentIndex().row()
if currentRow < 0:
QMessageBox.information(self, "提示", "请先选择要删除的关键词")
return
keywordInfo = self.tableModel.getKeywordInfo(currentRow)
if not keywordInfo:
return
reply = QMessageBox.question(
self,
"确认删除",
f"确定要删除关键词 '{keywordInfo['keyword']}' 吗?",
QMessageBox.Yes | QMessageBox.No
)
if reply == QMessageBox.Yes:
success = self.dbManager.deleteStepKeyword(keywordInfo['id'])
if success:
self.tableModel.loadData()
self.statusLabel.setText(f"成功删除关键词: {keywordInfo['keyword']}")
else:
QMessageBox.warning(self, "删除失败", "删除关键词失败")
def refreshData(self):
"""刷新数据"""
self.tableModel.loadData()
self.statusLabel.setText("数据已刷新")
def getKeywordByText(self, text):
"""根据文本获取关键词"""
return self.dbManager.getKeywordByText(text)
def getOperationTypes(self):
"""获取所有操作类型"""
return self.dbManager.getOperationTypes()