社区所有版块导航
Python
python开源   Django   Python   DjangoApp   pycharm  
DATA
docker   Elasticsearch  
aigc
aigc   chatgpt  
WEB开发
linux   MongoDB   Redis   DATABASE   NGINX   其他Web框架   web工具   zookeeper   tornado   NoSql   Bootstrap   js   peewee   Git   bottle   IE   MQ   Jquery  
机器学习
机器学习算法  
Python88.com
反馈   公告   社区推广  
产品
短视频  
印度
印度  
Py学习  »  Python

Python 3:_tkinter.TclError:命令名“”无效。!滚动条“

ranj10 • 5 年前 • 2098 次点击  

我是python编程新手,我正在尝试为时间序列数据创建两个可滚动的帧,但是当我添加动态帧时,它们都没有激活。每个框架包含3个部分,分别显示第1列中的变量、第2列中的绘图和第3行中的唯一日期 Snapshot of the GUI . 我得到以下错误:

    Exception in Tkinter callback
    Traceback (most recent call last):
      File "C:\Users\ranji\Anaconda3\lib\tkinter\__init__.py", line 1702, in __call__
        return self.func(*args)
      File "C:\Users\ranji\Anaconda3\lib\tkinter\__init__.py", line 3069, in set
        self.tk.call(self._w, 'set', first, last)
    _tkinter.TclError: invalid command name ".!scrollbar"
    Exception in Tkinter callback
    Traceback (most recent call last):
      File "C:\Users\ranji\Anaconda3\lib\tkinter\__init__.py", line 1702, in __call__
        return self.func(*args)
      File "C:\Users\ranji\Anaconda3\lib\tkinter\__init__.py", line 3069, in set
        self.tk.call(self._w, 'set', first, last)
    _tkinter.TclError: invalid command name ".!scrollbar2"

你们谁能帮我找出错误的根源吗?

