删除 tkinter 列表框中的大括号

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

嗨,我正在尝试删除

tkinter listbox
中的大括号,但是我需要将其维护为元组,这样当我使用
curselection
时,我可以填充
entry
框。 这是我的代码:

import tkinter as tk
from tkinter import *
from tkinter import ttk
from tkinter.ttk import *

import sqlite3

def connect():
    conn=sqlite3.connect("Section_25_GUI_and_Postgres/books2.db")
    cur=conn.cursor()
    cur.execute("CREATE TABLE IF NOT EXISTS book (id INTEGER PRIMARY KEY, title text, author text, year integer, isbn integer)")
    conn.commit()
    conn.close()
    
def insert(title, author, year, isbn):
    conn=sqlite3.connect("Section_25_GUI_and_Postgres/books2.db")
    cur=conn.cursor()
    cur.execute("INSERT INTO book VALUES (NULL, ?, ?, ?, ?)", (title, author, year, isbn))
    conn.commit()
    conn.close()

def view():
    conn=sqlite3.connect("Section_25_GUI_and_Postgres/books2.db")
    cur=conn.cursor()
    cur.execute("SELECT * FROM book")
    rows=cur.fetchall()
    conn.close()
    return rows 

# connect()
# insert("My Book 2", "Kevin Medri", 2020, 269494945)

def get_selected_row(event):
    
    try:
        global selected_tuple
        index = li1.curselection()[0]
        selected_tuple = li1.get(index)
        print(selected_tuple)
        e1.delete(0, END)
        e1.insert(END, selected_tuple[1])
        e2.delete(0, END)
        e2.insert(END, selected_tuple[2])
        e3.delete(0, END)
        e3.insert(END, selected_tuple[3])
        e4.delete(0, END)
        e4.insert(END, selected_tuple[4])
    except IndexError:
        pass

def view_command():
    li1.delete(0, END)
    for row in view():
        li1.insert(END, row)
        
def close_command():
        window.destroy()

window = tk.Tk()

window.title('Book Case')
window.geometry('-50+50')
window.resizable(False, False)
window.attributes('-alpha',0.9)
window.configure(background='#d7e1ff')

# UI options
paddings = {'padx': 5, 'pady': 5}
entry_font = {'font': ('Arial', 10)}

# configure style globally for labels and buttons
window.style = Style(window)
window.style.configure('TLabel', anchor='e', background='#d7e1ff', font=('Arial', 10))
window.style.configure('TButton', anchor='w', background='#d7e1ff', font=('Arial', 10))

l1 = Label(window, text='Title', **entry_font)
l1.grid(row=0, column=0, **paddings)

l2 = Label(window, text='Author', **entry_font)
l2.grid(row=0, column=2, **paddings)

l3 = Label(window, text='Year', **entry_font)
l3.grid(row=1, column=0, **paddings)

l3 = Label(window, text='ISBN', **entry_font)
l3.grid(row=1, column=2, **paddings)

title_text = StringVar()
e1 = Entry(window, textvariable=title_text, **entry_font)
e1.grid(row=0, column=1, **paddings)

author_text = StringVar()
e2 = Entry(window, textvariable=author_text, **entry_font)
e2.grid(row=0, column=3, **paddings)

year_text = StringVar()
e3 = Entry(window, textvariable=year_text, **entry_font)
e3.grid(row=1, column=1, **paddings)

isbn_text = StringVar()
e4 = Entry(window, textvariable=isbn_text, **entry_font)
e4.grid(row=1, column=3, **paddings)


li1 = Listbox(window, height=13, width=35, **entry_font)
li1.grid(row=2, column=0, rowspan=6, columnspan=2, **paddings)

sb1 = ttk.Scrollbar(window, orient='vertical', command=li1.yview)
sb1.grid(row=2, column=2, rowspan=6, sticky=tk.NS, **paddings)

li1.configure(yscrollcommand=sb1.set)
sb1.configure(command=li1.yview)

li1.bind('<<ListboxSelect>>', get_selected_row)

b1 = ttk.Button(window, text='View All', command=view_command)
b1.grid(row=2, column=3, **paddings)

b6 = ttk.Button(window, text='Close', command=close_command)
b6.grid(row=7, column=3, **paddings)

window.mainloop()

这是我单击“查看全部”时代码的结果

On View All

当我单击列表框中的一项但列表框中没有大括号时,我需要填充输入框

On click

python-3.x sqlite tkinter
2个回答
4
投票

基本上

{}
出现的原因已经解释过了: 我在输出末尾得到了 { } 。这是什么原因造成的以及如何消除它?

现在,当您使用

' '.join(map(str, row)))
将其转换为字符串时,您会发现,这很好。但是当您尝试将其插入输入框中时,您将遇到问题,因为它不再是
tuple
,而是
str
,并且使用
e1.insert(END, selected_tuple[1])
不会按您期望的方式工作。

所以你需要一种方法将字符串转换回元组。所以你可以使用像

selected_tuple = selected_tuple.split(' ')
这样的东西。但在这里,你正与每一个空白空间分裂。并且每个项目之间以及同一项目内部也可以有空白,例如 My Book Two。因此,您可以做的是,创建两个版本,一个版本使用
' '
分割每个元素,另一个版本使用
'-'
分割每个元素,并在它们之间创建链接:
{ 'this is item one': 'this-is-item-one' }

那么你的视图函数将是这样的:

mapper = {} def view_command(): li1.delete(0, END) for row in view(): items_hyphen = '-'.join(map(str, row)) # Hyphened items_space = ' '.join(map(str, row)) # Spaced li1.insert(END, items_space) mapper[items_space] = items_hyphen # Add to dictionary

你的 get 函数将是这样的:

def get_selected_row(event): try: index = event.widget.curselection() selected_item_space = li1.get(index) # Get string from listbox selected_item_hyphen = mapper[selected_item_space] # Get corresponding hyphenated value from dictionary selected_list = selected_item_hyphen.split('-')[1:] # Slide to remove the ID ents = [e1, e2, e3, e4] for ent, value in zip(ents, selected_list): # Loop through `ents` and `selected_list` at the same time ent.delete(0, END) # Clear ent.insert(END, value) # Then insert except IndexError: pass

或者,您可以存储元组本身,而不是使用连字符值,如@acw1668所述:

def get_selected_row(event): try: ... selected_item_tuple = mapper[selected_item_space] # Get corresponding tuple from dictionary ... for ent,value in zip(ents, selected_item_tuple): ... except IndexError: pass def view_command(): li1.delete(0, END) for row in view(): items_space = ' '.join(map(str, row)) # Spaced li1.insert(END, items_space) mapper[items_space] = row # Add to dictionary



2
投票

列表框需要一个字符串而不是元组,因此它使用 tcl 的内部转换器将元组转换为字符串。对于元组中包含空格或其他一些特殊字符的值,tcl 将在元素周围放置大括号。

您应该在将元组传递给列表框

insert

方法之前将其显式转换为字符串,这样就不会发生这种情况。一种方法是通过用空格(或任何其他字符)连接列表元素来将每一行转换为列表

例如,以下示例通过将每列转换为字符串,然后用空格将各列连接在一起,将每行转换为字符串。

def view_command(): li1.delete(0, END) for row in view(): li1.insert(END, " ".join([str(column) for column in row]))

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