You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Python Tkinter中show_info与show_filtered_data函数无法显示最后一列‘Notes’

Tkinter信息录入系统无法显示Excel最后一列"Notes"

我基于Python Tkinter开发的信息录入系统中,show_info和show_filtered_data两个函数在展示Excel数据时,无法显示最后一列‘Notes’,仅能显示8列中的前7列。Excel表格中确实包含完整的8列数据,尝试多种方法甚至求助ChatGPT都未能解决,作为Python新手感到十分困惑。

相关代码如下:

'''
This code demonstrates a simple information entry system using Tkinter.
The entered information is saved to an Excel file, and the user can also
view the information from the Excel file.

The code uses the following libraries:
- tkinter: For creating the GUI
- messagebox: For displaying error or success messages
- scrolledtext: For displaying the information in a scrollable text area
- openpyxl: For working with Excel files
- sys: For exiting the program
- tkcalendar: For displaying date entry fields
'''

import tkinter as tk
from tkinter import messagebox, ttk
from tkinter import scrolledtext
import openpyxl
from openpyxl import load_workbook
import sys
from tkcalendar import DateEntry



def validate_returned(event):
    input_string = entry_returned.get()
    if input_string and input_string.upper() not in ['Y', 'N']:
        entry_returned.delete(0, tk.END)
        messagebox.showerror("Error", "Please enter 'Y' or 'N'.")

def save_to_excel():
    # Get the information entered by the user
    first_name = entry_first_name.get()
    surname = entry_surname.get()
    ern = entry_ern.get()
    first_day_sick = entry_first_day_sick.get()
    last_day_sick = entry_last_day_sick.get()
    fit_note_expiry = entry_fit_note_expiry.get()
    returned = entry_returned.get()
    notes = entry_notes.get()

    try:
        # Load the existing Excel workbook
        workbook = openpyxl.load_workbook('data.xlsx')
        sheet = workbook.active
    except FileNotFoundError:
        # If the workbook doesn't exist, create a new one
        workbook = openpyxl.Workbook()
        sheet = workbook.active
        # Add headers to the sheet if it's empty
        if sheet.max_row == 0:
            sheet.append(["First Name", "Surname", "ERN", "FDS", "LDS", "FitN", "Ret", "Notes"])

    # Append the information to the Excel sheet
    sheet.append([first_name, surname, ern, first_day_sick, last_day_sick, fit_note_expiry, returned, notes])

    # Save the Excel file
    workbook.save('data.xlsx')
    messagebox.showinfo("Success", "Information saved to Excel file!")

    # Clear the entry fields
    entry_first_name.delete(0, tk.END)
    entry_surname.delete(0, tk.END)
    entry_ern.delete(0, tk.END)
    entry_first_day_sick.delete(0, tk.END)
    entry_last_day_sick.delete(0, tk.END)
    entry_fit_note_expiry.delete(0, tk.END)
    entry_returned.delete(0, tk.END)
    entry_notes.delete(0, tk.END)

# Function to show a new window with filtered data
def show_filtered_data():
    # Load the Excel workbook
    try:
        workbook = load_workbook("data.xlsx")

        # Select the appropriate sheet
        current_sheet = workbook.active

        # Define the headers
        headers = ["First", "Sur", "ERN", "FDS", "LDS", "FitN", "Ret", "Notes"]

        # Filter rows where "Returned = n"
        filtered_data = []
        for row in current_sheet.iter_rows(values_only=True):
            if row[6] == "n":
                filtered_data.append(row)

        # Create a new window for filtered data
        filtered_window = tk.Toplevel(window)
        filtered_window.title("Returned = n")
        filtered_window.geometry("1500x600")

        # Create a treeview widget to display the filtered data
        tree = ttk.Treeview(filtered_window, columns=headers, show="headings")
        
        # Set the column headers
        for header in headers:
            tree.heading(header, text=header)

        # Set the style to center-align the data
        style = ttk.Style()
        style.configure("Treeview", cellanchor="center")

        # Set the column alignment to center
        for col in headers:
            tree.column(col, anchor="center")

        # Insert the filtered data into the treeview
        for row in filtered_data:
            tree.insert("", tk.END, values=row)

        tree.pack()

    except FileNotFoundError:
        messagebox.showerror("Error", "No data file found!")




