尝试从matplotlib放置工具栏时使用.grid(row =#,column =#)时出错

时间:2017-03-24 01:48:50

标签: python matplotlib tkinter

这是我下面的代码,由于某种原因,在放置matplotlib图的导航工具栏时我无法使用.grid()。我一直收到这个错误:

next_record()
Exception in Tkinter callback
Traceback (most recent call last):
  File "C:\Users\nasto\AppData\Local\Programs\Python\Python36-32\lib\tkinter\__init__.py", line 1699, in __call__
    return self.func(*args)
  File "C:\Users\nasto\Documents\Company\CMS.py", line 63, in <lambda>
    self.master.bind('<Control-n>', lambda event: self.no_credentials())
  File "C:\Users\nasto\Documents\Company\CMS.py", line 94, in no_credentials
    self.master.change(main_frame)
  File "C:\Users\nasto\Documents\Company\CMS.py", line 32, in change
    self.frame = frame()
  File "C:\Users\nasto\Documents\Company\CMS.py", line 160, in __init__
    toolbar = NavigationToolbar2TkAgg(canvas, self)
  File "C:\Users\nasto\AppData\Local\Programs\Python\Python36-32\lib\site-packages\matplotlib\backends\backend_tkagg.py", line 711, in __init__
    NavigationToolbar2.__init__(self, canvas)
  File "C:\Users\nasto\AppData\Local\Programs\Python\Python36-32\lib\site-packages\matplotlib\backend_bases.py", line 2752, in __init__
    self._init_toolbar()
  File "C:\Users\nasto\AppData\Local\Programs\Python\Python36-32\lib\site-packages\matplotlib\backends\backend_tkagg.py", line 772, in _init_toolbar
    self.pack(side=Tk.BOTTOM, fill=Tk.X)
  File "C:\Users\nasto\AppData\Local\Programs\Python\Python36-32\lib\tkinter\__init__.py", line 2137, in pack_configure
    + self._options(cnf, kw))
_tkinter.TclError: cannot use geometry manager pack inside .!main_frame which already has slaves managed by grid