以下是我的代码:

    import os
    import tkinter as tk
    #from tkinter import ttk
    from tkinter import filedialog as fd
    import pandas as pd
    import matplotlib.pyplot as plt
    from matplotlib.backends.backend_tkagg import FigureCanvasTkAgg

    def on_configure(event):
        # update scrollregion after starting 'mainloop'
        canvas1.configure(scrollregion=canvas1.bbox('all'))
        canvas2.configure(scrollregion=canvas2.bbox('all'))

    root = tk.Tk()
    root.geometry('{}x{}'.format(800, 600))

    # layout all of the main containers
    root.grid_rowconfigure(1, weight=1)
    root.grid_columnconfigure(0, weight=1)


    #Global variables
    category = tk.StringVar()
    global rownum
    rownum =0
    mindatetime = pd.to_datetime('1900-01-01 00:00:00')
    maxdatetime = pd.to_datetime('1900-01-01 00:00:00')

    def enterCategory():
        global cat
        cat = category.get()
        global catmainframe
        global rownum
        global add_file

        catmainframe = tk.Frame(canvas1, borderwidth=2, relief="solid")
        catmainframe.grid(row=rownum,column=0,sticky='nsew', padx=3, pady=3)

        catmainframe.grid_rowconfigure(0, weight=1)
        catmainframe.grid_columnconfigure(0, weight=1)     
        catframe = tk.Frame(catmainframe, borderwidth=2, relief="solid")
        catframe.grid(row=0,column=0, sticky='nsew', padx=1, pady=1)

        catlabel = tk.Label(catframe, text=cat)
        catlabel.grid(row=0, column=0, sticky='nsew')

        add_file = tk.Button(catframe,text="Add File",command=openFile)
        add_file.grid(row=0, column=1, sticky='nsew')

        global catchildframe
        catchildframe = tk.Frame(catmainframe, borderwidth=2, relief="solid")
        catchildframe.grid(row=1,column=0,sticky='nsew', padx=1, pady=1)
        catchildframe.grid_rowconfigure(1, weight=1)
        catchildframe.grid_columnconfigure(1, weight=1)  
        global box1, box2, box3
        box1 = tk.Frame(catchildframe, borderwidth=2, relief="solid")
        box2 = tk.Frame(catchildframe, borderwidth=2, relief="solid")
        box3 = tk.Frame(catchildframe, borderwidth=2, relief="solid")
        box1.grid(row=1, column=0, sticky='nsew', padx=10, pady=10)
        box2.grid(row=1, column=1, sticky='nsew', padx=10, pady=10)
        box3.grid(row=1, column=2, sticky='nsew', padx=10, pady=10)
        box1.propagate(1)
        box2.propagate(1)
        box3.propagate(1)

        rownum =  rownum +1

    def openFile():
        parentname = catmainframe.winfo_parent()
        parent = catmainframe._nametowidget(parentname)

        #childname = catchildframe.winfo_parent()
        #child = catchildframe._nametowidget(childname)
        child = add_file.master

        print("Catmainframe parent:"+parentname)
        #print("Catchildframe parent:"+child)
        global fname
        global mindatetime
        global maxdatetime
        file_path=fd.askopenfilename()
        #print(file_path)

        file_name = os.path.basename(file_path)
        print(file_name)

        file_list = []

        file_list.append(file_name)

        df = pd.read_csv(file_path)
        names = list(df.columns[0:])
        indexcol = names[0]
        #print(indexcol)
        df = df.rename(columns = {indexcol:'datetime'})
        names = list(df.columns[1:])
        #print(names)
        df.datetime = pd.to_datetime(df.datetime)
        df.set_index('datetime',inplace=True)

        if mindatetime == pd.to_datetime('1900-01-01 00:00:00'):
            mindatetime = df.index.min()
        elif mindatetime > df.index.min():
            mindatetime = df.index.min()

        if maxdatetime == pd.to_datetime('1900-01-01 00:00:00'):
            maxdatetime = df.index.max()
        elif maxdatetime < df.index.max():
            maxdatetime = df.index.max()

        print(mindatetime)
        print(maxdatetime)    
        global unique_dates
        unique_dates = []
        unique_dates = df.index.map(pd.Timestamp.date).unique()

        for x in range(len(names)):    
            if(len(names)==1):
                l = tk.Checkbutton(box1, text=names[x], variable=names[x],state='disabled')
                l.select()
                l.pack(anchor = 'w')
            else:
                l = tk.Checkbutton(box1, text=names[x], variable=names[x])
                l.select()
                l.pack(anchor = 'w')

        figure = plt.Figure(figsize=(5,4), dpi=100)
        ax2 = figure.add_subplot(111)
        line = FigureCanvasTkAgg(figure, box2)
        line.get_tk_widget().grid(row=1,column=1,sticky='nsew')
        df.plot(kind='line', legend=False, ax=ax2, fontsize=10)
        ax2.set_title(cat)
        ax2.set_xlim(mindatetime,maxdatetime)

        for x in range(len(unique_dates)):
            d = tk.Checkbutton(box3, text=unique_dates[x], variable=unique_dates[x])
            d.select()
            d.pack(anchor = 'w')

    #Top frame
    top_frame = tk.Frame(root)
    top_frame.grid(row=0, column=0, sticky='nsew')

    category_name = tk.Label(top_frame, text='Category:')
    category_name.grid(row=0, column=0, sticky='nsew')

    entry_category = tk.Entry(top_frame, background="pink",textvariable = category)
    entry_category.grid(row=0, column=1, sticky='nsew')
    entry_category.focus()

    ok_button = tk.Button(top_frame, text="OK", command=enterCategory)
    ok_button.grid(row=0, column=2, sticky='nsew')

    xscrollbar = tk.Scrollbar(root, orient='horizontal')
    xscrollbar.grid(row=3, column=0, sticky='ew')

    yscrollbar = tk.Scrollbar(root)
    yscrollbar.grid(row=1, column=1, sticky='ns')

    canvas1 = tk.Canvas(root, bd=0,#scrollregion=(0, 0, 1000, 1000),
                    yscrollcommand=yscrollbar.set)
    canvas1.grid(row=1, column=0, sticky='nsew')

    # create the center widgets
    canvas1.grid_rowconfigure(1, weight=1)
    canvas1.grid_columnconfigure(0, weight=1)

    canvas2 = tk.Canvas(root, bd=0,#scrollregion=(0, 0, 1000, 1000),
                    xscrollcommand=xscrollbar.set)
    canvas2.grid(row=2, column=0, sticky='nsew')

    xscrollbar.config(command=canvas2.xview)
    yscrollbar.config(command=canvas1.yview)


    canvas1.config(scrollregion=canvas1.bbox("all"))

    canvas2.config(scrollregion=canvas2.bbox("all"))

    root.mainloop()

