Python Tkinter上一页复选框/复选框值的条件显示
我目前正在使用tkinter开发GUI,遇到了一个问题 我希望用户能够: 要在“传感器历史记录主页”页面中从复选按钮中选择任意数量的列,每个列名称1, 然后,当点击一个按钮时,会弹出一个新页面“sensors\u custom\u history”(传感器自定义历史记录),显示每个选定列的一些内容。 请在下面找到最小可复制示例:Python Tkinter上一页复选框/复选框值的条件显示,python,tkinter,Python,Tkinter,我目前正在使用tkinter开发GUI,遇到了一个问题 我希望用户能够: 要在“传感器历史记录主页”页面中从复选按钮中选择任意数量的列,每个列名称1, 然后,当点击一个按钮时,会弹出一个新页面“sensors\u custom\u history”(传感器自定义历史记录),显示每个选定列的一些内容。 请在下面找到最小可复制示例: import tkinter as tk import configparser, pickle class UI_demo: def __init__(sel
import tkinter as tk
import configparser, pickle
class UI_demo:
def __init__(self, master=None):
"""
# Load config_back.ini parameters
config = configparser.ConfigParser()
config.read('setup_front.ini')
self.output_folder = config['DEFAULT']['path_to_output_folder']
print("config_front.ini file was successfully loaded ! \n")
# Load in-scope columns
with open(self.output_folder+"headers_inscope", 'rb') as f:
self.columns = pickle.load(f)
"""
self.columns = ["Var1", "Var2", "Var3", "Var4", "Var5"] # Simple sample as the actual dataset is private
super().__init__()
self.master = master
self.master.geometry("1650x1000")
self.master.state('zoomed')
self.initHomePageUI()
def initHomePageUI(self):
self.master.title("Homepage")
# Some stuff....
# Menu buttons
frame1 = tk.Frame(self.master)
frame1.pack(side="top", fill="both", pady=20, expand=True)
but3 = tk.Button(frame1, text="History", font=('Courier',12),
bd=3, width=36, command = self.sensors_history_homepage)
but3.pack(side="top", pady=12)
def sensors_history_homepage(self):
# Open new window
window = tk.Toplevel(self.master)
window.title("Sensors selection")
window.state('zoomed')
# Top empty frame
top_frame = tk.Frame(window, height=80)
top_frame.pack(side='top', fill='x')
# Page header
title0 = tk.Label(window, borderwidth=1, text="Please select sensor(s) you wish to consult")
title0.config(font=('Courier',14))
title0.pack(side='top')
# List of sensors as check-buttons (10 sensors per column as in real-case I have 200+ sensors to display)
frame0 = tk.Frame(window, borderwidth=1)
frame0.pack(side='top', fill='x')
l_frames = []
l_checkvar = []
l_checkb = []
for i in range(int(len(self.columns)/10)):
l_frames = l_frames + [tk.Frame(frame0, borderwidth=1)]
l_frames[i].pack(side='left')
l_checkvar = l_checkvar +[tk.BooleanVar(master=window) for l in range(10)]
l_checkb = l_checkb + [tk.Checkbutton(l_frames[i], text=self.columns[10*i+l], variable=l_checkvar[10*i+l],
onvalue=True, offvalue=False, height=2, width=10) for l in range(10)]
for j in range(10*i,10*i+9):
l_checkb[j].pack(side='top')
l_checkb[j].toggle()
tmp_residual = int(len(self.columns)%10)
if not tmp_residual==0:
i = int(len(self.columns)/10)
l_checkvar += [tk.BooleanVar(master=window) for l in range(10*i,10*i+tmp_residual)]
l_frames += [tk.Frame(frame0, borderwidth=1)]
l_frames[i].pack(side='left')
l_checkb += [tk.Checkbutton(l_frames[i], text=self.columns[10*i+l], variable=l_checkvar[10*i+l],
onvalue=True, offvalue=False, height=2, width=10) for l in range(0,tmp_residual)]
for l in range(0,tmp_residual):
l_checkb[10*i+l].pack(side='top')
l_checkb[10*i+l].toggle()
# Check all / Uncheck all buttons
def check_all():
self.checkvars = [x.set(True) for x in self.checkvars]
def uncheck_all():
self.checkvars = [x.set(False) for x in self.checkvars]
frame1 = tk.Frame(window, borderwidth=1)
frame1.pack(side='top', fill='x')
but_ca = tk.Button(frame1, text="Check all", font=('Courier',10), bd=3,
command=check_all)
but_ca.pack(side='left', padx=5)
but_ua = tk.Button(frame1, text="Uncheck all", font=('Courier',10), bd=3,
command=uncheck_all)
but_ua.pack(side='left', padx=5)
self.checkvars = l_checkvar
# Button to display selected sensors' signal history
refresh_frame = tk.Frame(window, borderwidth=1)
refresh_frame.pack(side='top', fill='x')
refresh_but = tk.Button(refresh_frame, text="Display \n for selected sensors", font=('Courier',12),
bd=3, width=30, command=self.sensors_custom_history)
refresh_but.pack(side='top')
def sensors_custom_history(self):
# Open new window
window = tk.Toplevel(self.master)
window.title("Display of...")
window.geometry("1500x970")
window.state('zoomed')
# Page header
title0 = tk.Label(window, borderwidth=1, text="Sensors history")
title0.config(font=('Courier',14))
title0.pack(side='top')
# List of previously selected sensors
l_cols = []
l_checkvalues = list(map(lambda x: x.get(), self.checkvars))
for i in range(len(l_checkvalues)):
if l_checkvalues[i]==True:
l_cols = l_cols + [self.columns[i]]
# Some display on the page....
# Debugging console display
print("checkvars : length = "+str(len(l_checkvalues))+", nb of true = "+str(sum(l_checkvalues))+'\n')
print(l_checkvalues)
print('\n'+"columns selected : length = "+str(len(l_cols))+'\n')
print(l_cols)
if __name__ == '__main__':
root = tk.Tk()
app = UI_demo(master=root)
root.mainloop()
我的问题是关于将checkVar值从“传感器历史记录”页面传递到“传感器自定义历史记录”页面的问题:
似乎无论在“传感器历史记录”主页中选择了哪些复选框,“传感器历史记录”的打印都会给出相同的结果。
尝试从第2页获取checkVars值时出现以下错误:
我想知道如何正确地将checkVars值传递到“sensors\u custom\u history”页面,以便只显示用户在以前的“sensors\u history\u主页”中选择的信息
任何帮助都将不胜感激。这可能不是问题的全部,但是您的check\u all/uncheck\u all函数通过将none列表重新分配给self.checkvars,正在破坏self.checkvars。列表理解并不适用于简单地对列表中的每个项目做一些事情,它们的目的是生成一个新的列表。嗨@jasonharper,事实上,这似乎是整个问题所在。如果我启动UI并从列表中选择,而不使用check_alan和uncheck_all按钮,我会得到预期的结果。因此,如何在不重新写入相关的复选框的情况下,选中/取消选中带有2个按钮的所有复选框?非常感谢您的帮助。简单地去掉这两个函数中self.checkvars的赋值就可以修复它们,但是您仍然无法生成Nones列表。编写类似内容的正确方法是使用两行:self.checkvars:/x.setTrue中的x
File "<ipython-input-3-8b450e7f0e91>", line 149, in sensors_custom_history
l_checkvalues = list(map(lambda x: x.get(), self.checkvars))
File "<ipython-input-3-8b450e7f0e91>", line 149, in <lambda>
l_checkvalues = list(map(lambda x: x.get(), self.checkvars))
AttributeError: 'NoneType' object has no attribute 'get'