简体   繁体   English

我该如何解决这个错误? self.category_id.set(row[1]), IndexError: 字符串索引超出范围

[英]How do I fix this error? self.category_id.set(row[1]), IndexError: string index out of range

I'm adding data into sqlite table and when I try to update the table, I'm getting this error 'string index not in range'.我正在将数据添加到 sqlite 表中,当我尝试更新该表时,我收到此错误“字符串索引不在范围内”。

Again when I execute the update command, all the columns gets updated except the identity column but my intention is only to update a selected row.再次执行更新命令时,除标识列外,所有列都会更新,但我的目的只是更新选定的行。

what I not doing right from the code below>我从下面的代码中没有做的事情>

Your assistance will be highly appreciated.非常感谢您的协助。

The error is happening in the function update_record(self) .错误发生在 function update_record(self)中。

This is my code:这是我的代码:

import tkinter
from tkinter import *
from tkinter import ttk
import tkinter.messagebox
import sqlite3

root =Tk()
root.title('Accounting App')
root.config(bg='#3d6466')
root.geometry("520x400")
root.resizable(False, False)

style = ttk.Style()
style.theme_use('alt')
style.configure("TCombobox", fieldbackground="Grey", background="Grey")

class Backend():
    def __init__(self):
        self.conn = sqlite3.connect('accounting.db')
        self.cur = self.conn.cursor()

        #self.conn.execute("""DROP TABLE IF EXISTS account_type""")

        self.conn.execute("""CREATE TABLE IF NOT EXISTS account_type(
         id             INTEGER     PRIMARY KEY,
         category_id    INTEGER         NOT NULL,
         category_type  TEXT        NOT NULL
         )"""),

        self.conn.commit()
        # elf.conn.close()

    # =========Account Type======
    class Account_type():

        def insert_account_type(self, category_id, category_type):
            self.conn = sqlite3.connect('accounting.db')
            self.cur = self.conn.cursor()
            self.cur.execute("""INSERT INTO  account_type(category_id,category_type) VALUES(?,?);""",
                             (category_id, category_type,))
            self.conn.commit()
            self.conn.close()

        def view_account_type(self):
            self.conn = sqlite3.connect('accounting.db')
            self.cur = self.conn.cursor()
            self.cur.execute("SELECT * FROM account_type")
            rows = self.cur.fetchall()
            self.conn.close()
            return rows

acc_type = Backend.Account_type()
tb = Backend()

