• Tkinter


    Tkinter

    文档

    使用清华镜像源安装:

    pip install -i https://pypi.tuna.tsinghua.edu.cn/simple tkinter

    官方文档(python3.6版本)

    一本在线电子说明书

    一位大神的博客

    需求

    之前使用pyton编写了一个etl工具,但是使用命令行的形式来操作的,后面感觉这个不是很方便,尝试着做成GUI的形式,因为python有很多种gui库,比如:TkinterwxPythonJythonpyqt5等,一开始也不知道选哪个,后面发现Tkinter是官方自带的比较轻量的,因为容易上手,所以就选择了Tkinter

    因为数据的导入导出涉及到业务,所以这里的例子就用另外一种例子来代替。

    比如:我们想要一个实现,首先有两个按钮"开始、"暂停",下方有一个"文本框",当点击"开始","开始"按钮被禁用,然后文本框开始输出当前时间的字符串,点击"暂停","文本框"停止输出。再次点击"开始","文本框"继续输出。

    #!/usr/bin/env python
    # -*- coding: utf-8 -*-
    import time
    import threading
    from tkinter import *
    
    THREAD_RUNNING = False # 工作线程是否在运行的标志位
    THREAD_GLOBAL_FLAG = True # 线程种的循环标志位
    RUN_FLAG = True # 线程中业务循环执行标志位
    
    def increase(text):
        global RUN_FLAG
        global THREAD_GLOBAL_FLAG
        """
        启动一个线程刷新文本框,因为单线程会阻塞tkinter的gui刷新
        :param text:
        :return:
        """
        curr_table_name = "" # 当前表名
        while THREAD_GLOBAL_FLAG:
            while RUN_FLAG:
                text.config(state=NORMAL)
                text.insert('end', "{}
    ".format(time.strftime("%Y-%m-%d %H:%M:%S", time.localtime())))
                text.see("end")
                text.config(state=DISABLED)  # 禁止编辑
                time.sleep(1)
    
    def bt_method_start(event, bt_start=None, bt_pause=None, text=None):
        """
        开始按钮点击事件
        :param event:  当前事件
        :param bt_start: 开始按钮对象
        :param bt_pause:  暂停按钮对象
        :param text:  文本框对象
        :return:
        """
        print("bt_method_start")
        global RUN_FLAG
        RUN_FLAG = True
        bt_start['state'] = 'disabled'
        bt_pause['state'] = 'normal'
        # 启动线程
        global THREAD_RUNNING
        if not THREAD_RUNNING:
            THREAD_RUNNING = True
            t = threading.Thread(target=increase, args=(text,))
            t.start()
    
    def bt_method_pause(event, bt_start=None, bt_pause=None, text=None):
        """
        暂停按钮点击事件
        :param event: 当前事件
        :param bt_start: 开始按钮对象
        :param bt_pause: 暂停按钮对象
        :param text: 文本框对象
        :return: 
        """
        print("bt_method_pause")
        global RUN_FLAG
        RUN_FLAG = False
        bt_start['state'] = 'normal'
        bt_pause['state'] = 'disabled'
    
    def on_closing(root):
        """
        关闭窗口事件,在这里做清理工作,线程运行标志位修改
        :param root: 
        :return: 
        """
        print("窗口关闭!")
        global RUN_FLAG
        global THREAD_GLOBAL_FLAG
        RUN_FLAG = False
        THREAD_GLOBAL_FLAG = False
        print(root)
        root.destroy()
    
    
    def main():
        root = Tk()
        root.title("窗口")
        root.resizable(0, 0)  # 阻止Python GUI的大小调整
        # 注意此处调用lambda没有参数
        # 因为默认的绑定事件等号右边给的是函数名,这种情况没法传递参数,所以使用lambda表达式间接的传递参数
        root.protocol("WM_DELETE_WINDOW", lambda : on_closing(root)) 
        # 窗口居中显示,大小为当前屏幕的50%
        sw = root.winfo_screenwidth()
        sh = root.winfo_screenheight()
        init_width = int(sw * 0.5)
        init_height = int(sh * 0.5)
        init_x = int((sw - init_width)/2)
        init_y = int((sh - init_height)/2)
        root.geometry('{}x{}+{}+{}'.format(init_width, init_height, init_x, init_y))  # 这里的乘是小x
        root.update() # 刷新窗口大小,方便下面获得最新的窗口宽高
        # print(root.winfo_width())
        # print(root.winfo_height())
        # print(root.winfo_screenwidth())
        # print(root.winfo_screenheight())
    
    
        # 主框架
        app = Frame(root)
        app.pack()
    
        # 按钮区域
        frame_button = Frame(app)
        frame_button.pack(side="top")
        # 两个按钮
        bt_start = Button(frame_button, width=12, height=1)
        bt_start["text"] = "同步"
        # bt_start["command"] = bt_method
        # bt_start.bind("<Button-1>", bt_method_start) # 绑定单击事件
        # bt_start.pack(side="left")
        bt_start.grid(column=0, row=0, padx=10, pady=10, ipadx=10, ipady=10)
    
        bt_pause = Button(frame_button, width=12, height=1)
        bt_pause["text"] = "暂停"
        # bt_pause["command"] = bt_method
        # bt_pause.bind("<Button-1>", bt_method_pause)  # 绑定单击事件
        # bt_pause.pack(side="right")
        bt_pause.grid(column=1, row=0, padx=10, pady=10, ipadx=10, ipady=10)
    
        # 显示区域
        frame_show = Frame(app)
        frame_show.pack(side="top", padx=5, pady=5 ,ipadx=5, ipady=5)
        # 创建滚动条
        scroll = Scrollbar(frame_show)
        # 将滚动条填充
        scroll.pack(side=RIGHT, fill=Y)  # side是滚动条放置的位置,上下左右。fill是将滚动条沿着y轴填充
    
        # 显示文字区域
        text_show = Text(frame_show)
        text_show.pack(side=LEFT, fill=Y)
        # 插入初始值
        text_show.insert('end', '你好,欢迎使用!
    ')
        text_show.config(state=DISABLED)  # 禁止编辑
    
        # 将滚动条与文本框关联
        scroll.config(command=text_show.yview)  # 将文本框关联到滚动条上,滚动条滑动,文本框跟随滑动
        text_show.config(yscrollcommand=scroll.set)  # 将滚动条关联到文本框
    
        # 使用 lambda 匿名函数绑定监听控件
        bt_start.bind("<Button-1>", lambda event: bt_method_start(event, bt_start, bt_pause, text_show))  # 绑定单击事件
        bt_pause.bind("<Button-1>", lambda event: bt_method_pause(event, bt_start, bt_pause, text_show))  # 绑定单击事件
    
        root.mainloop()
    
    
    if __name__ == '__main__':
        main()
    

  • 相关阅读:
    饿了么P7级前端工程师进入大厂的面试经验
    前端程序员面试的坑,简历写上这一条信息会被虐死!
    这次来分享前端的九条bug吧
    移动端开发必会出现的问题和解决方案
    创建一个dynamics 365 CRM online plugin (八)
    创建一个dynamics 365 CRM online plugin (七)
    创建一个dynamics 365 CRM online plugin (六)
    创建一个dynamics 365 CRM online plugin (五)
    使用User Primary Email作为GUID的问题
    怎样Debug Dynamics 365 CRM Plugin
  • 原文地址:https://www.cnblogs.com/bartggg/p/12758925.html
Copyright © 2020-2023  润新知