在下面的程序中,我用 matplotlib 打开一个图形(在示例中没有出现任何内容,但无论如何,问题不是这个)。在角落(左下角),有一个用于将光标添加到图表的按钮。它会打开一个 tkinter 窗口来输入参数(x 轴上的光标 1 的值,光标 2 的值相同)。当激活检查按钮并且正确填充字段(使用浮动)时,应该创建光标,如果未选择检查按钮,则应该删除它们。问题是检查按钮的状态始终为“False”,即使它被激活也是如此。此外,为了实时获取字段的值,我使用“trace”方法来跟踪与每个字段关联的变量,但它始终为空,即使内部有东西也是如此。但奇怪的是,当我执行 saisie_curseur_1.get() 时(因此获取小部件而不是关联的变量,它可以工作)
from tkinter import *
from tkinter import filedialog,messagebox
from tkinter import ttk
import tkinter as tk
import numpy as np
import matplotlib.pyplot as plt
from matplotlib.figure import Figure
from matplotlib.patches import Circle
import matplotlib.patches as mpatches
from matplotlib.backend_bases import MouseButton
from matplotlib.backends.backend_tkagg import FigureCanvasTkAgg,NavigationToolbar2Tk
from matplotlib.widgets import Button,CheckButtons,Slider,Cursor
def gestion_curseurs(event):
global fenetre,fenetre_ouverte,largeur_fenetre,longueur_fenetre,bouton_curseurs,decision_curseurs,label_alerte_curseurs,saisie_curseur_1,variable_curseur_1,saisie_curseur_2,variable_curseur_2,bouton_valider_curseurs,bouton_annuler_curseurs
if fenetre_ouverte=="non":
fenetre=tk.Tk()
fenetre.protocol("WM_DELETE_WINDOW",fermer_curseurs)
fenetre.title("Gestion des curseurs")
fenetre.resizable(width=False,height=False)
fenetre["bg"]="black"
fenetre_ouverte="oui"
label_curseurs=Label(fenetre,text="GESTION DES CURSEURS",bg="black",fg="white",font=25)
label_curseurs.place(x=0,y=0)
decision_curseurs=tk.BooleanVar()
bouton_curseurs=tk.Checkbutton(fenetre,text="Curseurs",bg="white",fg="black",font=25,variable=decision_curseurs,onvalue=True,offvalue=False)
bouton_curseurs.place(x=0,y=label_curseurs.winfo_reqheight()+25)
if valeur_curseur_1=="":bouton_curseurs.select()
label_alerte_curseurs=Label(fenetre,text="",bg="black",fg="red",font=25)
label_curseur_1=Label(fenetre,text="Curseur 1 : ",bg="black",fg="blue",font=25)
label_curseur_1.place(x=0,y=label_curseurs.winfo_reqheight()+25+bouton_curseurs.winfo_reqheight()+10)
variable_curseur_1=tk.StringVar()
saisie_curseur_1=tk.Entry(fenetre,textvariable=variable_curseur_1,bg="white",fg="black",insertbackground="black",font=25,width=10)
saisie_curseur_1.place(x=label_curseur_1.winfo_reqwidth(),y=label_curseurs.winfo_reqheight()+25+bouton_curseurs.winfo_reqheight()+10)
variable_curseur_1.trace("w",lambda name,index,mode,variable_curseur_1=variable_curseur_1:entree_saisie_curseurs(variable_curseur_1))
label_curseur_2=Label(fenetre,text="Curseur 2 : ",bg="black",fg="red",font=25)
label_curseur_2.place(x=0,y=label_curseurs.winfo_reqheight()+25+bouton_curseurs.winfo_reqheight()+10+label_curseur_1.winfo_reqheight()+5)
variable_curseur_2=tk.StringVar()
saisie_curseur_2=tk.Entry(fenetre,textvariable=variable_curseur_2,bg="white",fg="black",insertbackground="black",font=25,width=10)
saisie_curseur_2.place(x=label_curseur_2.winfo_reqwidth(),y=label_curseurs.winfo_reqheight()+25+bouton_curseurs.winfo_reqheight()+10+label_curseur_1.winfo_reqheight()+5)
variable_curseur_2.trace("w",lambda name,index,mode,variable_curseur_2=variable_curseur_2:entree_saisie_curseurs(variable_curseur_2))
bouton_valider_curseurs=tk.Button(fenetre,text="\u2714 Valider",bg="white",fg="green",font=25,width=10,command=valider_curseurs,state="disable")
bouton_valider_curseurs.place(x=0,y=label_curseurs.winfo_reqheight()+25+bouton_curseurs.winfo_reqheight()+10+label_curseur_1.winfo_reqheight()+5+label_curseur_2.winfo_reqheight()+25)
bouton_annuler_curseurs=tk.Button(fenetre,text="\u2716 Annuler",bg="white",fg="red",font=25,width=10,command=fermer_curseurs)
bouton_annuler_curseurs.place(x=bouton_valider_curseurs.winfo_reqwidth()+5,y=label_curseurs.winfo_reqheight()+25+bouton_curseurs.winfo_reqheight()+10+label_curseur_1.winfo_reqheight()+5+label_curseur_2.winfo_reqheight()+25)
largeur_fenetre,longueur_fenetre=label_curseurs.winfo_reqheight()+25+bouton_curseurs.winfo_reqheight()+10+label_curseur_1.winfo_reqheight()+5+label_curseur_2.winfo_reqheight()+25+bouton_valider_curseurs.winfo_reqheight(),int(fenetre.winfo_screenheight()/720*500*1.2*1.5)
fenetre.geometry("{}x{}+{}+{}".format(longueur_fenetre,largeur_fenetre,fenetre.winfo_screenwidth()//2-(longueur_fenetre+2*(fenetre.winfo_rootx()-fenetre.winfo_x()))//2,fenetre.winfo_screenheight()//2-(largeur_fenetre+fenetre.winfo_rooty()-fenetre.winfo_y()+fenetre.winfo_rootx()-fenetre.winfo_x())//2))
variable_curseur_1.set(valeur_curseur_1),variable_curseur_2.set(valeur_curseur_2)
bouton_OK=tk.Button(fenetre,text="\u2714",bg="white",fg="green",command=entree_saisie_curseurs_bis)
bouton_OK.place(x=longueur_fenetre-bouton_OK.winfo_reqwidth(),y=0)
def entree_saisie_curseurs(valeur_curseurs):entree_saisie_curseurs_bis()
def entree_saisie_curseurs_bis():
print("curseur 1 : ",variable_curseur_1.get(),"curseur 2 : ",variable_curseur_2.get())
print("curseur 1 : ",saisie_curseur_1.get(),"curseur 2 : ",saisie_curseur_2.get())
print(decision_curseurs.get())
if variable_curseur_1.get()!="":
try:
float(variable_curseur_1.get())
erreur_curseur_1="non"
saisie_curseur_1.configure(fg="black")
except:
erreur_curseur_1="oui"
saisie_curseur_1.configure(fg="red")
else:erreur_curseur_1="vide"
if variable_curseur_2.get()!="":
try:
float(variable_curseur_2.get())
erreur_curseur_2="non"
saisie_curseur_2.configure(fg="black")
except:
erreur_curseur_2="oui"
saisie_curseur_2.configure(fg="red")
else:erreur_curseur_2="vide"
if erreur_curseur_1=="oui" or erreur_curseur_2=="oui":
label_alerte_curseurs.configure(text="\u26A0 Saisissez un nombre dans les champs en rouge.")
label_alerte_curseurs.place(x=bouton_valider_curseurs.winfo_reqwidth()+5+bouton_annuler_curseurs.winfo_reqwidth()+10,y=largeur_fenetre-bouton_valider_curseurs.winfo_reqheight()/2-label_alerte_curseurs.winfo_reqheight()/2)
elif erreur_curseur_1!="oui" and erreur_curseur_2=="vide" or erreur_curseur_1=="vide" and erreur_curseur_2!="oui":
label_alerte_curseurs.configure(text="\u26A0 Veuillez remplir les champs relatifs aux curseurs.")
label_alerte_curseurs.place(x=bouton_valider_curseurs.winfo_reqwidth()+5+bouton_annuler_curseurs.winfo_reqwidth()+10,y=largeur_fenetre-bouton_valider_curseurs.winfo_reqheight()/2-label_alerte_curseurs.winfo_reqheight()/2)
else:label_alerte_curseurs.place_forget()
if erreur_curseur_1=="non" and erreur_curseur_2=="non":bouton_valider_curseurs["state"]="normal"
else:bouton_valider_curseurs["state"]="disable"
def valider_curseurs():
global curseur_1,valeur_curseur_1,curseur_2,valeur_curseur_2
if decision_curseurs.get()==False:
valeur_curseur_1,valeur_curseur_2="",""
try:curseur_1.remove(),curseur_2.remove()
except:pass
else:
valeur_curseur_1,valeur_curseur_2=variable_curseur_1.get(),variable_curseur_2.get()
curseur_1=ax1.axvline(x=variable_curseur_1.get(),color="blue",linestyle="-")
curseur_2=ax1.axvline(x=variable_curseur_2.get(),color="red",linestyle="-")
ax1.figure.canvas.draw()
fermer_curseurs()
def fermer_curseurs():
global fenetre_ouverte
try:fenetre.destroy()
except:pass
fenetre_ouverte="non"
def REPRESENTATION_graphe():
global fenetre_ouverte,liste_points_signal,points_signal,x_coords,y_coords,fig,ax1,ax2,press,consigne,event_btn_press,event_btn_release,event_graphek,annot,on,off,valeur_curseur_1,valeur_curseur_2
fenetre_ouverte,valeur_curseur_1,valeur_curseur_2="non","",""
x=[1,2,3,4,5]
y=[1,2,3,4,5]
# Construction fenêtres Matplotlib
fig=Figure()
ax=fig.add_subplot(111)
axBtn=plt.axes([0.0,0.0,0.1,0.05])
Btn=Button(axBtn,label="Curseurs",color="orange",hovercolor="yellow")
Btn.on_clicked(gestion_curseurs)
# Représentation spectrale
ax.scatter(x,y,s=5,c="red")
plt.show(block=True)
REPRESENTATION_graphe()
为什么与字段和复选按钮关联的变量没有正确返回?
这是因为 matplotlib 的默认后端对于您的情况是
tkagg
,所以第一个绘图窗口实际上是 Tk()
的实例。 通过单击 matplotlib
按钮创建的第二个窗口也是 Tk()
的实例。
该问题是由
Tk()
的多个实例引起的,因为默认情况下,这些 tkinter 变量是在 Tk()
的第一个实例中创建的,因此它们不会链接到在 Tk()
的第二个实例中创建的检查按钮和条目小部件。
对第二个窗口使用
Toplevel()
,或者将这些 tkinter 变量的 master
选项设置为第二个窗口,例如:
decision_currseurs = tk.BooleanVar(master=fenetre)