Tkinter ttk.Checkbox не работает - PullRequest
0 голосов
/ 17 ноября 2018

Я столкнулся с ошибкой. 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 голосов
/ 18 ноября 2018

Код в вашем вопросе все еще вряд ли является минимальным количеством, необходимым для воссоздания проблемы - и по этой причине следующее не проверено и может иметь некоторые [незначительные] ошибки, но это не изменит поставленную точку.

В любом случае, проблема в том, как вы настраиваете параметр command для Checkbutton s.Вот что у вас есть (переписано, чтобы быть более читабельным и показать, что то же самое и что отличается между ними):

        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 s следующим образом:

        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() в качестве аргументов в каждом lambda.Помимо того, что кода меньше, я думаю, это решит проблему с постоянным получением одного и того же значения с кнопки.

0 голосов
/ 17 ноября 2018

Вот определения c1 и c5:

    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?

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...