尝试获取列位置时出现 Pandas 表错误

问题描述 投票:0回答:1

这是我的代码示例 - 我使用 tkinter,其中包含选项卡和 pandas 表。 当我尝试将数据插入第一个选项卡中的单元格时,我收到错误

`

import pandas as pd
from pandastable import Table
import tkinter as tk
from tkinter import ttk
 
class PandasTableApp(tk.Tk):
    def __init__(self):
        super().__init__()
        self.title("PandasTable in Tabs")
        self.geometry("800x600")
 
        # Sample DataFrames
        data1 = {'A': [1, 2, 3], 'B': [4, 5, 6], 'C': [7, 8, 9]}
        df1 = pd.DataFrame(data1)
        data2 = {'X': [10, 20, 30], 'Y': [40, 50, 60], 'Z': [70, 80, 90]}
        df2 = pd.DataFrame(data2)
 
        # Create Tab Control
        tab_control = ttk.Notebook(self)
 
        tab1 = ttk.Frame(tab_control)
        tab2 = ttk.Frame(tab_control)
 
        tab_control.add(tab1, text='Tab 1')
        tab_control.add(tab2, text='Tab 2')
 
        tab_control.pack(expand=1, fill='both')
 
        # Create PandasTable instances
        self.table1 = Table(tab1, dataframe=df1)
        self.table2 = Table(tab2, dataframe=df2)
 
        self.table1.show()
        self.table2.show()
 
        # Bind events for each table
        self.table1.bind("<Return>", self.handle_return_table1)
        self.table2.bind("<Return>", self.handle_return_table2)
 
    def handle_return_table1(self, event):
        # Custom handler for the Enter key event for table1
        self.table1.handle_arrow_keys(event)
        return "break"
 
    def handle_return_table2(self, event):
        # Custom handler for the Enter key event for table2
        self.table2.handle_arrow_keys(event)
        return "break"
 
if __name__ == "__main__":
    app = PandasTableApp()
    app.mainloop()`

这是我得到的错误:

C:\Users\xxxx\AppData\Local\Programs\Python\Python39\lib\tkinter\__init__.py:1884: FutureWarning: Downcasting object dtype arrays on .fillna, .ffill, .bfill is deprecated and will change in a future version. Call result.infer_objects(copy=False) instead. To opt-in to the future behavior, set `pd.set_option('future.no_silent_downcasting', True)`
  return self.func(*args)
C:\Users\xxxx\AppData\Local\Programs\Python\Python39\lib\tkinter\__init__.py:1884: FutureWarning: Downcasting object dtype arrays on .fillna, .ffill, .bfill is deprecated and will change in a future version. Call result.infer_objects(copy=False) instead. To opt-in to the future behavior, set `pd.set_option('future.no_silent_downcasting', True)`
  return self.func(*args)
C:\Users\xxxxx\AppData\Local\Programs\Python\Python39\lib\tkinter\__init__.py:1884: FutureWarning: Downcasting object dtype arrays on .fillna, .ffill, .bfill is deprecated and will change in a future version. Call result.infer_objects(copy=False) instead. To opt-in to the future behavior, set `pd.set_option('future.no_silent_downcasting', True)`
  return self.func(*args)
C:\Users\xxxxx\AppData\Local\Programs\Python\Python39\lib\tkinter\__init__.py:1884: FutureWarning: Series.__getitem__ treating keys as positions is deprecated. In a future version, integer keys will always be treated as labels (consistent with DataFrame behavior). To access a value by position, use `ser.iloc[pos]`
  return self.func(*args)
C:\Users\xxxxx\AppData\Local\Programs\Python\Python39\lib\tkinter\__init__.py:1884: FutureWarning: Setting an item of incompatible dtype is deprecated and will raise an error in a future version of pandas. Value '2' has dtype incompatible with int64, please explicitly cast to a compatible dtype first.
  return self.func(*args)
Exception in Tkinter callback
Traceback (most recent call last):
  File "C:\Users\xxxxx\AppData\Local\Programs\Python\Python39\lib\tkinter\__init__.py", line 1884, in __call__
    return self.func(*args)
  File "C:\Users\xxxxx\Desktop\xxxx-xxx\xxx-venv\lib\site-packages\pandastable\core.pyy", line 2350, in handle_arrow_keys
    x,y = self.getCanvasPos(self.currentrow, self.currentcol-1)
  File "C:\Users\xxxxx\Desktop\xxxx-xxx\xxx-venv\lib\site-packages\pandastable\core.py", line 2151, in getCanvasPos
    x1,y1,x2,y2 = self.getCellCoords(row,col)
  File "C:\Users\xxxxx\Desktop\xxxx-xxx\xxx-venv\lib\site-packages\pandastable\core.py", line 2140, in getCellCoords
    x1=self.col_positions[col]
IndexError: list index out of range

当我写入第二个选项卡时,它可以工作 - 我能够写入那里的单元格。 但写入第一个选项卡会崩溃并发送此错误。

知道为什么会发生吗?

提前致谢。

python pandas tkinter tkinter-canvas pandastable
1个回答
0
投票

该错误似乎与每个选项卡中的表的初始化有关。

tab1
上启动应用程序后尝试修改单元格时,我可以重现该错误,但如果我转到
tab2
,然后返回到
tab1
,则不会出现错误。

解决方法可能是在启动应用程序后通过每个选项卡手动强制初始化。

将此行添加到

def __init__(self):
:

self.after(100, self.initialize_tabs)

after
方法确保应用程序已加载。我尝试不使用它,但仍然遇到同样的问题。

并将此方法添加到您的类中:

def initialize_tabs(self):
    # Switch to each tab to initialize
    self.tab_control.select(self.tab2)
    self.tab_control.select(self.tab1)

此外,您没有正确处理

return
键。
handle_arrow_keys
方法无法用于
return
 键。

pandastable
包使得正确完成绑定变得更加复杂。

首先,我们需要将每个表的引用存储在

__init__
中,并将
return
键绑定到应用程序,而不是表:

self.tables = {self.tab1: self.table1, self.tab2: self.table2}
self.bind("<Return>", self.handle_return)

然后,我们可以定义

handle_return
方法:

def handle_return(self, event):
    try:
        widget_name = event.widget.rsplit(".!", 1)[0]
        widget = self.nametowidget(widget_name)
        table = self.tables.get(widget, None)
        self.process_enter_key(table)
    except AttributeError:
        pass
    return "break"

如果不在表格中时按下

return
键,则不会追加任何内容,但是当在表格内按下该键时,代码会获取表格父元素的名称,然后使用
tables
词典的帮助。

这样,你就可以随心所欲地操纵对象了。

例如:

def process_enter_key(self, table):
    row = table.getSelectedRow()
    col = table.getSelectedColumn()
    if row < len(table.model.df):
        row += 1
    else:
        row = 1
        if col < len(table.model.df.columns) - 1:
            col += 1
        else:
            col = 0
    table.setSelectedRow(row-1)
    table.setSelectedCol(col)
    table.redraw()

如果可能的话,这会转到下一行。如果没有,则转到下一列的第一行,如果不可能,则转到第一行第一列。这样,当您按

return
键时,您始终会到达选项卡的某个单元格。

由于我不知道的原因,行从 1 开始索引,列从 0 开始索引。

© www.soinside.com 2019 - 2024. All rights reserved.