Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/342.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/node.js/39.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python Tkinter线程化在GUI中使用更改页面_Python_Multithreading_Tkinter - Fatal编程技术网

Python Tkinter线程化在GUI中使用更改页面

Python Tkinter线程化在GUI中使用更改页面,python,multithreading,tkinter,Python,Multithreading,Tkinter,我想在tkinter GUI的两个页面上有两个实时绘图,带有停止实时更新的按钮。到目前为止,我已经成功地在我的第一页中创建了一个实时绘图。但是,我在其他函数中创建线程时遇到问题 api = csb.SeaBreezeAPI() devices = list_devices() #to get the serial number of the device spec = sb.Spectrometer.from_serial_number("FLMS15412") xs =

我想在tkinter GUI的两个页面上有两个实时绘图,带有停止实时更新的按钮。到目前为止,我已经成功地在我的第一页中创建了一个实时绘图。但是,我在其他函数中创建线程时遇到问题

api = csb.SeaBreezeAPI()
devices = list_devices() #to get the serial number of the device

spec = sb.Spectrometer.from_serial_number("FLMS15412")

xs = spec.wavelengths()
ys = spec.intensities()

fig1 = Figure(figsize=(10,6),tight_layout=True)
ax1 = fig1.add_subplot(111)

root = tk.Tk()
root.configure(background = 'light blue')
root.geometry("1400x800")

canvas1=FigureCanvasTkAgg(fig1,master=root)
canvas1.get_tk_widget().place(x=5,y=55) 

cond = False
def starts():                 
    root.after(1,starts)

cond = False
def plot_data():
    if (cond == True):
        ax1.cla()
        ax1.plot(spec.wavelengths(),spec.intensities
        (correct_dark_counts=True),'w',linewidth=1.0)
        ax1.set_xlabel('Wavelength (nm)')
        ax1.set_ylabel('Intensity (a.u.)')
        ax1.set_xlim(200,1000)
        ax1.set_ylim(0,60000) 
        ax1.set_facecolor('#1B1B2A')
        ax1.grid(color='w',linestyle='--',linewidth=0.2)
        canvas1.draw()
    root.after(1,plot_data)    
   
def plot_start():
    global cond
    cond = True

def plot_stop():
    global cond
    cond = False

root.update()
startplot = tk.Button(root, text = "Start", font = ('calibri', 12), command = lambda: plot_start())
startplot.place(x=5,y=25)

root.update()
stopplot = tk.Button(root, text = "Stop", font = ('calibri', 12), command = lambda: plot_stop())
stopplot.place(x=65,y=25)

root.update()
start = tk.Button(root, text = "Stage", font = ('calibri', 12), 
command=threading.Thread(target=plot_data).start())
start.place(x=125,y=25)

threading.Thread(target=plot_data).start()

root.after(1,plot_data)
root.mainloop()

这是单个页面中实时绘图的最小代码。我想创建另一个带有另一个live plot的页面。我怎样才能用tkinter做到这一点。任何帮助都将不胜感激。

下面是一个如何将值打印到windows的示例(不确定这是否是@TheLizzard所说的不做的,但这很有效(至少看起来是这样)):


一些代码只是为了外观,但主要部分是两个函数。它们在不同的线程上运行,只需更新textvariable,这使它变得非常简单。另外,请记住在循环之间放置一些暂停(就像我在
睡眠(0.2)
中所做的那样),否则只运行while循环将冻结GUI(值将被更新,但不可能与之交互)

您可以使用TopLevel并几乎复制代码。如果我使用TopLevel,它是否仍在主循环中?我可以在顶级窗口中使用另一个线程吗?将
command=threading.thread(…).start()
更改为
command=threading.thread(…).start
在使用tkinter时也不要使用线程。有时,如果您尝试从不同的线程访问tkinter,tkinter会崩溃。但这应该不是什么大问题,您仍然可以从一个线程更改小部件属性,同时将所有小部件保持在同一个线程(包括windows)中为什么要使用
\u thread.start\u new\u thread
而不是
threading.thread
?@TheLizzard,因为我知道如何更好地使用它;我也研究过线程,但在这种情况下使用
\u-thread
要容易得多(至少对我来说),但是如何启动线程是我唯一知道的
\u-thread
@matiss这非常有用,正是我想要的!我们是否可以在第一页添加一个按钮,以便在按下按钮后弹出第二页?@NicoleWaves是的,这是可能的,但您希望线程从开始运行还是仅在窗口打开时运行?实际上,我认为如果从一开始就运行另一个线程,可能会更容易,也可能更好too@NicoleWaves好的,我编辑的代码现在应该可以工作了
from tkinter import Tk, Toplevel, Label, StringVar, Button
from _thread import start_new_thread
from time import sleep


def update_root():
    counter = 0
    while True:
        root_var.set(f'{counter}')
        sleep(0.2)
        counter += 1


def update_tp():
    counter = 0
    while True:
        tp_var.set(f'{counter}')
        sleep(0.2)
        counter += 1


def second_window():
    tp = Toplevel(root)
    tp.title('Window 2')
    tp_label = Label(tp, textvariable=tp_var, font='default 20 normal')
    tp_label.pack(padx=200, pady=50)


root = Tk()
root.title('Window 1')

root_var = StringVar()
root_label = Label(root, textvariable=root_var, font='default 20 normal')
root_label.pack(padx=200, pady=50)

Button(root, text='Open other window', command=second_window).pack()

tp_var = StringVar()

start_new_thread(update_root, ())
start_new_thread(update_tp, ())

root.mainloop()