Python3 Tkinter GUI 数据传输工具
Posted CodeLogs
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Python3 Tkinter GUI 数据传输工具相关的知识,希望对你有一定的参考价值。
1、实现功能
- 数据文件导入数据库
- 库表新增、数据追加、不同库数据传输(测试阶段)
- 数据采用线程池操作,速度较优
2、界面展示
- 初始化
- 导入文件,双击编辑
- 导入日志
3、主要界面代码
界面采用纯tkinter编写,逻辑并不难实现,但是调试比较费时间。
- 导入文件弹窗选择
def openFile(self,f,tree,action_model,db_tablename,btn,actionModel_label):
"""获取文件路径
:param f:文本框对象
:param tree:表格对象
:param action_model:读取文件的模式
:param db_tablename:需要追加或者新增的库表名称
:param btn:导入按钮对象,恢复可点击状态
:param self.actionModel_label:底部状态栏,显示当前导入的模式
"""
self.db_tablename = re.sub('\\s', '', str(db_tablename))
if len(self.db_tablename)==0 or self.db_tablename=='输入数据库的表名称':
messagebox.showerror('错误提示','请在输入框输入需要追加或者新增的库表名称!')
else:
self.tree = tree
l = [('CSV','.csv'),('Excel','.xlsx'),('Excel 2007','.xls'),('TXT','.txt')] # 限定打开的文件类型
self.filename = filedialog.askopenfilename(title='选择文件',filetypes=l)
if self.filename != '':
btn.config(state='normal') # 释放导入控件状态
actionModel_label.set('当前模式:%s' % (action_model)) # 更新当前底部栏追加模式
self.action_model = action_model
f.set(self.filename)
self.refreshForm()
else:
self.filename = ' 您没有选择任何文件'
f.set(self.filename)
- Treeview(表单及滚动条)
def createWidgets(self):
treeScroll = ttk.Scrollbar(self.tabfm1)
treeScroll.grid(row=1, column=1, sticky=tk.N + tk.S)
self.tree = ttk.Treeview(self.tabfm1, show='headings', yscrollcommand=treeScroll,height=15)
self.tree['columns'] = ('1', '2', '3', '4','5','6','7')
self.tree.column('1', width=35)
self.tree.heading("1", text="序号")
self.tree.column('2', width=150)
self.tree.heading("2", text="检测列名")
self.tree.column('3', width=80)
self.tree.heading("3", text="检测类型")
self.tree.column('4', width=150)
self.tree.heading("4", text="库表对应列")
self.tree.column('5', width=167)
self.tree.heading("5", text="列类型")
self.tree.column('6', width=130)
self.tree.heading("6", text="提示")
self.tree.heading("7", text="是否导入")
self.tree.column('7', width=70)
# 双击事件绑定
self.tree.bind('<Double-1>', self.popupDialog)
self.tree.grid(row=1, column=0)
treeScroll.configure(command=self.tree.yview)
self.tree.configure(yscrollcommand=treeScroll.set)
# 读取文件模式(下拉列表)
fm1 = tk.Frame(self.tabfm1)
readModel = ['追加','新增','其他模式']
self.cmbox = ttk.Combobox(fm1,values=readModel,state='readonly',width=8)
self.cmbox.set(readModel[0])
self.cmbox.grid(row=0,column=3,padx=1,sticky=tk.N + tk.S)
# 功能控件
filename = tk.StringVar(value=' 您没有选择任何文件')
tablename = tk.StringVar(value='输入数据库的表名称')
# tablename = tk.StringVar(value='测试的新增表')
bt1 = tk.Button(fm1, text='选择文件', command=lambda:self.func.openFile(filename,self.tree,self.cmbox.get(),tablename.get(),bt2,self.actionModel_label)).grid(row=0,column=0)
bt2 = tk.Button(fm1, text='开始导入', command=lambda:self.func.import_data(bt2),bg='orange')
bt2.grid(row=0,column=4,padx=1,sticky=tk.W + tk.E)
ety_path=tk.Entry(fm1,state='readonly',textvariable=filename,width=62).grid(row=0,column=1,padx=1,sticky=tk.N + tk.S)
ety_name=tk.Entry(fm1,textvariable=tablename,width=20).grid(row=0,column=2,padx=1,sticky=tk.N + tk.S)
fm1.grid(row=0, pady=1, sticky=tk.W + tk.E)
# 底部状态栏
fm2 = tk.Frame(self.master)
self.actionModel_label = tk.StringVar()
dbType_label = tk.StringVar()
self.actionModel_label.set('当前模式:追加')
dbType_label.set('| 数据库:Oracle 地址:127.0.0.1 用户:User')
lb1 = tk.Label(fm2,textvariable=self.actionModel_label,fg='red').grid(row=0,column=0,padx=5)
lb2 = tk.Label(fm2, textvariable=dbType_label).grid(row=0,column=1)
fm2.grid(row=1, sticky=tk.W)
- 表单双击弹窗编辑
def popupDialog(self,event):
for i in self.tree.selection():
item = self.tree.item(i, 'values')
self.master.attributes("-disabled", 1) # 禁用主窗口
top = tk.Toplevel()
top.title("编辑")
w = 305;h = 110
x = (self.ws / 2) - (w / 2)
y = (self.hs / 2) - (h / 2)
top.geometry('%dx%d+%d+%d' % (w, h, x, y))
# top.geometry('300x100')
top.resizable(0, 0)
tk.Label(top, text='字段名称:').grid(row=0, padx=2, pady=2)
tk.Label(top, text='库表字段:').grid(row=1, padx=2, pady=2)
tk.Label(top, text='字段类型:').grid(row=2, padx=2, pady=2)
tk.Label(top, text='是否导入:').grid(row=3, padx=2, pady=2)
# ========字段名称========
col_name = tk.StringVar(value=item[1])
tk.Entry(top,textvariable=col_name,state='readonly').grid(row=0,column=1,sticky=tk.W + tk.E)
# ========库表字段========
db_col_list = self.func.data['db_table_columns']['name']
db_col_name = ttk.Combobox(top,values=db_col_list,state='readonly',width=8)
if item[3].strip():
db_col_name.set(item[3])
else:
db_col_name.set(db_col_list[0])
db_col_name.grid(row=1,column=1,sticky=tk.W + tk.E)
# ========字段类型========
db_col_type = tk.StringVar()
if self.cmbox.get()=='追加':
db_col_type.set('追加模式无法定义类型')
state_ = 'readonly'
elif self.cmbox.get()=='新增':
db_col_type.set(item[4])
state_ = 'normal'
else:
db_col_type.set('当前模式无法定义类型')
state_ = 'readonly'
tk.Entry(top,state=state_,textvariable=db_col_type).grid(row=2,column=1)
# ========是否导入========
db_col_valid_list = [' Y',' N']
db_col_valid = ttk.Combobox(top, values=db_col_valid_list, state='readonly', width=8)
db_col_valid.set(item[6])
db_col_valid.grid(row=3,column=1,sticky=tk.W + tk.E)
bt = tk.Button(top,text='确认',width=11,bg='orange',command=lambda:self.popupDialog_OK(top,i,item,db_col_name,db_col_type,db_col_valid))
bt.grid(row=0,column=3,rowspan=4,padx=2,pady=2,sticky=tk.N + tk.S)
# 关闭弹窗触发
top.protocol("WM_DELETE_WINDOW", lambda:self.popupDialog_close(top))
- 弹窗确认事件
def popupDialog_OK(self,top,i,item,db_col_name,db_col_type,db_col_valid):
:param top:子窗体对象
:param i:双击行对象
:param item:行对象数据
:param db_col_name:库表字段下拉框
:param db_col_type:库表字段类型
:param db_col_valid:是否导入下拉框
"""
items = self.tree.get_children()
col_list = [self.tree.item(item,'values')[3] for item in items if self.tree.item(item,'values')[0] != self.tree.item(i, 'values')[0]]
if db_col_name.get() in col_list:
messagebox.showerror('错误提示', '字段已存在,请重新输入!')
self.master.attributes("-disabled", 0) # 激活主窗口
top.destroy() # 销毁弹窗
else:
if '追加' in self.actionModel_label.get():
idx = self.func.data['db_table_columns']['name'].index(db_col_name.get())
db_col_type = self.func.data['db_table_columns']['type'][idx]
new_item = [item[0], item[1], item[2],db_col_name.get(), db_col_type,item[5],db_col_valid.get()]
elif '新增' in self.actionModel_label.get():
new_item = [item[0], item[1], item[2], db_col_name.get(), db_col_type.get(), item[5], db_col_valid.get()]
else:
pass
self.master.attributes("-disabled", 0) # 激活主窗口
top.destroy() # 销毁弹窗
# 更新表单行数据
self.tree.delete(i)
self.tree.insert('',int(new_item[0])-1,values=new_item)
- 线程池批量插入数据可以参考我的另外一篇文章
Python3 多线程(连接池)操作MySQL插入数据
4、个人废话
工具属于半成品,如截图所示两个tab,其中数据库配置并未完成,以及一些基本功能也纯在bug,所以纯属练手项目,感兴趣的朋友可以自行下载,新手代码,不喜勿喷。
源码下载:
https://download.csdn.net/download/joson1234567890/16799096
以上是关于Python3 Tkinter GUI 数据传输工具的主要内容,如果未能解决你的问题,请参考以下文章
使用Python3.6的标准GUI库tkinter快速创建GUI应用程序
Python3 GUI编程: 自带图形库 tkinter 学习教程
Python3.5、Win32gui、Tkinter。我无法从屏幕获取 Pixel
Python3 GUI编程: 自带图形库 tkinter 学习教程