Tkinter ttk.Checkbox不起作用

时间:2018-11-17 15:29:23

标签: python matplotlib tkinter

我遇到了一个错误。我的代码中的ttk.Checkbutton具有常数0。当我单击它时,该值完全不变。但是奇怪的是,其他ttk.Checkbutton也可以正常工作。这是麻烦的代码:

c1=ttk.Checkbutton(container,text='axis_y',variable=self.Int4,onvalue=1, offvalue=0,command=self.check1)
#c5 = ttk.Checkbutton(container,text='axis_z',variable=self.Int5,onvalue=1, offvalue=0,command=self.check1)

c1对我来说很好用,但是c5不,基本上,它们是相同的代码。有人有同样的问题吗?我不知道。

当我点击按钮时:

enter image description here

结果如下:

enter image description here

输出一个常量0,但是如果我更改为c1,则选中按钮:

enter image description here

有效。

enter image description here

代码更改为:

c1 = ttk.Checkbutton(container,text='z轴',variable=self.Int1,onvalue=1, offvalue=0,command=self.check1)
c1.grid(row=3,column=0)
#c5 = ttk.Checkbutton(container,text='z轴',variable=self.Int5,onvalue=1, offvalue=0,command=self.check1)
#c5.grid(row=3,column=0)

奇怪的事情。

这是我的全部作品。

import numpy as np
import tkinter as tk
from tkinter import ttk
import matplotlib
matplotlib.use('TkAgg')
from matplotlib.backends.backend_tkagg import FigureCanvasTkAgg
from matplotlib.figure import Figure
from matplotlib.animation import FuncAnimation
from tkinter import *

def read_file(path):
    print(path)
    file = open(path,'rb')
    cuvA = []
    cuvB = []
    cuvC = []
    cuvD = []
    dic = {}
    dic['flag'] = False
    while True:
        line = file.readline()
        words = line.split()
        if words != []:
            for i in range(1,5):
                if i == 1:
                    cuvA.append(int(words[i-1]))
                elif i == 2:
                    cuvB.append(int(words[i-1]))
                elif i == 3:
                    cuvC.append(int(words[i-1]))
                elif i == 4:
                    cuvD.append(int(words[i-1]))
        else:
            dic['x'] = range(0,len(cuvA))
            dic['cuvA'] = cuvA
            dic['cuvB'] = cuvB
            dic['cuvC'] = cuvC
            dic['cuvD'] = cuvD
            dic['flag'] = True
            print(cuvA)
            break
    return dic

class reader():
    def __init__(self,txt,container):
        data = txt.get()
        self.speed = 0
        self.dic = read_file(data)
        print(len(self.dic['x']))
        self.y = self.dic['cuvA']
        self.y2 = self.dic['cuvB']
        self.y3 = self.dic['cuvC']
        self.y4 = self.dic['cuvD']
        self.x = np.arange(0,100,1)
        self.Int1 = tk.IntVar()
        self.Int2 = tk.IntVar()
        self.Int3 = tk.IntVar()
        self.Int4 = tk.IntVar()
        self.Int5 = tk.IntVar()
        c1 = ttk.Checkbutton(container,text='axis_z',variable=self.Int1,onvalue=1, offvalue=0,command=self.check1)
        c2 = ttk.Checkbutton(container,text='standard_axis',variable=self.Int2,onvalue=1, offvalue=0,command=self.check2)
        c3 = ttk.Checkbutton(container,text='axis_x',variable=self.Int3,onvalue=1, offvalue=0,command=self.check3)
        c4 = ttk.Checkbutton(container,text='axis_y',variable=self.Int4,onvalue=1, offvalue=0,command=self.check4)
        #c5 = ttk.Checkbutton(container,text='axis_z',variable=self.Int5,onvalue=1, offvalue=0,command=self.check1)
        c3.grid(row=3,column=2)
        c2.grid(row=3,column=1)
        c1.grid(row=3,column=0)
        c4.grid(row=3,column=3)
        #c5.grid(row=3,column=0)

        self.figure = Figure(figsize=(4,4),dpi=100)
        p = self.figure.add_subplot(111)
        self.canvas = FigureCanvasTkAgg(self.figure,container)
        self.canvas.get_tk_widget().grid(row=4,columnspan=4,sticky='nwse')
        self.canvas.draw()
        self.line, = p.plot(self.x,self.y[0:100])
        self.line1, = p.plot(self.x,self.y2[0:100])
        self.line2, = p.plot(self.x,self.y3[0:100])
        self.line3, = p.plot(self.x,self.y4[0:100])
        self.lines = []
        self.ys = []
        self.background = self.canvas.copy_from_bbox(p.bbox)
        self.timer = self.canvas.new_timer(interval=1)
        self.timer.add_callback(self.update,self.lines)
        self.timer.start()

    def check1(self):
        print(self.Int1.get())
        if self.Int1.get() == 1:
            self.insert_line(self.line,self.y)
        if self.Int1.get() == 0:
            self.remove_line(self.line,self.y)
    def check2(self):
        if self.Int2.get() == 1:
            self.insert_line(self.line1,self.y2)
        if self.Int2.get() == 0:
            self.remove_line(self.line1,self.y2)
    def check3(self):
        if self.Int3.get() == 1:
            self.insert_line(self.line2,self.y3)
        if self.Int3.get() == 0:
            self.remove_line(self.line2,self.y3)
    def check4(self):
        if self.Int4.get() == 1:
            self.insert_line(self.line3,self.y4)
        if self.Int4.get() == 0:
            self.remove_line(self.line3,self.y4)
    def stoptime(self):
        print(self.Int5.get())
        if self.Int5.get() == 1:
            self.timer.stop()
            print("stop!!")

    def remove_line(self,line,y):
        if line in self.lines:
            self.lines.remove(line)
            self.ys.remove(y)
            print("remove!")
        else:
            pass

    def insert_line(self,line,y):
        if line in self.lines:
            pass
        else:
            self.lines.append(line)
            self.ys.append(y)
            print('Sucess')

    def update(self,line):
        if max(self.x) < len(self.dic['x'])-5:
            self.x[:] += 5
            temp = []
            for y in self.ys:
                temp_sub = []
                for index in self.x[:]:
                    temp_sub.append(y[index])
                temp.append(temp_sub)
            for i in range(0,len(temp)):
                self.lines[i].set_ydata(temp[i])
            self.canvas.restore_region(self.background)
            for i in range(0,len(temp)):
                self.figure.draw_artist(self.lines[i])
            self.canvas.blit(self.figure.bbox)
        else:
            self.timer.stop()
    def __del__(self):
        self.timer.stop()

