python tkinter页面 使用whlie逻辑的时候 gui页面卡死无响应,但是程序可以运行,怎么解决,循环执行要不日志打印出来。


import tkinter as tk
import threading
import tkinter.ttk
import tkinter.font
import sys
from os.path import abspath, dirname
sys.path.append(abspath(dirname(__file__)))
from tkinter import *
from TkinterDesigner import Fun
import time
import psycopg2
class Application(tk.Tk):
        # 生成界面
    def __init__(self,root,isTKroot = True):
        uiName = self.__class__.__name__
        Fun.Register(uiName,'UIClass',self)
        self.root = root
        Fun.Register(uiName,'root',root)


        if isTKroot == True:
            root.title("数据库操作工具!")
            Fun.CenterDlg(uiName,root,649,664)
            root.maxsize(649, 664)
            root['background'] = '#efefef'
            # root.attributes("-toolwindow", True)
        Form_1= tkinter.Canvas(root,width = 10,height = 4)
        Form_1.place(x = 0,y = 0,width = 649,height = 664)
        Form_1.configure(bg = "#efefef")
        Form_1.configure(highlightthickness = 0)
        Fun.Register(uiName,'Form_1',Form_1)
        #Create the elements of root
        Label_4 = tkinter.Label(Form_1,text="数据库配置:",width = 10,height = 4)
        Fun.Register(uiName,'Label_4',Label_4)
        Label_4.place(x = 221,y = 5,width = 222,height = 39)
        Label_4.configure(relief = "flat")
        Label_4_Ft=tkinter.font.Font(family='System', size=20,weight='bold',slant='roman',underline=0,overstrike=0)
        Label_4.configure(font = Label_4_Ft)
        Label_5 = tkinter.Label(Form_1,text="数据库库名:",width = 10,height = 4)
        Fun.Register(uiName,'Label_5',Label_5)
        Label_5.place(x = 24,y = 57,width = 100,height = 20)
        Label_5.configure(relief = "flat")
        Label_7 = tkinter.Label(Form_1,text="数据库用户名:",width = 10,height = 4)
        Fun.Register(uiName,'Label_7',Label_7)
        Label_7.place(x = 18,y = 87,width = 100,height = 20)
        Label_7.configure(relief = "flat")
        Label_9 = tkinter.Label(Form_1,text="数据库密码:",width = 10,height = 4)
        Fun.Register(uiName,'Label_9',Label_9)
        Label_9.place(x = 24,y = 121,width = 100,height = 20)
        Label_9.configure(relief = "flat")
        Label_11 = tkinter.Label(Form_1,text="数据库端口号:",width = 10,height = 4)
        Fun.Register(uiName,'Label_11',Label_11)
        Label_11.place(x = 18,y = 187,width = 100,height = 20)
        Label_11.configure(relief = "flat")
        Label_13 = tkinter.Label(Form_1,text="数据库执行语句:",width = 10,height = 4)
        Fun.Register(uiName,'Label_13',Label_13)
        Label_13.place(x = 12,y = 222,width = 100,height = 20)
        Label_13.configure(relief = "flat")
        Text_14 = tkinter.Text(Form_1)
        Fun.Register(uiName,'Text_14',Text_14)
        Text_14.place(x = 112,y = 226,width = 486,height = 166)
        Text_14.configure(relief = "sunken")
        Fun.AddUserData(uiName,'Text_14','sql','string','UPDATE vehicle.t_gps_trajectory_online_copy1 SET gps_time = now();',1)
        Button_16 = tkinter.Button(Form_1,text="循环执行",width = 10,height = 4)
        Fun.Register(uiName,'Button_16',Button_16)
        Button_16.place(x = 495,y = 434,width = 100,height = 28)
        Button_16.configure(command=lambda: Application.thread_it(Application.Button_16_onCommand(uiName, "Button_16")))
        Label_17 = tkinter.Label(Form_1,text="日志:",width = 10,height = 4)
        Fun.Register(uiName,'Label_17',Label_17)
        Label_17.place(x = 46,y = 479,width = 100,height = 20)
        Label_17.configure(relief = "flat")
        Text_18 = tkinter.Text(Form_1)
        Fun.Register(uiName,'Text_18',Text_18)
        Text_18.place(x = 121,y = 484,width = 480,height = 147)
        Text_18.configure(relief = "sunken")
        # Text_18.configure(state="disabled")
        Text_18_Scrollbar = tkinter.Scrollbar(Text_18,orient=tkinter.VERTICAL)
        Text_18_Scrollbar.place(x = 460,y = 0,width = 20,height = 147)
        Text_18_Scrollbar.config(command = Text_18.yview)
        Text_18.config(yscrollcommand = Text_18_Scrollbar.set)
        Fun.Register(uiName,'Text_18_Scrollbar',Text_18_Scrollbar)
        Fun.AddUserData(uiName,'Text_18','text','string','',0)
        Label_19 = tkinter.Label(Form_1,text="SQL语句执行的时间间隔(s):",width = 10,height = 4)
        Fun.Register(uiName,'Label_19',Label_19)
        Label_19.place(x = 112,y = 407,width = 208,height = 20)
        Label_19.configure(relief = "flat")
        Entry_20_Variable = Fun.AddTKVariable(uiName,'Entry_20','5')
        Entry_20 = tkinter.Entry(Form_1,textvariable=Entry_20_Variable)
        Fun.Register(uiName,'Entry_20',Entry_20)
        Entry_20.place(x = 310,y = 407,width = 291,height = 20)
        Entry_20.configure(relief = "sunken")
        Fun.AddUserData(uiName,'Entry_20','sj','string','5',1)
        Label_21 = tkinter.Label(Form_1,text="数据库IP:",width = 10,height = 4)
        Fun.Register(uiName,'Label_21',Label_21)
        Label_21.place(x = 31,y = 154,width = 100,height = 20)
        Label_21.configure(relief = "flat")
        Entry_6_Variable = Fun.AddTKVariable(uiName,'Entry_6','vehicle')
        Entry_6 = tkinter.Entry(Form_1,textvariable=Entry_6_Variable)
        Fun.Register(uiName,'Entry_6',Entry_6)
        Entry_6.place(x = 112,y = 57,width = 486,height = 20)
        Entry_6.configure(relief = "sunken")
        Fun.AddUserData(uiName,'Entry_6','database','string','vehicle',1)
        Entry_22_Variable = Fun.AddTKVariable(uiName,'Entry_22','192.168.104.235')
        Entry_22 = tkinter.Entry(Form_1,textvariable=Entry_22_Variable)
        Fun.Register(uiName,'Entry_22',Entry_22)
        Entry_22.place(x = 112,y = 154,width = 486,height = 20)
        Entry_22.configure(relief = "sunken")
        Fun.AddUserData(uiName,'Entry_22','host','string','192.168.104.235',1)
        Entry_12_Variable = Fun.AddTKVariable(uiName,'Entry_12','5433')
        Entry_12 = tkinter.Entry(Form_1,textvariable=Entry_12_Variable)
        Fun.Register(uiName,'Entry_12',Entry_12)
        Entry_12.place(x = 113,y = 187,width = 485,height = 20)
        Entry_12.configure(relief = "sunken")
        Fun.AddUserData(uiName,'Entry_12','port','string','5433',1)
        Entry_10_Variable = Fun.AddTKVariable(uiName,'Entry_10','Hylink2014@postgres')
        Entry_10 = tkinter.Entry(Form_1,textvariable=Entry_10_Variable)
        Fun.Register(uiName,'Entry_10',Entry_10)
        Entry_10.place(x = 113,y = 121,width = 485,height = 20)
        Entry_10.configure(relief = "sunken")
        Fun.AddUserData(uiName,'Entry_10','password','string','Hylink2014@postgres',1)
        Entry_8_Variable = Fun.AddTKVariable(uiName,'Entry_8','postgres')
        Entry_8 = tkinter.Entry(Form_1,textvariable=Entry_8_Variable)
        Fun.Register(uiName,'Entry_8',Entry_8)
        Entry_8.place(x = 114,y = 87,width = 484,height = 20)
        Entry_8.configure(relief = "sunken")
        Fun.AddUserData(uiName,'Entry_8','user','string','postgres',1)
        Button_15 = tkinter.Button(Form_1,text="执行一次",width = 10,height = 4)
        Fun.Register(uiName,'Button_15',Button_15)
        Button_15.place(x = 383,y = 434,width = 100,height = 28)
        Button_15.configure(command=lambda:Application.thread_it(Application.Button_15_onCommand(uiName,"Button_15")))
        #Inital all element's Data
        Fun.InitElementData(uiName)

    # 连接数据库
    def run(database, user, password, host, port, sql, sj):
        conn = psycopg2.connect(database=str(database), user=str(user), password=str(password), host=str(host),
                                port=str(port))
        cur = conn.cursor()  # 创建指针对象
        sql_shijian = sql
        cur.execute(sql_shijian)
        # 关闭练级
        conn.commit()
        cur.close()
        conn.close()

    # 校验字段
    def verification(database, user, password, host, port, sql, sj, rizhi, button):
        if database == '':
            Fun.MessageBox("数据库库名不能为空!")
        elif user == '':
            Fun.MessageBox('数据库用户名不能为空!')
        elif password == '':
            Fun.MessageBox('数据库密码不能为空!')
        elif host == '':
            Fun.MessageBox('数据库IP不能为空!')
        elif port == '':
            Fun.MessageBox('数据库端口号不能为空!')
        elif sql == '\n':
            Fun.MessageBox('数据库执行语句不能为空!')
        elif sj == '':
            Fun.MessageBox('SQL语句执行的时间间隔(s)不能为空!')
        elif button == 1:
            try:
                Application.run(database=database, user=user, password=password, host=host, port=port, sql=sql, sj=sj)
                rizhi.insert(END, Application.logs(sj=sj, tishi='程序运行正常!')[1])
            except BaseException as e:
                rizhi.insert(END, Application.logs(sj=sj, tishi='程序报错了!' + '\n' + '报错信息:' + str(e))[1])
        # elif button == 2:
        #     n = 0
        #     while True:
        #         n = n + 1
        #         try:
        #             Application.run(database=database, user=user, password=password, host=host, port=port, sql=sql, sj=sj)
        #             rizhi.insert(END, Application.logs(sj=sj, tishi='程序运行' + '\n' + '正常!',n=n)[0])
        #             time.sleep(int(sj))
        #         except BaseException as e:
        #             rizhi.insert(END, Application.logs(sj=sj,tishi='程序报错了!' + '\n' + '报错信息:'+str(e),n=n)[0])
        #             time.sleep(600)

        elif button == 2:
            n = 0
            while True:
                n = n + 1
                print(Application.logs(sj=sj, tishi='程序运行' + '\n' + '正常!', n=n)[0])
                rizhi.insert(END, Application.logs(sj=sj, tishi='程序运行' + '\n' + '正常!', n=n)[0])
                time.sleep(int(sj))

    # 日志
    def logs(sj, tishi, n=1):
        rizhi_1 = 'SQL语句每{}秒执行一次!当前执行第'.format(str(sj)) + str(n) + '次!'
        rizhi_2 = 'SQL语句执行了一次!'
        current_time = time.strftime('%Y-%m-%d %H:%M:%S', time.localtime(time.time()))
        logmsg_in_one = str(current_time) + " " + str(rizhi_1) + str(tishi) + "\n"  # 换行
        logmsg_in_two = str(current_time) + " " + str(rizhi_2) + str(tishi) + "\n"  # 换行
        return logmsg_in_one, logmsg_in_two

    # 字段元素
    def field(uiName):
        database = Fun.GetText(uiName, 'Entry_6')
        user = Fun.GetText(uiName, 'Entry_8')
        password = Fun.GetText(uiName, 'Entry_10')
        host = Fun.GetText(uiName, 'Entry_22')
        port = Fun.GetText(uiName, 'Entry_12')
        sql = Fun.GetText(uiName, 'Text_14')
        sj = Fun.GetText(uiName, 'Entry_20')
        rihzi = Fun.GetElement(uiName, 'Text_18')
        return database, user, password, host, port, sql, sj, rihzi

    # 循环执行按钮
    def Button_16_onCommand(uiName, widgetName):
        yusu = Application.field(uiName=uiName)
        Application.verification(database=yusu[0], user=yusu[1], password=yusu[2], host=yusu[3], port=yusu[4], sql=yusu[5],
                     sj=yusu[6],
                     rizhi=yusu[7], button=2)

    # 执行一次按钮
    def Button_15_onCommand(uiName, widgetName):
        yusu = Application.field(uiName=uiName)
        Application.verification(database=yusu[0], user=yusu[1], password=yusu[2], host=yusu[3], port=yusu[4], sql=yusu[5],
                     sj=yusu[6],
                     rizhi=yusu[7], button=1)


    # 线程处理
    @staticmethod
    def thread_it(func):
        t = threading.Thread(target=func)
        t.setDaemon(True)  # 守护--就算主界面关闭,线程也会留守后台运行(不对!)
        t.start()  # 启动
        t.join()          # 阻塞--会卡死界面!



root = tkinter.Tk()
app = Application(root=root)
root.mainloop()






运行结果及报错内容

无报错内容

我的解答思路和尝试过的方法
我想要达到的结果

点击循环执行,日志实现能实时展示,页面不卡死

img


            while True:
                n = n + 1
                print(Application.logs(sj=sj, tishi='程序运行' + '\n' + '正常!', n=n)[0])
                rizhi.insert(END, Application.logs(sj=sj, tishi='程序运行' + '\n' + '正常!', n=n)[0])
                time.sleep(int(sj))

这部分代码因为是死循环,一直占用tk的主线程所以会卡死,你将部分代码用多线程去执行,这样不会tk的主线程