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
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()
|
|
|
|
|