class Front_end():
    def __init__(self, master):
        # Frames

        global cur
        global conn
        conn = sqlite3.connect('accounting.db')
        cur = conn.cursor()
        # Frames
        self.left_frame = LabelFrame(master,bg='#3d6466', relief=SUNKEN,width=200)
        self.left_frame.pack(fill = 'both',expand = YES , padx = 5,side=LEFT,anchor=NW)
        self.right_frame = LabelFrame(master, bg='#3d6466', relief=SUNKEN)
        self.right_frame.pack(fill = 'both',expand = YES ,side=LEFT,anchor=NW)

        self.top_right_frame = LabelFrame(self.right_frame, bg='#3d6466', relief=SUNKEN,text='Details',fg='maroon')
        self.top_right_frame.pack(fill=BOTH,side=TOP, anchor=NW,expand=YES)

        self.top_r_inner_frame = LabelFrame(self.right_frame, bg='#3d6466', relief=SUNKEN, text='...', fg='maroon',height=10)
        self.top_r_inner_frame.pack(fill=BOTH, side=TOP, anchor=SW, expand=YES)

        self.bottom_right_frame = LabelFrame(self.right_frame, bg='#3d6466', relief=SUNKEN, text='Field View', fg='maroon')
        self.bottom_right_frame.pack(fill=BOTH,side=TOP, anchor=SW, expand=YES)

        self.my_canvas = Canvas(self.top_right_frame,bg='#3d6466')
        self.my_canvas.pack(side=LEFT,fill='both', expand=YES)

        # vertical configuration of scrollbar
        self.yscrollbar = ttk.Scrollbar(self.top_right_frame, orient=VERTICAL, command = self.my_canvas.yview)
        self.yscrollbar.pack(side=RIGHT,fill='both')

        self.my_canvas.config(yscrollcommand = self.yscrollbar.set)

        self.top_right_frame = Frame(self.my_canvas, bg='#3d6466', relief=SUNKEN)
        self.my_canvas.create_window((0,0),window=self.top_right_frame, anchor=NW)
        self.my_canvas.bind('<Configure>',lambda e:self.my_canvas.configure(scrollregion = self.my_canvas.bbox('all')))


        self.side_frame = LabelFrame(self.left_frame,bg='#3d6466',relief=SUNKEN,text='Menu Buttons',fg='maroon',)
        self.side_frame.pack(side=TOP,anchor=NW,expand=YES )

        # Side Buttons
        self.btn1 = Button(self.side_frame, text='Main Account Types', bg='#3d6466', font=('cambria', 12), anchor=W,
                           fg='white', width=18,height=2,command=self.main_account)
        self.btn1.grid(row=0, column=0, sticky=W)

    def main_account(self):

        # variables
        self.category_id = StringVar()
        self.category_type = StringVar()

        self.category_search =StringVar()

        # functions
        def add_main_accounts(self):
            if self.category_id.get() == "":
                tkinter.messagebox.showinfo('All fields are required')
            else:
                Backend.Account_type.insert_account_type(self,
                    self.category_id.get(),self.category_type.get())

                tkinter.messagebox.showinfo('Entry successful')

        def display_account_types(self):
            self.trv.delete(*self.trv.get_children())
            for rows in Backend.Account_type.view_account_type(self):
                self.trv.insert("", END, values=rows)

        def get_account_type(e):
            selected_row = self.trv.focus()
            data = self.trv.item(selected_row)
            row = data["values"]

            """Grab items and send them to entry fields"""
            self.category_id.set(row[1])
            self.category_type.set(row[2])

        def clear(self):
            self.category_id.set("")
            self.category_type.set("")

        **def update_record(self):
            selected = self.trv.focus()
            self.trv.item(selected, values=(
                self.category_id.get(), self.category_type.get()))
            conn = sqlite3.connect("accounting.db")
            cur = conn.cursor()
            if self.category_id.get() == "" or self.category_type.get() == "" :
                tkinter.messagebox.showinfo('All fields are required!')
                return
            update_record = tkinter.messagebox.askyesno('Confirm please',
                                                        'Do you want to update records?')
            if update_record > 0:
                cur.execute(
                    "UPDATE account_type SET category_id=:cat_id, category_type=:type",
                     {'cat_id': self.category_id.get(), 'type': self.category_type.get()})
                tkinter.messagebox.showinfo('Record update successful!')
            conn.commit()**

            # call the function for Clearing the fields
            clear(self)
            conn.close()

        """=================TreeView==============="""
        # Scrollbars
        ttk.Style().configure("Treeview", background = "#3d6466", foreground = "white", fieldbackground = "grey")

        scroll_x = Scrollbar(self.bottom_right_frame, orient = HORIZONTAL)
        scroll_x.pack(side = BOTTOM, fill = X)
        scroll_y = Scrollbar(self.bottom_right_frame, orient = VERTICAL)
        scroll_y.pack(side = RIGHT, fill = Y)

        # Treeview columns & setting scrollbars
        self.trv = ttk.Treeview(self.bottom_right_frame, height=5, columns=
        ('id','category_id', 'category_type'), xscrollcommand = scroll_x.set, yscrollcommand = scroll_y.set)

        # Treeview style configuration
        ttk.Style().configure("Treeview", background = "#3d6466", foreground = "white", fieldbackground = "#3d6466")

        # Configure vertical and Horizontal scroll
        scroll_x.config(command = self.trv.xview)
        scroll_y.config(command = self.trv.yview)

        # Treeview Headings/columns
        self.trv.heading('id', text = 'NO')
        self.trv.heading('category_id', text = 'Category ID')
        self.trv.heading('category_type', text = 'Category Type')

        self.trv['show'] = 'headings'

        # Treeview columns width
        self.trv.column('id', width = 50)
        self.trv.column('category_id', width = 70)
        self.trv.column('category_type', width = 90)

        self.trv.pack(fill = BOTH, expand = YES,anchor = NW)

        # Binding Treeview with data
        self.trv.bind('<<TreeviewSelect>>',get_account_type) # trv.bind('<Double-1>',"")

        # Account Types Labels
        self.lbl1 = Label(self.top_right_frame,text = 'Category ID',anchor = W,width=12,font = ('cambria',13,),bg = '#3d6466')
        self.lbl1.grid(row = 0,column = 0,pady = 5)

        self.lbl1 = Label(self.top_right_frame, text='Category Type', anchor=W, width=12, font=('cambria', 13,),  bg='#3d6466')
        self.lbl1.grid(row=1, column=0, pady=5)

        self.lbl2 = Label(self.top_right_frame, text='Search Account', anchor=W, width=12, font=('cambria', 13,),
                          bg='#3d6466')
        self.lbl2.grid(row=6, column=0, pady=5)

        # Account Type Entries
        self.entry1 = Entry(self.top_right_frame,textvariable = self.category_id,font = ('cambria',13,),bg = 'Grey',width=14)
        self.entry1.grid(row = 0,column=1,sticky = W,padx = 4,columnspan=2)
        self.entry1 = Entry(self.top_right_frame, textvariable=self.category_type, font=('cambria', 13,), bg='Grey', width=14)
        self.entry1.grid(row=1, column=1, sticky=W, padx=4, columnspan=2)
        self.entry2 = Entry(self.top_right_frame, textvariable=self.category_search, font=('cambria', 13,), bg='Grey', width=14)
        self.entry2.grid(row=6, column=1, sticky=W, padx=4, columnspan=2)

        # Buttons
        self.btn_1 = Button(self.top_right_frame,text='Add',font=('cambria',12,'bold'),bg='#3d6466',
                            activebackground='green', fg = 'white',width=12,height = 1,relief=RAISED,
                            command = lambda :[add_main_accounts(self),display_account_types(self),clear(self)])
        self.btn_1.grid(row = 3,column = 0,pady=6, padx=6)
        self.btn_2 = Button(self.top_right_frame, text = 'View',command=lambda :[display_account_types(self),clear(self)],
                            font=('cambria', 12, 'bold'), bg = '#3d6466', activebackground='green',
                           fg ='white', width=12, height = 1, relief=RAISED)
        self.btn_2.grid(row = 3, column=1,padx=0)
        self.btn_3 = Button(self.top_right_frame, text = 'Update', command= lambda :[update_record(self),
                                display_account_types(self)],font=('cambria', 12, 'bold'), bg = '#3d6466',
                           activebackground = 'green', fg='white', width = 12, height = 1, relief=RAISED)
        self.btn_3.grid(row = 4, column = 0,pady=6,padx=10)

