【问题标题】:Unintended interaction between tkinter checkbuttonstkinter 检查按钮之间的意外交互
【发布时间】:2021-09-07 07:13:00
【问题描述】:

我正在编写一个小程序:

  • 获取一个excel文件
  • 从该 excel 文件中读取一些潜在的文件名
  • 搜索潜在文件名是该名称一部分的文件

我的问题是:我有两列带有复选按钮。但出于某些原因,column1 (cb) 中的复选按钮绑定到 column2 (cb2) 中的复选按钮。因此,当在 column1 或 column2 中按下一个复选按钮时,另一列中相应的复选按钮会被选中或取消选中。

import tkinter as tk
from tkinter import filedialog
import pandas as pd
import numpy as np
import os

class FileMover:
    def __init__(self):
        self.master = tk.Tk()
        self.master.title('File Mover')
        self.master.geometry('700x700')
        self.master.resizable(0,0)

        self.source_folder_path = ''
        self.destination_folder_path = ''

        self.part_dict = {}

        self.mainframe = tk.Frame(self.master, height=700, width=700, highlightbackground='red', highlightthickness=0)
        self.mainframe.grid(row=0, column=0)
        self.mainframe.grid_propagate(False)

        self.top_frame = tk.Frame(self.mainframe, height=84, width=700, highlightbackground='blue', highlightthickness=3)
        self.top_frame.grid(row=0, column=0)
        self.top_frame.grid_propagate(False)
        
        self.center_frame = tk.Frame(self.mainframe, height=700-2*80-2*3, width=700, highlightbackground='red', highlightthickness=0)
        self.center_frame.grid(row=1, column=0)
        self.center_frame.grid_propagate(False)

        self.botton_frame = tk.Frame(self.mainframe, height=80, width=700, highlightbackground='red', highlightthickness=3)
        self.botton_frame.grid(row=2, column=0, sticky='s')
        self.botton_frame.grid_propagate(False)

        self.left_frame = tk.Frame(self.center_frame, height=700-2*80, width=350, highlightbackground='blue', highlightthickness=3)
        self.left_frame.grid(row=0, column=0)
        self.left_frame.grid_propagate(False)

        self.right_frame = tk.Frame(self.center_frame, height=700-2*80, width=350, highlightbackground='green', highlightthickness=3)
        self.right_frame.grid(row=0, column=1)
        self.right_frame.grid_propagate(False)


        self.b_get_part_list = tk.Button(self.top_frame, text='Select Part List', width=20, command=self.get_file_names).grid(row=0, column=0, sticky='w')
        self.b_get_source_folder = tk.Button(self.top_frame, text='Select Source Folder', width=20, command=self.get_source_folder).grid(row=1, column=0, sticky='w')
        self.b_get_destination_folder = tk.Button(self.top_frame, text='Select Destination Folder', width=20, command=self.get_destination_folder).grid(row=2, column=0, sticky='w')

        self.left_scroller = tk.Scrollbar(self.left_frame)
        self.left_scroller.grid(row=0, column=1, sticky='ns')

        self.left_text =tk.Text(self.left_frame, width=40, height=33)
        self.left_text.grid(row=0, column=0)
        
        self.left_text.config(yscrollcommand=self.left_scroller.set)
        self.left_scroller.config(command=self.left_text.yview)

        self.right_scroller = tk.Scrollbar(self.right_frame)
        self.right_scroller.grid(row=0, column=1, sticky='ns')

        self.right_text = tk.Text(self.right_frame, width=40, height=33)
        self.right_text.grid(row=0, column=0)

        self.right_text.config(yscrollcommand=self.right_scroller.set)
        self.right_scroller.config(command=self.right_text.yview)

    def get_file_names(self):
        excel_file_path = filedialog.askopenfilename(title='Select Part List', filetypes=[('Excel Files', '*.xlsx')])
        l1 = tk.Label(self.top_frame, text=f'{excel_file_path}')
        l1.grid(row=0, column=1, sticky='w')
        df = pd.read_excel(excel_file_path)
        col_A = 'Unnamed: 0'
        col_B = 'Unnamed: 1'
        index_start = 16
        index_end = len(df[col_A])
        for index in range(index_start, index_end, 1):
            if (df.iloc[index][col_A] and df.iloc[index][col_B]) not in self.part_dict:
                if not np.isnan(df.iloc[index][col_A]):
                    self.part_dict[str(df.iloc[index][col_A])] = {}
                    self.part_dict[str(df.iloc[index][col_A])]['variable_cb'] = tk.IntVar()
                else:
                    self.part_dict[str(df.iloc[index][col_B])] = {}
                    self.part_dict[str(df.iloc[index][col_B])]['variable_cb'] = tk.IntVar() 
        self.cb_packer()

    def cb_packer(self):
        for index, key in enumerate(self.part_dict):
            cb = tk.Checkbutton(self.left_frame, text=key, bg='white', command=lambda i=index: self.cb_changer(list(self.part_dict)[i]))
            self.left_text.window_create('end', window=cb)
            self.left_text.insert('end', '\n')
    
    def cb_changer(self, name):
        if self.part_dict[name]['variable_cb'].get() != 1:
            self.part_dict[name]['variable_cb'].set(1)
            print(self.part_dict[name]['variable_cb'].get())
        else:
            self.part_dict[name]['variable_cb'].set(0)
            print(self.part_dict[name]['variable_cb'].get())

    def cb2_packer(self):
        for index, key in enumerate(self.part_dict):
            try:
                cb2 = tk.Checkbutton(self.right_frame, text=self.part_dict[key]['file'], bg='white', command=lambda i=index: self.cb2_changer(list(self.part_dict)[i]))
                self.right_text.window_create('end', window=cb2)
                self.right_text.insert('end', '\n')
            except:
                pass

    def cb2_changer(self, name):
        if self.part_dict[name]['variable_cb2'].get() != 1:
            self.part_dict[name]['variable_cb2'].set(1)
            print(self.part_dict[name]['variable_cb2'].get())
        else:
            self.part_dict[name]['variable_cb2'].set(0)
            print(self.part_dict[name]['variable_cb2'].get())
                    
    def get_source_folder(self):
        self.source_folder_path = filedialog.askdirectory(title='Select Source Folder')
        l2 = tk.Label(self.top_frame, text=f'{self.source_folder_path}')
        l2.grid(row=1, column=1, sticky='w')
        self.file_crawler()
        self.cb2_packer()

    def file_crawler(self):
        for path, subdirs, files in os.walk(self.source_folder_path):
            for file in files:
                for key in self.part_dict:
                    if key in file:
                        try:
                            self.part_dict[key]['file']
                        except:
                            if file.endswith('pdf') or file.endswith('PDF') or file.endswith('dxf') or file.endswith('DXF') or file.endswith('stp') or file.endswith('STP') or file.endswith('step') or file.endswith('STEP'):
                                self.part_dict[key]['path'] = path
                                self.part_dict[key]['file'] = file
                                self.part_dict[key]['variable_cb2'] = tk.IntVar()

    def get_destination_folder(self):
        pass


