Mar-13-2024, 04:54 PM
(This post was last modified: Mar-13-2024, 05:55 PM by deanhystad.)
Hi,
I would like to have a Maplotlib window with a graph and interacting with normal instruction from the kernel. In parallel, I would like to have a QT or tkinter window that behave independetly (in a thread) that interact also with the matplotlib window for instance to modify the selection of the data to plot. I have globally a problem of "main thread" saying that mpl instructions have to be done from the same thread as the thread that called the mpl window. If I call the mpl window from the tkinter thread , I cannot interact directly with the matplotlib window with the kernel prompt. Is it clear ? Do you have a solution for this ?
For instance I tried this script, but tkinter window is not able to modify the mpl graph (I attached the file, don't know how to put is correctly inside the message).
I would like to have a Maplotlib window with a graph and interacting with normal instruction from the kernel. In parallel, I would like to have a QT or tkinter window that behave independetly (in a thread) that interact also with the matplotlib window for instance to modify the selection of the data to plot. I have globally a problem of "main thread" saying that mpl instructions have to be done from the same thread as the thread that called the mpl window. If I call the mpl window from the tkinter thread , I cannot interact directly with the matplotlib window with the kernel prompt. Is it clear ? Do you have a solution for this ?
For instance I tried this script, but tkinter window is not able to modify the mpl graph (I attached the file, don't know how to put is correctly inside the message).
import tkinter as tk import threading import queue import matplotlib.pyplot as plt %matplotlib qt class MainWindow(tk.Tk): def __init__(self, initial_value, event_queue, fig ): super().__init__() self.event_queue = event_queue self.title('Parameter window') self.geometry('300x150') self.listcounter = initial_value self.fig = fig self.counter = self.listcounter[0] self.label = tk.Label(self, text=f'Present value : {self.counter}') self.label.pack(pady=10) self.add_button = tk.Button(self, text='Add 1', command=self.add_one) self.add_button.pack(pady=5) self.close_button = tk.Button(self, text='Close', command=self.close_window) self.close_button.pack(pady=5) def add_one(self): self.counter += 1 self.label.config(text=f'Present value : {self.counter}') self.listcounter.append(self.counter) self.event_queue.put(('CounterChanged', self.counter)) ax = self.fig.axes[0] ax.set_title('From parameter window') ax.grid() def close_window(self): self.destroy() def listener(event_queue): while True: event = event_queue.get() if event[0] == 'CounterChanged': print(f"Event detected : counter value : {event[1]}") def run_gui(initial_value, event_queue, fig): window = MainWindow(initial_value, event_queue, fig) window.mainloop() if __name__ == '__main__': fig = plt.figure() event_queue = queue.Queue() initial_value = [10] thread = threading.Thread(target=run_gui, args=(initial_value, event_queue, fig,)) thread.start() plt.plot([1,3,5], [5,9,3])
deanhystad write Mar-13-2024, 05:55 PM:
Please post all code, output and errors (it it's entirety) between their respective tags. Refer to BBCode help topic on how to post. Use the "Preview Post" button to make sure the code is presented as you expect before hitting the "Post Reply/Thread" button.
Please post all code, output and errors (it it's entirety) between their respective tags. Refer to BBCode help topic on how to post. Use the "Preview Post" button to make sure the code is presented as you expect before hitting the "Post Reply/Thread" button.
Attached Files
Tkinter_talking_Mpl.py (Size: 1.75 KB / Downloads: 115)