forked from xianrenge/sequence_label
-
Notifications
You must be signed in to change notification settings - Fork 0
/
labeling.py
278 lines (235 loc) · 12.3 KB
/
labeling.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
#1.3 版本 提供JSON格式文件的输入及导出以及标注的键盘绑定
from tkinter import *
import hashlib
import time
from tkinter import filedialog
import chardet
import math
import tkinter
import numpy as np
from tkinter.scrolledtext import ScrolledText
import tkinter.font as tkFont
import os
from tkinter.messagebox import showinfo
import json
LOG_LINE_NUM = 0
class MY_GUI():
def __init__(self,init_window_name):
self.init_window_name = init_window_name
self.max1=""
self.filename=""
self.btns_names=['资产','价格','时间日期','年龄','其他数值']
#设置窗口
def set_init_window(self):
# 设置输入输出框字体
ft = tkFont.Font(family='宋体', size=15)
self.init_window_name.title("电子病历标注工具_v1.3 ") #窗口名
#self.init_window_name.geometry('320x160+10+10') #290 160为窗口大小,+10 +10 定义窗口弹出时的默认展示位置
self.init_window_name.geometry('1500x1000+10+10')
#self.init_window_name["bg"] = "pink" #窗口背景色,其他背景色见:blog.csdn.net/chl0000/article/details/7657887
#self.init_window_name.attributes("-alpha",0.9) #虚化,值越小虚化程度越高
#标签
self.init_data_label = Label(self.init_window_name, text="待处理数据")
self.init_data_label.grid(row=0, column=0)
self.result_data_label = Label(self.init_window_name, text="输出结果")
self.result_data_label.grid(row=0, column=12)
self.log_label = Label(self.init_window_name, text="日志")
self.log_label.grid(row=12, column=0)
#文本框
self.init_data_Text = ScrolledText(self.init_window_name, width=67, height=35,font=ft) #原始数据录入框
self.init_data_Text.grid(row=1, column=0, rowspan=10, columnspan=10)
self.result_data_Text = ScrolledText(self.init_window_name, width=70, height=49,font=ft) #处理结果展示
self.result_data_Text.grid(row=1, column=12, rowspan=15, columnspan=10)
self.log_data_Text = Text(self.init_window_name, width=66, height=9) # 日志框
self.log_data_Text.grid(row=13, column=0, columnspan=10)
self.init_data_Text.bind("<Button-1>", self.button_start)
self.init_data_Text.bind("<ButtonRelease-1>", self.button_end)
#按钮
# self.str_trans_to_md5_button = Button(self.init_window_name, text="字符串转MD5", bg="lightblue", width=10,command=self.str_trans_to_md5) # 调用内部方法 加()为直接调用
# self.str_trans_to_md5_button.grid(row=1, column=11)
#导入文件按钮
self.input_button = Button(self.init_window_name,text="导入文件",bg="lightgreen",width=8,command=self.openfile)
self.input_button.grid(row=0, column=2)
# 输入窗口清空按钮
self.delet_input_button = Button(self.init_window_name, text="一键清空", bg="red", width=8,command=self.delet_ofInput)
self.delet_input_button.grid(row=0, column=3)
#展示窗口清空按钮
self.delet_result_button = Button(self.init_window_name, text="一键清空", bg="red", width=8,command=self.delet_ofResult)
self.delet_result_button.grid(row=0,column=13)
#导出文件按钮
self.output_button = Button(self.init_window_name,text="导出文件",bg="lightgreen",width=8,command=self.outputfile)
self.output_button.grid(row=0,column=14)
#标记解剖部位按钮
self.show_button = Button(self.init_window_name,text=self.btns_names[0],bg="lightblue",width='8',command=self.show_jpbw)
self.show_button.grid(row=2, column=11)
# 标记症状描述按钮
self.show_button = Button(self.init_window_name, text=self.btns_names[1],bg="lightyellow", width='8', command=self.show_zzms)
self.show_button.grid(row=3, column=11)
# 标记独立症状按钮
self.show_button = Button(self.init_window_name, text=self.btns_names[2], bg="lightgreen",width='8', command=self.show_dlzz)
self.show_button.grid(row=4, column=11)
# 标记药物按钮
self.show_button = Button(self.init_window_name, text=self.btns_names[3],bg="red", width='8', command=self.show_yw)
self.show_button.grid(row=5, column=11)
# 标记手术按钮
self.show_button = Button(self.init_window_name, text=self.btns_names[4],bg="lightpink", width='8', command=self.show_ss)
self.show_button.grid(row=6, column=11)
# 恢复操作按钮
self.recover_button = Button(self.init_window_name, text="恢复", width='8', command=self.recover)
self.recover_button.grid(row=0,column =15)
# 标注撤销功能ctrl+z实现
self.back_button = Button(self.init_window_name, text="撤销", width='8', command=self.backToHistory)
self.back_button.grid(row=0, column=16)
self.result_data_Text.bind('<Control-Key-z>',self.backToHistory)
self.result_data_Text.edit_separator()
#功能函数
def str_trans_to_md5(self):
src = self.init_data_Text.get(1.0,END).strip().replace("\n","").encode()
#print("src =",src)
if src:
try:
myMd5 = hashlib.md5()
myMd5.update(src)
myMd5_Digest = myMd5.hexdigest()
#print(myMd5_Digest)
#输出到界面
self.result_data_Text.delete(1.0,END)
self.result_data_Text.insert(1.0,myMd5_Digest)
self.write_log_to_Text("INFO:str_trans_to_md5 success")
except:
self.result_data_Text.delete(1.0,END)
self.result_data_Text.insert(1.0,"字符串转MD5失败")
else:
self.write_log_to_Text("ERROR:str_trans_to_md5 failed")
#获取鼠标选中文本
def button_start(self,event):
global s
global line_no
s = self.init_data_Text.index('@%s,%s' % (event.x, event.y))
line_no=str(s).split('.')[0]
s=str(s).split('.')[1]
def button_end(self,event):
global e
e = self.init_data_Text.index('@%s,%s' % (event.x, event.y))
e = str(e).split('.')[1]
# 处理选中位置参数
def get_loc(self):
e=int(str(self.init_data_Text.index('insert')).split('.')[1])-1 # 末尾列数
ll=int(str(self.init_data_Text.index('insert')).split('.')[0])-1 # 行号
con_num=len(self.init_data_Text.selection_get())
s=e-con_num+1 # 开始列数
return s,e,ll
#标记1
def show_jpbw(self):
self.result_data_Text.edit_separator()
start_index,end_index,ll=self.get_loc()
print(self.init_data_Text.selection_get()+"\t"+str(self.btns_names[0])+"\n")
self.result_data_Text.insert(END,self.init_data_Text.selection_get()+"\t" + str(start_index) + "\t" + str(end_index) + "\t"+ str(ll)+ "\t" +str(self.btns_names[0])+"\n")
print(self.result_data_Text.get(END))
self.max1 =self.result_data_Text.get('1.0',END)
self.result_data_Text.edit_separator()
# 标记2
def show_zzms(self,):
self.result_data_Text.edit_separator()
start_index,end_index,ll=self.get_loc()
print(self.init_data_Text.selection_get() + "\t" + str(start_index) + "\t" + str(end_index)+ "\t"+ str(ll)+ "\t" + str(self.btns_names[1]) + "\n")
self.result_data_Text.insert(END, self.init_data_Text.selection_get() + "\t" + str(start_index) + "\t" + str(end_index) +"\t"+ str(ll)+ "\t" + str(self.btns_names[1]) + "\n")
self.max1 = self.result_data_Text.get('1.0', END)
self.result_data_Text.edit_separator()
# 标记3
def show_dlzz(self):
self.result_data_Text.edit_separator()
start_index,end_index,ll=self.get_loc()
print(self.init_data_Text.selection_get() + "\t"+ str(start_index) + "\t" + str(end_index) + str(self.btns_names[2]) + "\n")
self.result_data_Text.insert(END, self.init_data_Text.selection_get() + "\t" + str(start_index) + "\t" + str(end_index) + "\t"+ str(ll)+ "\t" +str(self.btns_names[2]) + "\n")
self.max1 = self.result_data_Text.get('1.0', END)
self.result_data_Text.edit_separator()
# 标记4
def show_yw(self):
self.result_data_Text.edit_separator()
start_index,end_index,ll=self.get_loc()
print(self.init_data_Text.selection_get() + "\t" + str(self.btns_names[3]) + "\n")
self.result_data_Text.insert(END, self.init_data_Text.selection_get() + "\t" + str(start_index) + "\t" + str(end_index) + "\t"+ str(ll)+ "\t" +str(self.btns_names[3]) + "\n")
self.max1 = self.result_data_Text.get('1.0', END)
self.result_data_Text.edit_separator()
# 标记5
def show_ss(self):
self.result_data_Text.edit_separator()
start_index,end_index,ll=self.get_loc()
print(self.init_data_Text.selection_get() + "\t" + str(self.btns_names[4]) + "\n")
self.result_data_Text.insert(END, self.init_data_Text.selection_get() + "\t"+ str(start_index) + "\t" + str(end_index) + "\t"+ str(ll)+ "\t" +str(self.btns_names[4]) + "\n")
self.max1 = self.result_data_Text.get('1.0', END)
self.result_data_Text.edit_separator()
#标注操作撤销功能
def callback(self,event):
# 每当有字符插入的时候,就自动插入一个分割符,主要是防止每次撤销的时候会全部撤销
self.result_data_Text.edit_separator()
def backToHistory(self): #撤销操作
if len(self.result_data_Text.get('1.0','end'))!=0:
self.result_data_Text.edit_undo()
else: #无字符时不能撤销
return
def recover(self): #恢复操作
if len(self.max1) == len(self.result_data_Text.get('1.0',END)):
return
self.result_data_Text.edit_redo()
#输入窗口一键清空功能
def delet_ofInput(self):
self.init_data_Text.delete('1.0','end')
#结果窗口一键清空功能
def delet_ofResult(self):
self.result_data_Text.delete('1.0','end')
#打开文件功能
def openfile(self):
fname = filedialog.askopenfilename(title='打开文件', filetypes=[('All Files', '*')])
self.filename=os.path.basename(fname)
print(self.filename)
f=open(fname,'r',encoding='utf-8',errors='ignore')
# #对文本数据存储进数组,方便后续操作
# line = f.readline()
# data_list = []
# while line:
# # num = list(map(str, line.split()))
# # data_list.append(num)
# data_list.append(line)
# line = f.readline()
# f.close()
# data_array = np.array(data_list)
# f_contet = data_array
# new
f_contet=''.join(f.readlines())
self.init_data_Text.insert(END,f_contet)
# 导出文件功能
def outputfile(self):
if self.filename!="":
# os.chdir(r'E:\GitTest\untitled\文本标注1.1\Annoation')
# os.chdir(r'data/out')
f = open("data/out/ann"+self.filename, 'w', encoding='utf-8', errors='ignore')
f.write(self.result_data_Text.get("1.0", "end"))
json1 = json.dumps(self.result_data_Text.get("1.0",END))
print(json1)
showinfo(title="成功",message="标注文件已导出至Annoation文件夹")
else:
showinfo(title="错误",message="未找到指定文件")
#获取当前时间
def get_current_time(self):
current_time = time.strftime('%Y-%m-%d %H:%M:%S',time.localtime(time.time()))
return current_time
#日志动态打印
def write_log_to_Text(self,logmsg):
global LOG_LINE_NUM
current_time = self.get_current_time()
logmsg_in = str(current_time) +" " + str(logmsg) + "\n" #换行
if LOG_LINE_NUM <= 7:
self.log_data_Text.insert(END, logmsg_in)
LOG_LINE_NUM = LOG_LINE_NUM + 1
else:
self.log_data_Text.delete(1.0,2.0)
self.log_data_Text.insert(END, logmsg_in)
def gui_start():
init_window = tkinter.Tk() #实例化出一个父窗口
ZMJ_PORTAL = MY_GUI(init_window)
# 设置根窗口默认属性
ZMJ_PORTAL.set_init_window()
init_window.mainloop() #父窗口进入事件循环,可以理解为保持窗口运行,否则界面不展示
gui_start()