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

如何在PySimpleGUI中实现两列复选框以操作Pandas DataFrame的In_Possession列值

实现PySimpleGUI复选框控制Pandas DataFrame数据

你的思路方向是对的,但Tree控件确实不太适合这种互斥复选框的交互场景,换成Table控件会更直观且容易实现界面与数据的双向绑定。我帮你调整了代码,实现通过TRUE/FALSE两列的复选框来修改DataFrame的In_Possession值,同时保证两列复选框互斥(选了TRUE就不能选FALSE,反之亦然)。

修改后的完整代码

import PySimpleGUI as sg
import pandas as pd
from io import BytesIO
from PIL import Image, ImageDraw

def get_checkbox_icon(is_checked, is_disabled=False):
    """生成复选框图标:支持未选中、选中、禁用(灰色选中)三种状态"""
    box_size = (32, 32)
    background = (255, 255, 255, 0)
    rectangle = (3, 3, 29, 29)
    check_line = ((9, 17), (15, 23), (23, 9))
    
    im = Image.new('RGBA', box_size, background)
    draw = ImageDraw.Draw(im, 'RGBA')
    # 绘制复选框边框,禁用状态用灰色边框
    draw.rectangle(rectangle, outline='black' if not is_disabled else 'grey', width=3)
    
    if is_checked:
        # 绘制勾选标记,禁用状态用灰色标记
        draw.line(check_line, fill='black' if not is_disabled else 'grey', width=3, joint='curve')
    
    with BytesIO() as output:
        im.save(output, format="PNG")
        return output.getvalue()

# 预生成三种状态的图标
icon_unchecked = get_checkbox_icon(False)
icon_checked = get_checkbox_icon(True)
icon_disabled_checked = get_checkbox_icon(True, is_disabled=True)

# 初始化DataFrame
genshin_characters = {
    'CHARACTER_NAME': ['Amber','Jean','Lisa','HuTao'],
    'In_Possession': [True, False, True, False]
}
df = pd.DataFrame(genshin_characters)

# 把DataFrame数据转换成Table需要的格式:每行包含角色名、TRUE列图标、FALSE列图标
def update_table_data():
    table_data = []
    for _, row in df.iterrows():
        if row['In_Possession']:
            # 拥有角色:TRUE列选中,FALSE列禁用
            table_data.append([row['CHARACTER_NAME'], icon_checked, icon_disabled_checked])
        else:
            # 未拥有角色:FALSE列选中,TRUE列禁用
            table_data.append([row['CHARACTER_NAME'], icon_disabled_checked, icon_checked])
    return table_data

# 设置PySimpleGUI主题和字体
sg.theme('LightPurple')
sg.set_options(font=('Helvetica', 16))

# 构建布局:使用Table控件替代Tree,更适合行列数据交互
layout = [
    [sg.Table(
        values=update_table_data(),
        headings=['CHARACTER_NAME', 'TRUE', 'FALSE'],
        auto_size_columns=False,
        col_widths=[20, 6, 6],  # 手动设置列宽,适配复选框图标大小
        num_rows=10,
        key='-TABLE-',
        row_height=48,
        enable_events=True,  # 开启点击事件监听
        select_mode=sg.TABLE_SELECT_MODE_BROWSE
    )],
    [sg.Button('Submit'), sg.Button('Quit')]
]

window = sg.Window('Character Collection', layout, finalize=True)
table = window['-TABLE-']

while True:
    event, values = window.read()
    
    if event in (sg.WINDOW_CLOSED, 'Quit'):
        break
    
    elif event == '-TABLE-':
        # 获取用户点击的行和列索引
        selected = values['-TABLE-']
        if not selected:
            continue
        row_idx = selected[0]
        col_idx = table.CurrentColumn
        
        # 根据点击的列更新DataFrame数据
        if col_idx == 1:  # 点击了TRUE列
            df.at[row_idx, 'In_Possession'] = True
        elif col_idx == 2:  # 点击了FALSE列
            df.at[row_idx, 'In_Possession'] = False
        
        # 同步更新Table显示
        table.update(values=update_table_data())
    
    elif event == 'Submit':
        # 提交时打印更新后的DataFrame,方便验证数据正确性
        print("更新后的角色拥有状态:")
        print(df)
        sg.popup("数据已更新!可查看控制台输出详情")

window.close()

关键功能说明

  1. 互斥复选框逻辑:

    • 点击TRUE列时,将对应行的In_Possession设为True,同时把FALSE列的复选框设为灰色禁用状态(避免重复点击)
    • 点击FALSE列时则相反,确保同一行只能有一个选项生效
  2. DataFrame双向同步:

    • 每次点击复选框都会直接修改DataFrame的In_Possession值,保证界面显示与底层数据完全一致
    • update_table_data()函数负责将DataFrame数据转换成Table需要的图标格式,每次修改后重新渲染界面
  3. 用户体验优化:

    • 手动设置列宽,让复选框显示更协调
    • 禁用未选中的列,减少无效操作
    • Submit按钮点击后弹出提示,并在控制台打印完整数据,方便验证修改结果

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.04.27 18:12:50