首页 > 解决方案 > 在 Tkinter 中不断传递值并相应地对其进行修改

问题描述

目的是 input fn 接受字符串输入并将其传递到 GUI fn 运行条件并相应地修改 tkinter 窗口。

#*********************************** IMPORTING MODULES*****************
import tkinter
from tkinter import*
import tkinter.messagebox
import sqlite3
import os
import threading
from time import sleep
from input import*
conn = sqlite3.connect('portal.db')
c = conn.cursor()
global a
#*************** TKINTER GUI CODE******************
def gui(a):
    window = tkinter.Tk()
    window.title("Smart Notice Board")

    #********************** FRAMES OF MAIN WINDOW(HOME)******************

    top = Canvas(window,width=1024,height=184)
    top.pack(fill=X)

    middle = Canvas(window, width=1024, height=450, bg='steelblue')
    middle.pack(fill=X)

    main_left = Canvas(middle, width=275, height=450, bg='lightgreen')
    main_left.pack(side=LEFT)

    main_right = Canvas(middle, width=800, height=450, bg='steelblue')
    main_right.pack(side=RIGHT)

    bottom = Canvas(window, width=1024, height=70, bg='black')
    bottom.pack(fill=X)
    #************************** IMAGES********************

    i_top = tkinter.PhotoImage(file='F:\\C_backup\\fyp\\5 jan 2k19\\BG.png')
    top.create_image(0,10, anchor=tkinter.NW,image = i_top)
    i_right = tkinter.PhotoImage(file='F:\\C_backup\\fyp\\5 jan 2k19\\aus1.png')
    main_right.create_image(0,0, anchor=tkinter.NW,image = i_right)
    #i_left = tkinter.PhotoImage(file='F:\\C_backup\\fyp\\5 jan 2k19\\widget1.png')
    #main_left.create_image(0,0, anchor=tkinter.NW,image = i_left)


    t1 = tkinter.PhotoImage(file='F:\\C_backup\\fyp\\5 jan 2k19\\first.png')
    t2 = tkinter.PhotoImage(file='F:\\C_backup\\fyp\\5 jan 2k19\\BG.png')


    #***************** TIMETABLE IMAGE VIEWING FN***********************

    def home():

        main_right.create_image(0,0, anchor=tkinter.NW,image = t2)

    #*********************** TIMETABLE BUTTON PRESS FN*************************
    def timetable():

        main_right.create_image(0,0, anchor=tkinter.NW,image = t1)


    #******************************* CONDITIONS**********************
    if a == "NULL":
        timetable()
    if a == "HOME":
        home()
    #*********************** MAIN MENU BUTTONS****************

    button_1 = Button(text = '  HOME', anchor = 'w', height = 2, width = 8,activebackground = '#33B5e5',bg = 'brown',fg = 'white',command = home)
    top.create_window(2,150,anchor = 'nw', window = button_1)


    button_2 = Button(text='TIMETABLE', height = 2, width=12, activebackground = '#33B5e5', bg = 'brown', fg = 'white',command = timetable)
    top.create_window(75,150, anchor='nw', window = button_2)
    window.mainloop()


#************************** MAIN LOOP************************

if __name__ == "__main__":
    #print(valuea())
    a=valuea()
    gui(a)

现在我想要的是不断运行那个东西并更新 Tkinter 窗口;但是 2btn fn 只需要一次并将其传递给运行 tkinter 的 GUI fn 并卡在 window.mainloop 上,因为 tkinter 是无限循环。请建议我一个解决方案,您也可以通过仅从您的计算机设置图片来运行此代码 在此处输入图像描述

标签: pythonpython-3.xmultithreadingtkinter

解决方案


定期运行代码的标准方法是使用根窗口mainloop的方法注册一个超时函数。after

但是,无论你在这样的超时函数中(实际上是在所有其他回调中)做什么,它都不应该阻塞,因为这会锁定主循环!所以你不能使用input. 但是您可以从 中读取sys.stdin,这是一个io.TextIOWrapper实例。

您可以input在第二个线程中使用。但由于 Tkinter 不是线程安全的,第二个线程不应该使用Tkinter 函数或方法。所以你不应该简单地从第二个线程更新标签。您可以将输入保存/附加到全局变量,但您必须使用锁或互斥锁来保护它。您需要在 Tkinter 主线程中使用超时函数来测试第二个线程是否释放了锁或互斥锁,以便 Tkinter 线程可以声明它并访问数据。正如你所看到的,这真的很复杂。所以一般不建议混合使用 Tkinter 和线程。


推荐阅读