zoukankan      html  css  js  c++  java
  • 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()
    

  • 相关阅读:
    Java实现蓝桥杯算法提高12-2扑克排序
    Java实现蓝桥杯算法提高12-2扑克排序
    Java实现蓝桥杯算法提高12-2扑克排序
    Java实现N*N矩阵旋转(360度)
    Java实现N*N矩阵旋转(360度)
    Java实现N*N矩阵旋转(360度)
    Java实现ACMGoShopping
    linux 远程桌面工具NX
    windows下用vs2010编译ffmpeg
    在Windows下编译ffmpeg完全手册
  • 原文地址:https://www.cnblogs.com/bartggg/p/12758925.html
Copyright © 2011-2022 走看看