我已经找到了问题,它似乎发生在以下代码行中:

    #importing tkinter libraries
    import tkinter as tk
    from tkinter.ttk import Combobox,Treeview,Scrollbar
    from tkinter import font

    #importing matplotlib libraries
    import matplotlib.pyplot as plt
    from matplotlib.backends.backend_tkagg import FigureCanvasTkAgg, NavigationToolbar2TkAgg
    from matplotlib.figure import Figure
    import matplotlib.animation as animation
    from matplotlib import style

    #Other libraries
    import hashlib
    import sqlite3
    import os

    #sets the style for the graph
    style.use('ggplot')

    Fig = Figure(figsize=(12,4), dpi=100)
    a = Fig.add_subplot(111)

    class start(tk.Tk):
      def __init__(self):
        tk.Tk.__init__(self)
        self.frame = login_window()
        self.frame.grid()

      def change(self, frame):
        self.frame.grid_forget()
        self.frame = frame()
        self.frame.grid()

    class login_window(tk.Frame):
      def __init__(self, master=None, **kwargs):
        tk.Frame.__init__(self, master, **kwargs)

        #Sets the width and height of the screen
        width = 600
        height = 600
        screenWidth = self.winfo_screenwidth()
        screenHeight = self.winfo_screenheight()
        x = (screenWidth/2) - (width/2)
        y = (screenHeight/2) - (height/2)
        self.master.geometry('%dx%d+%d+%d' % (width, height, x, y))
        self.master.resizable(width=False, height=False)
        self.master.title('Login')

        #On screen widgets
        self.__userID = tk.StringVar()
        self.__password = tk.StringVar()
        self.__error = tk.StringVar()
        userIDLabel = tk.Label(self, text = 'User ID: ').grid(row=1,column=0)
        passwordLabel = tk.Label(self, text='Password: ').grid(row=2,column=0)
        errorLabel = tk.Label(self, textvariable=self.__error).grid(row=0,column=0)
        userIDEntry = tk.Entry(self, textvariable=self.__userID).grid(row=1,column=1)
        passwordEntry = tk.Entry(self, textvariable=self.__password).grid(row=2,column=1)
        loginButton = tk.Button(self, text='Login', command = self.check_credentials).grid(row=3,column=0)
        clearButton = tk.Button(self, text='Clear', command = self.clear).grid(row=3,column=1)
        exitButtom = tk.Button(self, text='Exit', command = self.exit).grid(row=3,column=2)
        self.master.bind('<Return>', lambda event: self.check_credentials())
        self.master.bind('<Control-n>', lambda event: self.no_credentials())

      def check_credentials(self, event=None):
        userID = self.__userID.get()
        password = self.__password.get()
        hashPassword = (password.encode('utf-8'))
        newPassword = hashlib.sha256()
        newPassword.update(hashPassword)
        if userID == '' and password == '':
          self.__error.set('Error! No credentials entered')
        elif userID == '' :
          self.__error.set('Error! No userID entered')
        elif password == '':
          self.__error.set('Error! No password entered')
        else:
          with sqlite3.connect ('pkdata.db') as db:
            cursor = db.cursor()
            cursor.execute('select userID, password from users where userID=?',(userID))
            info = cursor.fetchone()
            if info is None:
              self.__error.set('Error! Credentials not found')
            else:
              dbUserID = info[0]
              dbPassword = info[1]
              if userID == dbUserID or newPassword.hexdigest() == dbPassword:
                self.master.change(main_frame)
              else:
                self.__error.set('Error! please enter credentials again')
                self.clear()

      def no_credentials(self):
        self.master.change(main_frame)

      def clear(self):
        self.__userID.set('')
        self.__password.set('')

      def exit(self):
        pass

    class main_frame(tk.Frame):
      def __init__(self, master=None, **kwargs):
        tk.Frame.__init__(self, master, **kwargs)
        self.master.state('zoomed')
        self.master.resizable(width=False, height=False)
        self.master.title('Pyraknight')

        #Sets up te menus
        menu = tk.Menu(self.master)
        self.master.config(menu=menu)

        fileMenu = tk.Menu(menu)
    ##    fileMenu.add_command(label='Save', command=None)
    ##    fileMenu.add_command(label='Exit', command=None)
        menu.add_cascade(label='File', menu = fileMenu)

        editMenu = tk.Menu(menu)
    ##    editMenu.add_command(label='Undo', command=None)
    ##    editMenu.add_command(label='Redo', command=None)
        menu.add_cascade(label='Edit', menu = editMenu)

        quickAccessMenu = tk.Menu(menu)
        menu.add_cascade(label='Access', menu = quickAccessMenu)

        helpMenu = tk.Menu(menu)
        menu.add_cascade(label='Help', menu = helpMenu)

        #Treeview for finances. ingoing and outgoing finances are displayed in the treeview
        self.financeTree = Treeview(self.master, height=25)
        self.financeTree['columns']=('transactionNumber','transactionAmount','productID','taxPaid','dateOfTransaction','timeOfTransaction','transactionApproved')
        self.financeTree.column('transactionNumber', width=125)
        self.financeTree.column('transactionAmount', width=125)
        self.financeTree.column('productID', width=75)
        self.financeTree.column('taxPaid', width=75)
        self.financeTree.column('dateOfTransaction', width=125)
        self.financeTree.column('timeOfTransaction', width=125)
        self.financeTree.column('transactionApproved', width=125)

        self.financeTree.heading('transactionNumber',text='Transaction Number')
        self.financeTree.heading('transactionAmount',text='Transaction Amount')
        self.financeTree.heading('productID',text='Product ID')
        self.financeTree.heading('taxPaid',text='Tax Paid')
        self.financeTree.heading('dateOfTransaction',text='Date Of Transaction')
        self.financeTree.heading('timeOfTransaction',text='Time Of Transaction')
        self.financeTree.heading('transactionApproved',text='Transaction Approved')
        self.financeTree['show'] = 'headings'

        yscrollbar = Scrollbar(self.master, orient='vertical', command=self.financeTree.yview)
        xscrollbar = Scrollbar(self.master, orient='horizontal', command=self.financeTree.xview)

        self.financeTree.configure(yscroll=yscrollbar.set, xscroll=xscrollbar.set)
        self.financeTree.grid(row=0,column=0)

        #Places the graph on the main screen & updates the graph when the file updates
        canvas = FigureCanvasTkAgg(Fig, self)
        canvas.show()
        canvas.get_tk_widget().grid(row=1,column=0)
    ''' toolbar = NavigationToolbar2TkAgg(canvas, self)
        toolbar.update()
        canvas._tkcanvas.grid(row=1,column=0)
       '''

        self.ani = animation.FuncAnimation (Fig, self.animate_graph, interval=1000)

      # Retrieves data from a txt file to be displayed on the main screen
      def animate_graph(self, i):
        pullData = open('financeData.txt','r').read()
        dataList = pullData.split('\n')
        xAxisList = []
        yAxisList = []
        for eachLine in dataList:
          if len(eachLine) > 1:
            x, y = eachLine.split(',')
            xAxisList.append(int(x))
            yAxisList.append(int(y))
        a.clear()
        a.plot(xAxisList, yAxisList)
        a.title.set_text('Pyraknight Finances')

      def workout_taxes(self):
        pass


    app = start()
    app.mainloop()

任何帮助将非常感谢,提前感谢。 〜纳斯

0 个答案:

没有答案