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)

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 学习教程

Python3 - 函数以及GUI_TKINTER(第四天)

使用python3在Raspberry Pi上打开和关闭Tkinter GUI