def show_info():
    try:
        # Load the existing Excel workbook
        workbook = openpyxl.load_workbook('data.xlsx')

        # Select the appropriate sheet
        current_sheet = workbook.active

        # Get the headers
        headers = ["First", "Sur", "ERN", "FDS", "LDS", "FitN", "Ret", "Notes"]

        # Create a new window to display the information
        info_window = tk.Toplevel()
        info_window.title("Information Display")

        # Create a treeview widget
        tree = ttk.Treeview(info_window, columns=headers, show="headings")

        # Set the column headers
        for header in headers:
            tree.heading(header, text=header)

        # Set the style to center align the data
        style = ttk.Style()
        style.configure("Treeview", cellanchor="center")

        # Set the column alignment to center
        for col in headers:
            tree.column(col, anchor="center")

        # Get the data from the sheet
        data = current_sheet.iter_rows(min_row=2, values_only=True)

        # Insert the data into the treeview
        for row in data:
            tree.insert("", tk.END, values=row[:len(headers)])

        # Calculate the total width required by all columns
        total_width = sum(tree.column(col, option="width") for col in headers)

        # Set the width of the information window to accommodate all columns
        info_window.geometry(f"{total_width+30}x600")

        # Create a horizontal scrollbar
        scrollbar = ttk.Scrollbar(info_window, orient="horizontal", command=tree.xview)

        # Configure the scrollbar to scroll horizontally with the treeview
        tree.configure(xscrollcommand=scrollbar.set)

        # Pack the treeview and scrollbar
        tree.pack(side="left", fill="both", expand=True)
        scrollbar.pack(fill="x")

    except FileNotFoundError:
        messagebox.showerror("Error", "No data file found!")




def close_program():
    sys.exit()

# Create the main application window
window = tk.Tk()
window.title("Information Entry")
window.geometry("400x600")

# Create labels and entry fields
label_first_name = tk.Label(window, text="First Name:")
label_first_name.pack()
entry_first_name = tk.Entry(window)
entry_first_name.pack()

label_surname = tk.Label(window, text="Surname:")
label_surname.pack()
entry_surname = tk.Entry(window)
entry_surname.pack()

label_ern = tk.Label(window, text="ERN:")
label_ern.pack()
entry_ern = tk.Entry(window)
entry_ern.pack()

label_first_day_sick = tk.Label(window, text="First Day Sick:")
label_first_day_sick.pack()
entry_first_day_sick = DateEntry(window)
#entry_first_day_sick = tk.Entry(window)
entry_first_day_sick.pack()

label_last_day_sick = tk.Label(window, text="Last Day Sick:")
label_last_day_sick.pack()
entry_last_day_sick = DateEntry(window)
#entry_last_day_sick = tk.Entry(window)
entry_last_day_sick.pack()

label_fit_note_expiry = tk.Label(window, text="Fit Note Expiry:")
label_fit_note_expiry.pack()
entry_fit_note_expiry = DateEntry(window)
#entry_fit_note_expiry = tk.Entry(window)
entry_fit_note_expiry.pack()

label_returned = tk.Label(window, text="Returned Y/N:")
label_returned.pack()
entry_returned = tk.Entry(window)
entry_returned.pack()
entry_returned.bind("<KeyRelease>", validate_returned)

label_notes = tk.Label(window, text="Notes:")
label_notes.pack()
entry_notes = tk.Entry(window)
entry_notes.pack()

# Create a button to save the information to Excel
button_save = tk.Button(window, text="Save to Excel", command=save_to_excel)
button_save.pack()

# Create a button to display the information
button_show = tk.Button(window, text="Show Info", command=show_info)
button_show.pack()

button_close = tk.Button(window, text="Close", command=close_program)
button_close.pack()

button_filter = tk.Button(window, text="Show Filtered Data", command=show_filtered_data)
button_filter.pack()

# Start the GUI event loop
window.mainloop()

问题原因及修复方案

核心问题

两个函数中,Treeview控件的列宽度未明确设置,且show_filtered_data缺少水平滚动条,导致窗口宽度不足时最后一列"Notes"被挤压隐藏。show_info中的row[:len(headers)]切片是多余操作,但并非直接原因。

具体修复步骤

1. 修复show_info函数

  • 移除多余的切片操作,直接传入完整行数据
  • 为每列设置固定宽度,确保列能正常显示
  • 调整窗口宽度计算逻辑,基于设置的列宽计算

修改后的show_info关键代码段:

# Insert the data into the treeview
for row in data:
    tree.insert("", tk.END, values=row)  # 移除多余切片

# 为每列设置固定宽度,保证显示空间
for col in headers:
    tree.column(col, anchor="center", width=120)

# Calculate the total width required by all columns
total_width = sum(tree.column(col, option="width") for col in headers)

# Set the width of the information window to accommodate all columns
info_window.geometry(f"{total_width+30}x600")

2. 修复show_filtered_data函数

  • 为每列设置固定宽度
  • 添加水平滚动条,支持横向滚动查看所有列
  • 调整控件布局,让Treeview和滚动条配合工作

修改后的show_filtered_data关键代码段:

# Set the column alignment to center and add fixed width
for col in headers:
    tree.column(col, anchor="center", width=120)

# Insert the filtered data into the treeview
for row in filtered_data:
    tree.insert("", tk.END, values=row)

# 添加水平滚动条
scrollbar = ttk.Scrollbar(filtered_window, orient="horizontal", command=tree.xview)
tree.configure(xscrollcommand=scrollbar.set)

# 调整布局,让滚动条正常工作
tree.pack(side="left", fill="both", expand=True)
scrollbar.pack(fill="x")

验证说明

修复后,两个函数的Treeview都会为每列分配足够显示空间,加上水平滚动条的支持,即使窗口宽度临时不足,也能通过滚动查看完整的8列数据,包括"Notes"列。

内容的提问来源于stack exchange,提问作者KCranfield

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.19 04:44:55