1 本工具使用python的PyQt编写的,第一次尝试,所以暂时将代码和界面写到一起,后期应该会分开。
2 实现的功能是 例如 AA BB 要在这两个字符前后,中间,添加特定的字符,如果只有一行,还是手动比较快,但是行数过多之后就比较麻烦了,因此编写此工具作为第一版。
import sys
from PyQt5.QtCore import Qt, pyqtSignal
from PyQt5.QtGui import QIcon, QTextCursor
from PyQt5.QtWidgets import (QMainWindow, QApplication, QAction, qApp, QHBoxLayout, QVBoxLayout, QPushButton,
QFrame, QTextEdit, QFileDialog, QSplitter, QWidget, QDesktopWidget, QCheckBox, QMessageBox,
QScrollArea, QLabel, QLineEdit, QGridLayout)
class NeLa2(QMainWindow):
textsignal = pyqtSignal(str) # 信号定义为类属性
def __init__(self):
super().__init__()
self.v_splitter = QSplitter(Qt.Vertical)
self.h_splitter = QSplitter(Qt.Horizontal)
self.buttom = QFrame(self)
self.all_box = QHBoxLayout(self) # 总体布局
self.topright = QFrame(self) # 右边控件
self.topleft = QFrame(self) # 左边控件
self.frm = QFrame(self) # 程序的总体面板
self.lbl = QLabel() # 底部显示面板
self.s = SecondWindow() # 子面板
self.textsignal.connect(self.s.showSelect) # 连接信号和槽函数
self.initUI()
def initUI(self):
global text_edit
text_edit = QTextEdit() # 文本框
self.initMenu() # 初始化菜单栏
self.initLayout() # 初始化布局
self.lbl.setFrameShape(QLabel.StyledPanel)
self.lbl.setFixedSize(835, 30)
buttom_hbox = QHBoxLayout(self) # 下,底部显示面板布局
buttom_hbox.addWidget(self.lbl)
self.buttom.setLayout(buttom_hbox)
# 初始化布局
def initLayout(self):
self.topleft = QFrame(self)
self.topleft.setFrameShape(QFrame.StyledPanel)
self.topright = QFrame(self)
self.topright.setFrameShape(QFrame.StyledPanel)
self.buttom.setFrameShape(QFrame.StyledPanel)
self.h_splitter.addWidget(self.topleft)
self.h_splitter.addWidget(self.topright)
self.v_splitter.addWidget(self.h_splitter)
self.v_splitter.addWidget(self.buttom)
self.all_box.addWidget(self.v_splitter)
self.topright.setGeometry(0, 20, 800, 780) # 顶部右边,使得左边范围变小
self.h_splitter.setGeometry(0, 20, 700, 600) # 是的下边范围变小
self.frm.setGeometry(0, 20, 880, 760)
self.frm.setLayout(self.all_box)
# self.setGeometry(500, 200, 880, 780) # 距左,距上,宽,高
self.setFixedSize(880, 780)
self.show()
self.center()
# 初始化菜单栏
def initMenu(self):
self.statusBar()
# 退出菜单
exitAction = QAction(QIcon('../img/exit.jpg'), 'Exit', self)
exitAction.setShortcut('Ctrl+Q') # 快捷键
exitAction.setStatusTip('Exit Tools')
exitAction.triggered.connect(qApp.quit)
# 打开文件菜单
open_file = QAction(QIcon('../img/exit.jpg'), 'Open...', self)
open_file.setShortcut('Ctrl+O')
open_file.setStatusTip('Open New File')
open_file.triggered.connect(self.show_dialog)
# 编辑菜单
editAction = QAction(QIcon('../img/exit.jpg'), 'Edit', self)
editAction.setShortcut('Ctrl+E') # 快捷键
editAction.setStatusTip('Edit Tools')
editAction.triggered.connect(self.editDialog)
# 设置菜单
menubar = self.menuBar()
filemenu = menubar.addMenu('&File')
filemenu.addAction(exitAction)
filemenu.addAction(open_file)
editmenu = menubar.addMenu('&Edit')
editmenu.addAction(editAction)
self.setWindowTitle('Main ')
# 显示到中间
def center(self):
# screen = QDesktopWidget().screenGeometry()
# size = self.geometry()
# self.move((screen.width() - size.width()) / 2, (screen.height() - size.height()) / 2)
qr = self.frameGeometry()
cp = QDesktopWidget().availableGeometry().center()
qr.moveCenter(cp)
self.move(qr.x(), qr.y())
# 编辑控件
def editDialog(self):
btnJSP = QPushButton(self)
btnJava = QPushButton(self)
btnJava.clicked.connect(self.showText)
btnJava.setText('Java')
btnJSP.setText('Jsp')
vbox = QVBoxLayout(self)
vbox.addWidget(btnJava)
vbox.addWidget(btnJSP)
vbox.addStretch(1)
lhbox = QHBoxLayout(self)
lhbox.addStretch(1) # 延伸因子,均分布局
lhbox.addLayout(vbox)
rhbox = QHBoxLayout(self)
rhbox.addWidget(text_edit)
text_edit.selectionChanged.connect(self.selectLines) # 连接文本选中事件
self.topleft.setLayout(lhbox) # 添加按钮控件
self.topright.setLayout(rhbox) # 添加编辑文本控件
# open file
def show_dialog(self):
fname = QFileDialog.getOpenFileName(self, 'Open File', '/home')
if fname[0]:
f = open(fname[0], 'r')
with f:
data = f.read()
text_edit.setText(data)
# 获取内容显示到子窗口
def showText(self):
content = text_edit.toPlainText()
self.sendEditText(content)
self.s.click()
def sendEditText(self, content):
self.textsignal.emit(content) # 发送信号
# 选中行
def selectLines(self):
# print('文本信息')
# print(text_edit.toPlainText())
try:
cursor = text_edit.textCursor()
col_num = '列位置:{}'.format(QTextCursor.columnNumber(cursor))
block_num = 'row:{}'.format(QTextCursor.blockNumber(cursor) + 1)
start = '光标是否在开始位置:{}'.format(QTextCursor.atStart(cursor))
end = '光标是否在结束位置:{}'.format(QTextCursor.atEnd(cursor))
sel_str = str(QTextCursor.selection(cursor).toPlainText())
nsel_str = '选择的文本:{}'.format(QTextCursor.selectedText(cursor))
if sel_str != '':
nexline = str(sel_str.count('\n')) + ' line break'
l = len(sel_str)
if l == 1:
len_str = '1 char'
elif l > 1:
len_str = str(len(sel_str)) + 'chars'
self.lbl.setText(col_num + ' ' + block_num + ' ' + len_str + ' ' + nexline)
# print(col_num)
# print(block_num)
# print(start)
# print(end)
# print(sel_str) # 带有格式的文本
# print(nsel_str) # 不带有格式的文本
# print(sel_str.count('\n')) # 几个换行
except Exception as e:
print(e)
# 重新显示
def reShowText(self):
if len(l) == 0:
return
try:
text_edit.clear()
for x in l:
text_edit.append(x)
except Exception as e:
print(e)
class SecondWindow(QWidget):
listsignal = pyqtSignal(list) # 信号定义为类属性
def __init__(self):
super().__init__()
self.label = QLabel()
self.top = QFrame(self)
self.buttom = QFrame(self)
self.top_edit = QTextEdit()
self.scroll = QScrollArea()
self.vehbox = QVBoxLayout()
self.listsignal.connect(NeLa2.reShowText) # 连接信号和槽函数
self.initUI()
def initUI(self):
# 功能按钮
selectAllButton = QPushButton('Select All')
selectAllButton.clicked.connect(self.selectAll)
deselectAllButton = QPushButton('Deselect All')
deselectAllButton.clicked.connect(self.deselectAll)
AnalysisButton = QPushButton('Analysis')
AnalysisButton.clicked.connect(self.analyText)
# 分析后显示控件
global anaLabel # 定义为全局变量
anaLabel = QLabel()
okButton = QPushButton('OK')
okButton.clicked.connect(self.sendText)
cancelButton = QPushButton('Cancel')
cancelButton.clicked.connect(self.close) # 直接触发窗口的close方法,此方法会调用closeEvent
# 分析文本框title
line_edit_title = QLabel('表达式:')
# 分析文本输入框
global line_edit
line_edit = QLineEdit()
global line_regular
# 键title
line_key_title = QLabel('键:')
# 键
global line_key
line_key = QLineEdit()
# 值title
line_value_title = QLabel('值:')
# 值
global line_value
line_value = QLineEdit()
# 底部
hbox = QHBoxLayout()
hbox.addStretch(1)
hbox.addWidget(okButton)
hbox.addWidget(cancelButton)
grid = QGridLayout()
grid.setSpacing(10)
grid.addWidget(line_edit_title, 2, 1)
grid.addWidget(line_edit, 2, 2, 1, 4)
grid.addWidget(line_key_title, 3, 1)
grid.addWidget(line_key, 3, 2)
grid.addWidget(line_value_title, 3, 3)
grid.addWidget(line_value, 3, 4)
grid.addWidget(AnalysisButton, 3, 5)
grid.addWidget(anaLabel, 4, 1)
hbox2 = QHBoxLayout()
hbox2.addWidget(selectAllButton)
hbox2.addWidget(deselectAllButton)
hbox2.addStretch(1)
# 下半部分
vbox = QVBoxLayout()
vbox.addLayout(hbox2)
vbox.addLayout(grid)
vbox.addStretch(1)
vbox.addLayout(hbox)
# 上半部分
tbox = QVBoxLayout()
tbox.addWidget(self.scroll)
self.top.setLayout(tbox)
self.buttom.setLayout(vbox)
self.top.setFrameShape(QFrame.StyledPanel)
self.buttom.setFrameShape(QFrame.StyledPanel)
self.top.setGeometry(100, 100, 300, 300)
# 分割 上下
h_splitter = QSplitter(Qt.Vertical)
h_splitter.addWidget(self.top)
h_splitter.addWidget(self.buttom)
# 整体布局
sbox = QHBoxLayout()
sbox.addWidget(h_splitter)
self.setLayout(sbox)
self.setGeometry(100, 100, 400, 400)
self.setWindowTitle('Second')
self.setWindowModality(Qt.ApplicationModal) # 设置窗口为应用程序模态,阻止和人任何其他窗口进行交互
self.center() # 直接调用父类的center方法
# 发送分析后文件
def sendText(self):
self.analyText()
self.listsignal.emit(l)
self.close()
# 分析
def analyText(self):
if line_edit.text() == '':
QMessageBox.information(self, 'information', self.tr('表达式不能为空'))
return
if line_key.text() == '':
QMessageBox.information(self, 'information', self.tr('键不能为空'))
return
if line_value.text() == '':
QMessageBox.information(self, 'information', self.tr('值不能为空'))
return
# 规则数组
str1 = line_edit.text().strip()
k = line_key.text() # 替换的键
v = line_value.text() # 替换的值
try:
global l
l = list()
for x in self.label.findChildren(QCheckBox):
# 找到选中的进行替换
if x.isChecked():
kc = x.text()
print(str1.replace(k, kc).replace(v, dic[kc]))
newstr = str1.replace(k, kc).replace(v, dic[kc])
l.append(newstr)
except Exception as e:
print(e)
# 全选
def selectAll(self):
# 遍历所有子控件,然后选中
for x in self.label.findChildren(QCheckBox):
x.setChecked(True)
# 全不选
def deselectAll(self):
# 遍历所有子控件,然后取消选中
for x in self.label.findChildren(QCheckBox):
x.setChecked(False)
# 展示下拉框
def showSelect(self, content):
ss = str(content).splitlines() # 分割成行列表
lable_height = self.geometry().height() # label的高
h2 = lable_height - 150 + len(ss) * 21 # 扩大的值
if lable_height < 250:
self.label.setMinimumSize(300, 250)
elif lable_height > 250:
self.label.setMinimumSize(300, h2)
elif len(ss) > 100:
QMessageBox.information(self, 'information', self.tr('暂时支持100条数据'))
return
# 创建一个空字典保存数据,全局变量
global dic
dic = {}
for x in ss:
k = x.strip()
if k == '':
continue
y = ' '.join(k.split()) # 去除两边空格,保留中间一个空格
vv = y.split(' ') # 按空格分割
try:
dic[vv[0]] = vv[1]
except Exception as e:
QMessageBox.information(self, 'information', self.tr('文本格式不正确,请按照:‘AAA BBB’形式传入'))
# self.close() # 关闭子窗口
return # 停止后面的按钮创建
cb = QCheckBox(vv[0], self)
self.vehbox.addWidget(cb)
self.vehbox.addStretch(0) # 增加一个伸缩量,都挤到上边,从上往下排列
self.label.setLayout(self.vehbox) # 将check放大label中
self.scroll.setWidget(self.label)
# 显示子窗口
def click(self):
# 因为关闭时删除了,在此重新创建
self.vehbox = QVBoxLayout()
if not self.isVisible():
self.show()
# 删除控件
def deleteKong(self):
# 遍历所有子控件,然后删除
# 删除QCheckBox
for x in self.label.findChildren(QCheckBox):
x.deleteLater()
# 删除QVBoxLayout
for y in self.label.findChildren(QVBoxLayout):
y.deleteLater()
# 关闭窗口
def closeEvent(self, event):
# 清除一些控件
self.deleteKong()
# reply = QMessageBox.question(self,
# '本程序',
# "是否要退出程序?",
# QMessageBox.Yes | QMessageBox.No,
# QMessageBox.No)
# if reply == QMessageBox.Yes:
# event.accept()
# else:
# event.ignore()
# 显示到中间
def center(self):
# screen = QDesktopWidget().screenGeometry()
# size = self.geometry()
# self.move((screen.width() - size.width()) / 2, (screen.height() - size.height()) / 2)
qr = self.frameGeometry()
cp = QDesktopWidget().availableGeometry().center()
qr.moveCenter(cp)
self.move(qr.x(), qr.y())
if __name__ == '__main__':
app = QApplication(sys.argv)
tool = NeLa2()
sys.exit(app.exec_())