gui = FileMover()
gui.master.mainloop()

【问题讨论】:

  • 我认为使用.csv 文件会更好:它们更容易阅读,因为它们是原始文本。此外,您可以将 excel 文件导出到 .csv
  • 我不是生成 xlsx 文件的人。我的问题是,当检查或取消检查其他列中的核心禁止核般的托管顿时,还是未选中。 span>
  • 好的,我知道,我只是想告诉你这个选项。这样您就可以避免因使用模块读取文件的方式而产生的错误。
  • 您发布的代码太多了。你能把它剪成minimal reproducible example吗?
  • 我不能 100% 确定我的代码的哪些部分导致了错误。我敢打赌,它位于以下函数之一中:cb_packer、cb2_packer、cb_changer 或 cb2_changer。

标签: variables tkinter python-3.8


【解决方案1】:

查看您的代码,这部分可能表现得很奇怪:

    col_A = 'Unnamed: 0'
    col_B = 'Unnamed: 1'
    index_start = 16
    index_end = len(df[col_A])
    for index in range(index_start, index_end, 1):
        if (df.iloc[index][col_A] and df.iloc[index][col_B]) not in self.part_dict:
            if not np.isnan(df.iloc[index][col_A]):
                self.part_dict[str(df.iloc[index][col_A])] = {}
                self.part_dict[str(df.iloc[index][col_A])]['variable_cb'] = tk.IntVar()
            else:
                self.part_dict[str(df.iloc[index][col_B])] = {}
                self.part_dict[str(df.iloc[index][col_B])]['variable_cb'] = tk.IntVar() 
    self.cb_packer()

字典中的键是str(df.iloc[index][col_B]),是工作表中的变量。这些可能不是唯一的。

【讨论】:

    猜你喜欢
    • 2015-04-13
    • 1970-01-01
    • 2013-10-21
    • 2021-09-10
    • 2021-08-14
    • 2013-04-05
    • 1970-01-01
    • 1970-01-01
    • 2017-03-08
    相关资源
    最近更新 更多