system = tk.Tk()
system.title('System')
container = tk.Frame(system)
container.pack(side='top',expand=True)
text = tk.Entry(container,width=10)
text.grid(row=0,column=0,sticky='nwse')
button = ttk.Button(container,text='Analyze!',command=lambda:reader(text,container)).grid(row=0,column=1,sticky='nwse')
button2 = ttk.Button(container,text='Exit',command=lambda:system.destroy()).grid(row=0,column=2,sticky='nwse')

system.mainloop()

2 个答案:

答案 0 :(得分:0)

以下是c1c5的定义:

    c1 = ttk.Checkbutton(container,text='axis_z',variable=self.Int1,onvalue=1, offvalue=0,command=self.check1)
    c5 = ttk.Checkbutton(container,text='axis_z',variable=self.Int5,onvalue=1, offvalue=0,command=self.check1)

c1切换名为self.Int1的变量并调用方法self.check1

c5切换名为self.Int5的变量并调用方法self.check1

self.check1显示self.Int1的值,但是c5切换self.Int5。如果您已将c1注释掉,则self.Int1不会发生任何变化,并且将保持为零。

也许您打算编写方法check5并将command=self.check5放在c5上?

答案 1 :(得分:0)

问题中的代码仍然不是重现问题所需的最少代码,因此,以下代码未经测试,因此可能会有一些[轻微]错误,但这不会改变要点。 / p>

无论如何,问题出在您设置command的{​​{1}}选项的方式上。 这就是你所拥有的(重写后更具可读性,并显示出它们之间的相同点和不同点):

Checkbutton

与这些功能相关联的 c1 = ttk.Checkbutton(container, onvalue=1, offvalue=0, text='axis_z', variable=self.Int1, command=self.check1) c2 = ttk.Checkbutton(container, onvalue=1, offvalue=0, text='standard_axis', variable=self.Int2, command=self.check2) c3 = ttk.Checkbutton(container, onvalue=1, offvalue=0, text='axis_x', variable=self.Int3, command=self.check3) c4 = ttk.Checkbutton(container, onvalue=1, offvalue=0, text='axis_y', variable=self.Int4, command=self.check4) 函数是:

command

这是很多非常重复的代码,不是必需的。 相反,您需要定义一个单个泛型 def check1(self): print(self.Int1.get()) if self.Int1.get() == 1: self.insert_line(self.line, self.y) if self.Int1.get() == 0: self.remove_line(self.line, self.y) def check2(self): if self.Int2.get() == 1: self.insert_line(self.line1, self.y2) if self.Int2.get() == 0: self.remove_line(self.line1, self.y2) def check3(self): if self.Int3.get() == 1: self.insert_line(self.line2, self.y3) if self.Int3.get() == 0: self.remove_line(self.line2, self.y3) def check4(self): if self.Int4.get() == 1: self.insert_line(self.line3, self.y4) if self.Int4.get() == 0: self.remove_line(self.line3, self.y4) 函数,该函数接受告诉其使用哪些数据的参数,例如:

checker()

使用它,您将可以像这样创建 def checker(self, var, line, y): print(var.get()) if var.get() == 1: self.insert_line(line, y) if var.get() == 0: self.remove_line(line, y)

Checkbutton

请注意如何将数据作为每个 c1 = ttk.Checkbutton(container, onvalue=1, offvalue=0, text='axis_z', variable=self.Int1, command=lamdba: self.checker(self.Int1, self.line, self.y)) c2 = ttk.Checkbutton(container, onvalue=1, offvalue=0, text='standard_axis', variable=self.Int2, command=lamdba: self.checker(self.Int2, self.line1, self.y2)) c3 = ttk.Checkbutton(container, onvalue=1, offvalue=0, text='axis_x', variable=self.Int3, command=lamdba: self.checker(self.Int3, self.line2, self.y3)) c4 = ttk.Checkbutton(container, onvalue=1, offvalue=0, text='axis_y', variable=self.Int4, command=lamdba: self.checker(self.Int4, self.line3, self.y4)) 中的参数传递给checker()。除了减少代码量,我认为这将解决始终从按钮获得相同值的问题。