首页 > 解决方案 > 具有可调整大小列的 tkinter 列表框 - 递归致命错误

问题描述

我正在使用该.place方法。以下代码是可调整大小列的工作简化以及在短时间内用鼠标移动列时出现的错误消息。

import tkinter as tk


def column_drag(event):
    #print(event.x)
    for ii, i in enumerate(column_head):
        if ii != 0:
            currCur = root.winfo_pointerx() - root.winfo_rootx()
            if currCur <= column_head[ii].winfo_x() + 10 and currCur >= column_head[ii].winfo_x() - 10:
                if currCur <= column_head[ii].winfo_x() + 10 and currCur >= column_head[ii].winfo_x() - 10:
                    column_head[ii].configure(cursor="sb_h_double_arrow")
                    column_posx[ii] = currCur
                    column_user[ii] = True
                refresh_run_display()
            else: column_head[ii].configure(cursor="arrow")

def resize(event):
    refresh_run_display()


def refresh_run_display():
    ii = len(column_body)-1
    for i in reversed(column_body):
        # Last column
        if ii+1 == len(column_body):
            if column_user[ii] is False:
                column_head[ii].place(x=ii * 150, y=0, height=20, width=root.winfo_width())
                column_head[ii].update()
                column_body[ii].place(x=ii * 150, y=column_head[ii].winfo_height(), height=120, width=root.winfo_width())
            if column_user[ii] is True:
                column_head[ii].place(x=column_posx[ii], y=0, height=20, width=root.winfo_width())
                column_head[ii].update()
                column_body[ii].place(x=column_posx[ii], y=column_head[ii].winfo_height(), height=120, width=root.winfo_width())
        #middle column
        if ii+1 != len(column_body) and ii != 0:
            if column_user[ii] is False:
                column_head[ii].place(x=ii * 150, y=0, height=20, width=column_head[ii+1].winfo_x())
                column_head[ii].update()
                column_body[ii].place(x=ii * 150, y=column_head[ii].winfo_height(), height=120, width=column_head[ii+1].winfo_x())
            if column_user[ii] is True:
                column_head[ii].place(x=column_posx[ii], y=0, height=20, width=column_head[ii+1].winfo_x())
                column_head[ii].update()
                column_body[ii].place(x=column_posx[ii], y=column_head[ii].winfo_height(), height=120, width=column_head[ii+1].winfo_x())
        #first column
        if ii == 0:
            if column_user[ii] is False:
                column_head[ii].place(x=1, y=0, height=20, width=column_head[ii+1].winfo_x())
                column_head[ii].update()
                column_body[ii].place(x=1, y=column_head[ii].winfo_height(), height=120, width=column_head[ii+1].winfo_x())
            if column_user[ii] is True:
                column_head[ii].place(x=1, y=0, height=20, width=column_head[ii+1].winfo_x())
                column_head[ii].update()
                column_body[ii].place(x=1, y=column_head[ii].winfo_height(), height=120, width=column_head[ii+1].winfo_x())
        ii = ii - 1



root = tk.Tk()
gui_w = 650
gui_h = 270
gui_h_old = 0
x = (root.winfo_screenwidth()/2) - (gui_w/2)
y = (root.winfo_screenheight()/2) - (gui_h/2)
root.geometry('%dx%d+%d+%d' % (gui_w, gui_h, x, y))
root.bind('<Configure>', resize)
root.minsize(width=350, height=315)
root.maxsize(width=root.winfo_screenwidth(), height=root.winfo_screenheight())


column_names = ['id', 'name', 'size', 'time']
column_body = [tk.Listbox(borderwidth=0, highlightthickness=0, exportselection=0, activestyle='none') for i in column_names]
column_head = [tk.Button(text=i, borderwidth=0.5, relief="ridge", anchor="w") for i in column_names]
[i.bind("<Motion>", column_drag) for i in column_head]

column_lead = [False for i in column_names]; column_lead[0] = True
column_flip = [False for i in column_names]
column_user = [False for i in column_names]
column_posx = [0 for i in column_names]

root.mainloop()

错误信息:

Fatal Python error: Cannot recover from stack overflow.

Current thread 0x00001440 (most recent call first):
  File "C:\python37\lib\tkinter\__init__.py", line 1704 in __call__
  File "C:\python37\lib\tkinter\__init__.py", line 1177 in update
  File "path.../tst.py", line 42 in refresh_run_display
  File "path.../tst.py", line 14 in column_drag
Process finished with exit code -1073740791 (0xC0000409)

如果可能,我想保留当前格式。请帮忙!

标签: pythonpython-3.xtkintermultiple-columns

解决方案


我认为这column_head[ii].update()是导致此错误的原因。

之前,column_head[ii].winfo_height()当要求在下一行返回其值时,In testing 会返回一个不正确的值: column_head[ii].place(x=ii * 150, y=0, height=20, width=root.winfo_width())

column_head[ii].update()解决了这个问题,但显然现在没有必要并且注释掉所有column_head[ii].update()似乎都有效。这是调试中调用的行


推荐阅读