Python社区是高质量的Python/Django开发社区
本文地址:http://www.python88.com/topic/50714
 
2098 次点击  
文章 [ 1 ]  |  最新文章 5 年前
furas
Reply   •   1 楼
furas    5 年前

你已经知道了,但我把一切都放在一个地方


将小部件添加到 Canvas 你必须使用

 canvas.create_window(position, window=widget) 

而不是 grid() .

如果你不使用 create_window() 然后画布是空的,滚动条没有可滚动的内容。

catmainframe = tk.Frame(canvas1, borderwidth=2, relief="solid")
canvas1.create_window((0,0), window=catmainframe, anchor='nw') #, width=750)

你还得加上

root.bind('<Configure>', on_configure) 

运行更新滚动条信息的函数。

你可以直接在 root.mainloop()


我用来测试的代码-还有一些其他的清理:all函数在代码的开头,all global 在函数开始时。

import os
import tkinter as tk
from tkinter import filedialog as fd
import pandas as pd
import matplotlib.pyplot as plt
from matplotlib.backends.backend_tkagg import FigureCanvasTkAgg

# --- functions ---
# all functions at the beginning to make it more readable

def on_configure(event):
    # update scrollregion after starting 'mainloop'
    canvas1.configure(scrollregion=canvas1.bbox('all'))
    canvas2.configure(scrollregion=canvas2.bbox('all'))

def enterCategory():
    # all `global` at the beginning to make it more readable
    global cat
    global catmainframe
    global rownum
    global add_file
    global catchildframe
    global box1, box2, box3

    cat = category.get()

    catmainframe = tk.Frame(canvas1, borderwidth=2, relief="solid")
    canvas1.create_window((0,0), window=catmainframe, anchor='nw')#, width=750)

    catmainframe.grid_rowconfigure(0, weight=1)
    catmainframe.grid_columnconfigure(0, weight=1)     

    catframe = tk.Frame(catmainframe, borderwidth=2, relief="solid")
    catframe.grid(row=0,column=0, sticky='nsew', padx=1, pady=1)

    catlabel = tk.Label(catframe, text=cat)
    catlabel.grid(row=0, column=0, sticky='nsew')

    add_file = tk.Button(catframe, text="Add File", command=openFile)
    add_file.grid(row=0, column=1, sticky='nsew')

    catchildframe = tk.Frame(catmainframe, borderwidth=2, relief="solid")
    catchildframe.grid(row=1,column=0,sticky='nsew', padx=1, pady=1)
    catchildframe.grid_rowconfigure(1, weight=1)
    catchildframe.grid_columnconfigure(1, weight=1)  
    box1 = tk.Frame(catchildframe, borderwidth=2, relief="solid")
    box2 = tk.Frame(catchildframe, borderwidth=2, relief="solid")
    box3 = tk.Frame(catchildframe, borderwidth=2, relief="solid")
    box1.grid(row=1, column=0, sticky='nsew', padx=10, pady=10)
    box2.grid(row=1, column=1, sticky='nsew', padx=10, pady=10)
    box3.grid(row=1, column=2, sticky='nsew', padx=10, pady=10)
    box1.propagate(1)
    box2.propagate(1)
    box3.propagate(1)

    rownum += 1

