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.

455 lines
19 KiB
Python

from PyQt5.QtWidgets import QTabWidget, QDockWidget, QTableView, QHeaderView, QTableWidget, QMessageBox,\
QAbstractItemView, QMenu, QWidget, QTextBrowser, QFrame, QGridLayout, QLabel, QWidget, QVBoxLayout, QMainWindow
from PyQt5.QtWebEngineWidgets import *
from PyQt5.QtGui import QStandardItemModel, QStandardItem, QBrush, QCursor, QColor
from PyQt5.QtCore import Qt, QCoreApplication, QMetaObject, QUrl, QFileInfo
from DcsUi.DockCLass import NewDockWidget
from utils.ClientModels import Usecase, UsecaseGroup, Procedure
from PyQt5.QAxContainer import QAxWidget
import openpyxl
import json
import sys
import os
import docx
from pydocx import PyDocX
tittle = ['序号', '实验步骤', '执行时间', '操作类型', '执行结果', '备注', '是否符合预期']
class TabDockWidget(NewDockWidget):
def __init__(self, title, parent = None):
NewDockWidget.__init__(self, title, parent=parent)
self.ExcelTab = QTabWidget()
self.ExcelTab.setTabsClosable(True)
self.ExcelTab.tabCloseRequested.connect(self.closeTab)
self.parent = parent
# def addExcel(self, path):
# if path:
# self.TabelView = ExcelTabelView(path, self.parent)
# self.ExcelTab.addTab (self.TabelView, '规程:' + os.path.basename(path))
# self.setWidget(self.ExcelTab)
def addExcel(self, path):
if path:
self.TabelView = ProWidget(path, self.parent)
self.ExcelTab.addTab (self.TabelView, '规程:' + os.path.basename(path))
self.setWidget(self.ExcelTab)
def addUseCase(self, usecaseName):
self.TabelView = UsecaseTabelView(usecaseName, self.parent)
self.ExcelTab.addTab (self.TabelView, '用例:' + usecaseName)
self.setWidget(self.ExcelTab)
def addUsecaseGroup(self, allCases):
self.TabelView = ProWidget(allCases, self.parent)
self.ExcelTab.addTab (self.TabelView, 'TEST1')
self.setWidget(self.ExcelTab)
def closeTab(self, index):
if not self.parent.ProcedureThread._isWork or index != self.ExcelTab.indexOf(self.parent.ProcedureThread.procedureExcel):
self.ExcelTab.removeTab(index)
else:
reply = QMessageBox.question(self, '提示', '请先退出正在运行的规程!', QMessageBox.Yes)
class ExcelTabelView(QTableView):
def __init__(self, path, parent):
QTableView.__init__(self)
self.parent = parent
if os.path.exists(path):
self.model = QStandardItemModel(0,0)
self.addExcelContent(path)
self.setModel(self.model)
self.resizeRowsToContents()
self.horizontalHeader().setStretchLastSection(True)
self.setEditTriggers(QAbstractItemView.NoEditTriggers)
self.horizontalHeader().setSectionResizeMode(QHeaderView.Stretch)
# self.horizontalHeader().setPropertySectionResizeMode(QHeaderView.ResizeToContents);
self.verticalHeader().setSectionResizeMode(QHeaderView.Fixed);
self.setContextMenuPolicy(Qt.CustomContextMenu) # 右键菜单
self.customContextMenuRequested.connect(self.showContextMenu) # 菜单连接信号
self.type = 'procedure'
def addExcelContent(self,path):
self.setUpdatesEnabled(False)
wb = openpyxl.load_workbook(path)
ws = wb.active
self.rowsCon = ws.rows
for row in ws.rows:
self.model.appendRow([QStandardItem(str(x.value)) if x.value is not None else QStandardItem(' ') for x in row])
self.rowsLen = ws.max_column
self.colsLen = ws.max_row
self.rowsCon = [x for x in self.rowsCon]
self.setUpdatesEnabled(True)
def changeRowColor(self, rowIndex, res):
if res:
brush = QBrush(QColor(0,255,154))
else:
brush = QBrush(QColor(220,20,60))
if rowIndex < 0:
for x in range(self.rowsLen):
self.model.setData(self.model.index(abs(rowIndex), x), brush, Qt.BackgroundRole)
else:
for x in range(self.rowsLen):
self.model.setData(self.model.index(rowIndex, x), brush, Qt.BackgroundRole)
# self.model.setData(self.model.index(rowIndex -1, x), QBrush(Qt.gray), Qt.BackgroundRole)
def getRowContent(self, rowIndex):
try:
rowCon = self.model.item(rowIndex, 1).text()
except:
try:
if 'STEP' in self.model.item(rowIndex, 1).text():
return None
except:
return None
return '全部'
return rowCon
def showContextMenu(self): # 创建右键菜单、
self.contextMenu = QMenu(self)
self.actionA = self.contextMenu.addAction('从选中行开始执行')
self.contextMenu.popup(QCursor.pos()) # 2菜单显示的位置
self.actionA.triggered.connect(self.actionHandler)
self.contextMenu.show()
def actionHandler(self):
if self.parent.ProcedureThread._isPause and self.parent.ProcedureThread._isWork:
self.parent.procedureRunIndex = self.currentIndex().row()
self.parent.ProcedureThread.resume()
else:
self.parent.procedureRunIndex = self.currentIndex().row()
self.parent.procedureAutoRunClicked()
self.parent.log.infoLog(f'{self.parent.procedureRunPath}规程从{self.currentIndex().row()}行开始执行')
class UsecaseTabelView(QTableView):
def __init__(self, usecaseName, parent):
QTableView.__init__(self)
self.parent = parent
self.type = 'usecase'
self.colIndex = 0
self.rowIndex = 2
self.usecaseName = usecaseName
self.usecaseOperation = json.loads(Usecase.get_by_name(usecaseName).operation)
self.model = QStandardItemModel(0,0)
self.addExcelContent()
self.setModel(self.model)
self.resizeRowsToContents()
self.horizontalHeader().setStretchLastSection(True)
self.horizontalHeader().setSectionResizeMode(QHeaderView.Stretch)
# self.horizontalHeader().setPropertySectionResizeMode(QHeaderView.ResizeToContents);
self.verticalHeader().setSectionResizeMode(QHeaderView.Fixed);
self.setEditTriggers(QAbstractItemView.NoEditTriggers)
self.setContextMenuPolicy(Qt.CustomContextMenu) # 右键菜单
self.customContextMenuRequested.connect(self.showContextMenu) # 菜单连接信号
def addExcelContent(self):
self.model.setItem(0, 0, QStandardItem('测试用例'))
self.model.setItem(0, 1, QStandardItem(self.usecaseName))
self.model.setItem(0, 2, QStandardItem('用例编号'))
self.model.setItem(0, 3, QStandardItem(Usecase.get_by_name(self.usecaseName).number))
self.model.appendRow([QStandardItem(str(x)) if x is not None else QStandardItem(' ') for x in tittle])
self.setUpdatesEnabled(False)
for step in self.usecaseOperation:
for opr in step:
# print(opr)
if 'STEP' in opr:
self.model.setItem(self.rowIndex, self.colIndex, QStandardItem(opr))
self.rowIndex += 1
else:
# self.insertRow(self.rowIndex)
for k, v in opr[1].items():
v = '-' if v == '' else v
self.model.setItem(self.rowIndex, self.colIndex, QStandardItem(v))
self.colIndex += 1
self.rowIndex += 1
self.colIndex = 0
self.colsLen = self.model.rowCount()
self.rowsLen = 7
self.setUpdatesEnabled(True)
def changeRowColor(self, rowIndex, res):
if res:
brush = QBrush(QColor(0,255,154))
else:
brush = QBrush(QColor(220,20,60))
try:
self.model.item(rowIndex, 1).text()
except:
# for x in range(self.rowsLen):
# self.model.setData(self.model.index(rowIndex -1, x), QBrush(Qt.gray), Qt.BackgroundRole)
return
if rowIndex < 0:
for x in range(self.rowsLen):
self.model.setData(self.model.index(abs(rowIndex), x), brush, Qt.BackgroundRole)
else:
# print([x.text() for x in self.model.takeRow(rowIndex)])
for x in range(self.rowsLen):
self.model.setData(self.model.index(rowIndex, x), brush, Qt.BackgroundRole)
# self.model.setData(self.model.index(rowIndex -1, x), QBrush(Qt.gray), Qt.BackgroundRole)
def getRowContent(self, rowIndex):
try:
rowCon = self.model.item(rowIndex, 1).text()
except:
try:
if 'STEP' in self.model.item(rowIndex, 1).text():
return None
except:
return None
return '全部'
return rowCon
def showContextMenu(self): # 创建右键菜单、
self.contextMenu = QMenu(self)
self.actionA = self.contextMenu.addAction('从选中行开始执行')
self.contextMenu.popup(QCursor.pos()) # 2菜单显示的位置
self.actionA.triggered.connect(self.actionHandler)
self.contextMenu.show()
def actionHandler(self):
if self.parent.ProcedureThread._isPause and self.parent.ProcedureThread._isWork:
self.parent.procedureRunIndex = self.currentIndex().row()
self.parent.ProcedureThread.resume()
else:
self.parent.procedureRunIndex = self.currentIndex().row()
self.parent.procedureAutoRunClicked()
self.parent.log.infoLog(f'{self.parent.procedureRunPath}规程从{self.currentIndex().row()}行开始执行')
class UsecaseGroupView(QTableView):
def __init__(self, allCases, parent):
QTableView.__init__(self)
self.parent = parent
self.type = 'usecasegroup'
self.allCases = allCases
self.colIndex = 0
self.rowIndex = 0
self.model = QStandardItemModel(0,0)
self.getAllUsecase()
self.setModel(self.model)
self.resizeRowsToContents()
self.horizontalHeader().setStretchLastSection(True)
self.horizontalHeader().setSectionResizeMode(QHeaderView.Stretch)
self.verticalHeader().setSectionResizeMode(QHeaderView.Fixed)
# self.horizontalHeader().setPropertySectionResizeMode(QHeaderView.ResizeToContents)
# self.verticalHeader().setMinimumHeight(100)
# self.verticalHeader().setMaximumHeight(100)
self.setEditTriggers(QAbstractItemView.NoEditTriggers)
self.setContextMenuPolicy(Qt.CustomContextMenu) # 右键菜单
self.customContextMenuRequested.connect(self.showContextMenu) # 菜单连接信号
self.proType = parent.proType
def getAllUsecase(self):
for usecaseName in self.allCases:
self.usecaseOperation = json.loads(Usecase.get_by_name(usecaseName).operation)
self.insertUsecase(usecaseName)
def insertUsecase(self, usecaseName):
self.setUpdatesEnabled(False)
self.model.setItem(self.rowIndex, 0, QStandardItem('测试用例'))
self.model.setItem(self.rowIndex, 1, QStandardItem(usecaseName))
self.model.setItem(self.rowIndex, 2, QStandardItem('用例编号'))
self.model.setItem(self.rowIndex, 3, QStandardItem(Usecase.get_by_name(usecaseName).number))
self.model.setItem(self.rowIndex, 4, QStandardItem('实验类型'))
self.model.setItem(self.rowIndex, 5, QStandardItem(self.parent.proType))
self.model.appendRow([QStandardItem(str(x)) if x is not None else QStandardItem(' ') for x in tittle])
self.rowIndex += 2
for step in self.usecaseOperation:
for opr in step:
# print(opr)
if 'STEP' in opr[0]:
self.model.setItem(self.rowIndex, self.colIndex, QStandardItem(opr[0]))
self.model.setItem(self.rowIndex, self.colIndex + 1, QStandardItem(opr[1]))
self.rowIndex += 1
elif '序号' in opr[0]:
self.model.setItem(self.rowIndex, self.colIndex, QStandardItem(''))
self.model.setItem(self.rowIndex + 1, self.colIndex, QStandardItem(usecaseName))
self.rowIndex += 2
elif opr[0]:
# print(opr)
for k, v in opr[1].items():
# print(v)
self.model.setItem(self.rowIndex, self.colIndex, QStandardItem(str(v)))
self.colIndex += 1
self.rowIndex += 1
self.colIndex = 0
self.rowIndex += 1
self.colsLen = self.model.rowCount()
self.rowsLen = 7
self.setUpdatesEnabled(True)
def changeRowColor(self, rowIndex, res):
if res:
brush = QBrush(QColor(0,255,154))
else:
brush = QBrush(QColor(220,20,60))
try:
self.model.item(rowIndex, 1).text()
except:
# for x in range(self.rowsLen):
# self.model.setData(self.model.index(rowIndex -1, x), QBrush(Qt.gray), Qt.BackgroundRole)
return
if rowIndex < 0:
for x in range(self.rowsLen):
self.model.setData(self.model.index(abs(rowIndex), x), brush, Qt.BackgroundRole)
else:
# print([x.text() for x in self.model.takeRow(rowIndex)])
for x in range(self.rowsLen):
self.model.setData(self.model.index(rowIndex, x), brush, Qt.BackgroundRole)
# self.model.setData(self.model.index(rowIndex -1, x), QBrush(Qt.gray), Qt.BackgroundRole)
def getRowContent(self, rowIndex):
try:
rowCon = self.model.item(rowIndex, 1).text()
# print(rowCon,1111111111111111)
except:
try:
if 'STEP' in self.model.item(rowIndex, 1).text():
return None
except:
return None
return '全部'
return rowCon
def showContextMenu(self): # 创建右键菜单、
self.contextMenu = QMenu(self)
self.actionA = self.contextMenu.addAction('从选中行开始执行')
self.contextMenu.popup(QCursor.pos()) # 2菜单显示的位置
self.actionA.triggered.connect(self.actionHandler)
self.contextMenu.show()
def actionHandler(self):
if self.parent.ProcedureThread._isPause and self.parent.ProcedureThread._isWork:
self.parent.procedureRunIndex = self.currentIndex().row()
self.parent.ProcedureThread.resume()
else:
self.parent.procedureRunIndex = self.currentIndex().row()
self.parent.procedureAutoRunClicked()
self.parent.log.infoLog(f'{self.parent.procedureRunPath}规程从{self.currentIndex().row()}行开始执行')
def clearAllItem(tabelview):
for y in range(tabelview.model.rowCount()):
for x in range(tabelview.model.columnCount()):
tabelview.model.setData(tabelview.model.index(y, x), QBrush(), Qt.BackgroundRole)
class ProWidget(QWidget):
def __init__(self, path, parent):
super().__init__()
self.path = path
self.parent = parent
self.setupUi()
def setupUi(self):
self.gridLayout = QGridLayout(self)
self.gridLayout.setObjectName("gridLayout")
self.label_2 = QLabel(self)
self.label_2.setAlignment(Qt.AlignCenter)
self.label_2.setObjectName("label_2")
self.gridLayout.addWidget(self.label_2, 0, 2, 1, 1)
self.wordPath = Procedure.get(name = self.parent.currentPro).wordPath
self.wordAx = AxWidget(self.wordPath, self.parent)
self.wordAx.setObjectName("textBrowser")
# self.wordAx.show()
self.gridLayout.addWidget(self.wordAx, 1, 2, 1, 1)
self.proListView = UsecaseGroupView(self.path, self.parent)
self.proListView.setObjectName("proListView")
self.gridLayout.addWidget(self.proListView, 1, 0, 1, 1)
self.label = QLabel(self)
self.label.setAlignment(Qt.AlignCenter)
self.label.setObjectName("label")
self.gridLayout.addWidget(self.label, 0, 0, 1, 1)
self.line = QFrame(self)
self.line.setFrameShape(QFrame.VLine)
self.line.setFrameShadow(QFrame.Sunken)
self.line.setObjectName("line")
self.gridLayout.addWidget(self.line, 0, 1, 2, 1)
self.gridLayout.setColumnStretch(0, 3)
self.gridLayout.setColumnStretch(1, 1)
self.gridLayout.setColumnStretch(2, 1)
self.retranslateUi()
QMetaObject.connectSlotsByName(self)
# def addWord(self):
def retranslateUi(self):
_translate = QCoreApplication.translate
self.setWindowTitle(_translate("self", "self"))
self.label_2.setText(_translate("self", "规程源文件"))
self.label.setText(_translate("self", "解析后规程"))
class AxWidget(QMainWindow):
def __init__(self,path,parent, *args, **kwargs):
super(AxWidget, self).__init__(*args, **kwargs)
# self.resize(800, 600)
# layout = QVBoxLayout(self)
# self.axWidget = QAxWidget(self)
# self.axWidget = QTextBrowser()
# self.setCentralWidget(self.axWidget)
# path = 'C:\\Users\\lj\\Desktop\\原量程中子注量率高 分析(1).docx'
# my_doc = docx.Document(path)
# print(my_doc.paragraphs[0].text)
# for my_paragraph in my_doc.paragraphs:
# print(my_paragraph.text)
# self.axWidget.append(my_paragraph.text)
# self.axWidget.append(read_docx(path))
# layout.addWidget(self.axWidget)
# layout.addWidget(QLabel())
# self.openOffice(path)
# from pydocx import PyDocX
html = PyDocX.to_html(path)
docxName = os.path.basename(path)
portion = os.path.splitext(docxName)
htmlName = portion[0] + '.html'
htmlPath = os.path.join(parent.projectPath, '规程文档', htmlName)
f = open(htmlPath, 'w', encoding="utf-8")
f.write(html)
f.close()
# self.parent = parent
self.browser=QWebEngineView()
#加载外部的web界面
self.browser.load(QUrl(QFileInfo(htmlPath).absoluteFilePath()))
self.setCentralWidget(self.browser)
def openOffice(self, path):
app = 'Word.Application'
self.axWidget.clear()
if not self.axWidget.setControl(app):
return QMessageBox.critical(self, '错误', '没有安装 %s' % app)
self.axWidget.dynamicCall(
'SetVisible (bool Visible)', 'false') # 不显示窗体
self.axWidget.setProperty('DisplayAlerts', False)
self.axWidget.setControl(path)
self.axWidget.show()
def openPdf(self, path):
self.axWidget.clear()
if not self.axWidget.setControl('Adobe PDF Reader'):
return QMessageBox.critical(self, '错误', '没有安装 Adobe PDF Reader')
self.axWidget.setControl("{233C1507-6A77-46A4-9443-F871F945D258}")
self.axWidget.dynamicCall(
'SetVisible (bool Visible)', 'false') # 不显示窗体
self.axWidget.dynamicCall('LoadFile(const QString&)',0, path)
def closeEvent(self, event):
self.axWidget.close()
self.axWidget.clear()
self.layout().removeWidget(self.axWidget)
del self.axWidget
super(AxWidget, self).closeEvent(event)