PyQt 重载TreeWidget
预览图:
目的是将输入文件批量转换成Json文件,为了可视化处理,制作了一个界面来管理这些操作,主要难点是列表、列表子项、菜单之间的应用,每一个都需要重载
下面是具体的代码,plainTextEdit就是转换后的Json文本
class TreeWidget(QTreeWidget):
def __init__(self, parent=None):
super(TreeWidget, self).__init__(parent)
# self.setExpandsOnDoubleClick(False) # 禁用双击展开节点
self.path = ''
self.line_number_flag = True # 显示行号
self.menu = QMenu() # 新建菜单
self.setMenu() # 初始化菜单
def set_plainTextEdit(self, plainTextEdit):
"""
设置文本
"""
self.plainTextEdit = plainTextEdit
def refreshPlainText(self):
"""
刷新文本
"""
# 获取当前选中的Item
if self.currentItem() == None:
return
path = self.currentItem().item_output_path
if self.path != path:
self.path = path
if os.path.exists(path):
with open(path, 'r', encoding='utf8') as f:
if self.line_number_flag:
lines = f.readlines()
cnt = 1
display_string = ''
for line in lines:
display_string += '%-6s|%s' % (str(cnt), line)
cnt += 1
self.plainTextEdit.setPlainText(display_string)
else:
self.plainTextEdit.setPlainText(f.read())
def mousePressEvent(self, event: QtGui.QMouseEvent):
"""
鼠标点击事件重载
"""
try:
itemIndex = self.indexAt(event.pos())
# if itemIndex.row() != self.currentIndex().row():
self.setCurrentIndex(itemIndex)
if (itemIndex.row() == -1):
self.plainTextEdit.setPlainText('')
self.path = ''
else:
self.refreshPlainText()
super().mousePressEvent(event)
except Exception as ex:
print(ex)
def contextMenuEvent(self, event: QtGui.QContextMenuEvent):
"""
右键菜单事件重载
"""
try:
currentItem = self.currentItem()
# 根据Item的类名显示对应的菜单
if type(currentItem) == TreeItem or type(currentItem) == InfoItem:
self.menu.popup(QCursor.pos())
self.menu.show()
# super().contextMenuEvent(event)
except Exception as ex:
print(ex)
def setMenu(self):
"""
设置右键菜单
"""
try:
self.menu.addAction(u'显示输入文件').triggered.connect(self.open_input_directory)
self.menu.addAction(u'显示输出文件').triggered.connect(self.open_output_directory)
self.menu.addAction(u'移除').triggered.connect(self.clear_item)
self.menu.addAction(u'删除Json').triggered.connect(self.delete_self)
except Exception as ex:
print(ex)
def open_input_directory(self):
"""
在资源管理器显示源文件
"""
currentItem = self.currentItem()
# InfoItem为子项,不具有该变量
if type(currentItem) == InfoItem:
currentItem = currentItem.parent()
if os.path.exists(currentItem.item_input_path):
try:
# os.system("explorer /select," + currentItem.item_input_path)
command = 'explorer /select, {}"'.format(currentItem.item_input_path)
run(command, shell=True)
except Exception as ex:
print(ex)
else:
currentItem.set_error(0)
QMessageBox.critical(None, ' ', '不存在此文件', QMessageBox.Yes, QMessageBox.Yes)
def open_output_directory(self):
"""
在资源管理器显示显示输出文件
"""
currentItem = self.currentItem()
# InfoItem为子项,不具有该变量
if type(currentItem) == InfoItem:
currentItem = currentItem.parent()
if os.path.exists(currentItem.item_output_path):
try:
# os.system("explorer /select," + currentItem.item_output_path)
command = 'explorer /select, {}"'.format(currentItem.item_output_path)
run(command, shell=True)
except Exception as ex:
print(ex)
else:
currentItem.set_error(1)
QMessageBox.critical(None, '', '不存在此文件', QMessageBox.Yes, QMessageBox.Yes)
def clear_item(self):
"""
移除整个子项
"""
currentItem = self.currentItem()
if type(currentItem) == InfoItem:
currentItem = currentItem.parent()
try:
rootIndex = self.indexOfTopLevelItem(currentItem)
self.takeTopLevelItem(rootIndex)
except Exception as ex:
print(ex)
def delete_self(self):
"""
删除Json
"""
currentItem = self.currentItem()
if type(currentItem) == InfoItem:
currentItem = currentItem.parent()
try:
reply = QMessageBox.question(None, '警告', '您确认删除文件吗?', QMessageBox.Yes | QMessageBox.No, QMessageBox.No)
if reply == QMessageBox.Yes:
if os.path.exists(currentItem.item_output_path):
os.remove(currentItem.item_output_path)
else:
currentItem.set_error(1)
QMessageBox.critical(None, ' ', '不存在此文件', QMessageBox.Yes, QMessageBox.Yes)
return
rootIndex = self.indexOfTopLevelItem(currentItem)
self.takeTopLevelItem(rootIndex)
except Exception as ex:
print(ex)
class TreeItem(QTreeWidgetItem):
"""
根子项
"""
def __init__(self, parent=None, item_input_name='', item_output_name='', item_input_path='', item_output_path=''):
super(TreeItem, self).__init__(parent)
self.item_input_path = item_input_path
self.item_output_path = item_output_path
self.setText(0, item_input_name)
self.setText(1, item_output_name)
self.inputItem = InfoItem(self, 'input', self.item_input_path)
self.outputItem = InfoItem(self, 'output', self.item_output_path)
def set_error(self, code, message=''):
"""
错误
"""
try:
if code == 0:
InfoItem(self, 'error', '无输入文件')
elif code == 1:
InfoItem(self, 'error', '无输出文件')
elif code == 2:
InfoItem(self, 'error', '格式转换失败:%s' % message)
except Exception as ex:
print(ex)
class InfoItem(QTreeWidgetItem):
"""
二级子项
"""
def __init__(self, parent=None, item_type='', item_path=''):
super(InfoItem, self).__init__(parent)
self.setText(0, item_type)
self.setText(1, item_path)
self.item_output_path = self.parent().item_output_path
绑定treewidget item的点击事件
self.treeWidget.itemClicked['QTreeWidgetItem*','int'].connect(self.item_clicked)
def item_clicked(self,item,column):
print(item.text(0))