def openFile():
    # all `global` at the beginning to make it more readable
    global fname
    global mindatetime
    global maxdatetime
    global unique_dates

    parentname = catmainframe.winfo_parent()
    parent = catmainframe._nametowidget(parentname)

    #childname = catchildframe.winfo_parent()
    #child = catchildframe._nametowidget(childname)
    child = add_file.master

    print("Catmainframe parent:", parentname)
    #print("Catchildframe parent:"+child)
    file_path = fd.askopenfilename()
    #print(file_path)

    file_name = os.path.basename(file_path)
    print(file_name)

    file_list = []

    file_list.append(file_name)

    df = pd.read_csv(file_path)
    names = list(df.columns[0:])
    indexcol = names[0]
    #print(indexcol)
    df = df.rename(columns = {indexcol:'datetime'})
    names = list(df.columns[1:])
    #print(names)
    df.datetime = pd.to_datetime(df.datetime)
    df.set_index('datetime', inplace=True)

    if mindatetime == pd.to_datetime('1900-01-01 00:00:00'):
        mindatetime = df.index.min()
    elif mindatetime > df.index.min():
        mindatetime = df.index.min()

    if maxdatetime == pd.to_datetime('1900-01-01 00:00:00'):
        maxdatetime = df.index.max()
    elif maxdatetime < df.index.max():
        maxdatetime = df.index.max()

    print(mindatetime)
    print(maxdatetime)    
    unique_dates = []
    unique_dates = df.index.map(pd.Timestamp.date).unique()

    for x in range(len(names)):    
        l = tk.Checkbutton(box1, text=names[x], variable=names[x])
        if len(names) == 1:
            l['state'] = 'disabled'
        l.select()
        l.pack(anchor='w')

    figure = plt.Figure(figsize=(5,4), dpi=100)
    ax2 = figure.add_subplot(111)
    line = FigureCanvasTkAgg(figure, box2)
    line.get_tk_widget().grid(row=1, column=1, sticky='nsew')
    df.plot(kind='line', legend=False, ax=ax2, fontsize=10)
    ax2.set_title(cat)
    ax2.set_xlim(mindatetime,maxdatetime)

    for x in range(len(unique_dates)):
        d = tk.Checkbutton(box3, text=unique_dates[x], variable=unique_dates[x])
        d.select()
        d.pack(anchor='w')

# --- main ---

# global is used only inside function to inform function 
# that you want to use external/global variable when you assign value
# and then it doesn't create local variable
#global rownum # not needed # all variables created outside functionsa  are glboal

root = tk.Tk()
root.geometry('{}x{}'.format(800, 600))

# layout all of the main containers
root.grid_rowconfigure(1, weight=1)
root.grid_columnconfigure(0, weight=1)

#Global variables
category = tk.StringVar()
rownum = 0
mindatetime = pd.to_datetime('1900-01-01 00:00:00')
maxdatetime = pd.to_datetime('1900-01-01 00:00:00')

#Top frame
top_frame = tk.Frame(root)
top_frame.grid(row=0, column=0, sticky='nsew')

category_name = tk.Label(top_frame, text='Category:')
category_name.grid(row=0, column=0, sticky='nsew')

entry_category = tk.Entry(top_frame, background="pink",textvariable = category)
entry_category.grid(row=0, column=1, sticky='nsew')
entry_category.focus()

ok_button = tk.Button(top_frame, text="OK", command=enterCategory)
ok_button.grid(row=0, column=2, sticky='nsew')

xscrollbar = tk.Scrollbar(root, orient='horizontal')
xscrollbar.grid(row=3, column=0, sticky='ew')

yscrollbar = tk.Scrollbar(root)
yscrollbar.grid(row=1, column=1, sticky='ns')

canvas1 = tk.Canvas(root, bd=0,#scrollregion=(0, 0, 1000, 1000),
                yscrollcommand=yscrollbar.set)
canvas1.grid(row=1, column=0, sticky='nsew')

# create the center widgets
canvas1.grid_rowconfigure(1, weight=1)
canvas1.grid_columnconfigure(0, weight=1)

canvas2 = tk.Canvas(root, bd=0,#scrollregion=(0, 0, 1000, 1000),
                xscrollcommand=xscrollbar.set)
canvas2.grid(row=2, column=0, sticky='nsew')

xscrollbar.config(command=canvas2.xview)
yscrollbar.config(command=canvas1.yview)

root.bind('<Configure>', on_configure)

root.mainloop()