# calling the class

app = Front_end(root)


root.mainloop() 

Your update function updates all the records exist.您的更新 function 更新了所有存在的记录。 To avoid this you should use WHERE.为避免这种情况,您应该使用 WHERE。 Here its fixed version这是它的固定版本

def update_record(self):
    selected = self.trv.focus()
    
    oldValues = self.trv.item(selected)["values"]

    self.trv.item(selected, values=(oldValues[0],
        self.category_id.get(), self.category_type.get()))
    conn = sqlite3.connect("accounting.db")
    cur = conn.cursor()
    if self.category_id.get() == "" or self.category_type.get() == "" :
        tkinter.messagebox.showinfo('All fields are required!')
        return
    update_record = tkinter.messagebox.askyesno('Confirm please',
                                                'Do you want to update employee records?')
    if update_record > 0:
        cur.execute(
            "UPDATE account_type SET category_id=:cat_id, category_type=:type WHERE id=:id_value",
             {'cat_id': self.category_id.get(), 'type': self.category_type.get(), "id_value": oldValues[0]})
        tkinter.messagebox.showinfo('Record update successful!')
    conn.commit()

    # call the function for Clearing the fields
    clear(self)
    conn.close()

We used selected rows idx etc. However your error string index out of range is not about this.我们使用了选定的行 idx 等。但是您的错误字符串索引超出范围与此无关。 The function above going to fix your record update problem.上面的 function 将解决您的记录更新问题。 Your error is because it tries to show a record value but after refreshed table, nothing is selected.您的错误是因为它试图显示记录值,但在刷新表格后,没有选择任何内容。 So it returns empty.所以它返回空。

def get_account_type(e):
    selected_row = self.trv.focus()
    data = self.trv.item(selected_row)
    row = data["values"]
    if(row == ""):
        return
    """Grab items and send them to entry fields"""
    self.category_id.set(row[1])
    self.category_type.set(row[2])

Now if row is just an empty string, function stops executing and you get no errors.现在,如果 row 只是一个空字符串,则 function 将停止执行并且不会出现任何错误。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 如何修复IndexError:Python中的字符串索引超出范围 - How do I fix IndexError: string index out of range in python 如何修复此错误 IndexError: string index out of range - How I can fix this error IndexError: string index out of range 如何修复Python中的“ IndexError:字符串索引超出范围”错误 - How to fix “IndexError: string index out of range” error in python 如何解决此错误:IndexError:列表索引超出范围 - How can I fix this error: IndexError: list index out of range IndexError:列表索引超出范围错误,如何修复代码? - IndexError: list index out of range error, How do I fix the code? 我收到错误提示 IndexError: list index out of range。 我该如何解决? - I got error saying IndexError: list index out of range. how do I fix this? 如何解决错误“IndexError:列表索引超出范围” - How do I solve the error, "IndexError: list index out of range" 如何处理错误“ IndexError:字符串索引超出范围” - How can I handle the error “IndexError: string index out of range” Contraction.fix 导致错误“IndexError:字符串索引超出范围” - Contraction.fix resulted an error "IndexError: string index out of range" IndexError: string index out of range - 当索引不在调用列表范围之外时,我如何得到这个错误? - IndexError: string index out of range - How do I get this error when the index does not go outside the range of called list?
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM