首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >如何使用小部件在Sqlite3表中获得一行?

如何使用小部件在Sqlite3表中获得一行?
EN

Stack Overflow用户
提问于 2020-12-09 21:10:24
回答 2查看 965关注 0票数 0

我让Python程序连接到Sqlite3数据库,前面是Tkinter。我的数据库表( subject列表)由四列组成: id (唯一插槽)、主题(文本)、串行(唯一插槽)、is_active (布尔插槽)。这是我的节目:

代码语言:javascript
运行
复制
import sqlite3
from tkinter import *

conn = sqlite3.connect('database.db')
c = conn.cursor()
c.execute('SELECT COUNT() FROM subjectlist WHERE is_active = 1')
number = c.fetchone()[0]

c.execute('SELECT * FROM subjectlist WHERE is_active = 1 ORDER BY serial')
data = c.fetchall()

c.close
conn.close()


root = Tk()

listbox = Listbox(root)
listbox.pack()
for i in range(number):
    listbox.insert(END, data[i][1])

def get_serial():
    print(listbox.get(listbox.curselection()))

btn = Button(root, text="Show row", command=lambda: get_serial())
btn.pack()

mainloop()

目前,当我在运行时单击列表框上的item (它基本上显示了所有在同一行上都有is_active=1的主题列值),然后按Tkinter按钮,我就可以单击subject。相反,我想让我点击的整排。

关于这张桌子,有几件事要考虑:

  1. Subject列在两个或多个不同行上可能具有相同的值。如果行is_active值为0 (False),则按顺序排列列表框中的
  2. 项。如果is_active值为0(False),则不会在列表框上显示。列表框中将没有空行,下一个is_active=1 (真行)行将取代它。

考虑一下这个表(左)及其在GUI上的表示(右):

我希望GUI首先向所有is_active=1展示列表框中的主题。然后单击"Dogs“(列表框显示的第三项),然后单击按钮,让程序打印整行(id=1、subject=Dogs、serial=5、is_active=1)。

我怎样才能做到这一点呢?

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2020-12-09 23:25:48

使用Listbox并提取整个行值的唯一方法是将插入到列表框中的值保留在字典中的引用中,同时保持正常增加的数量。字典的形式是{idx:[id,subject]},实际上你不需要在列表中包含主题,你也可以用id来完成它,但是它可以让你更容易理解主题的选择。

看一看:

代码语言:javascript
运行
复制
from tkinter import *
import sqlite3

conn = sqlite3.connect('database.db')
c = conn.cursor() 
c.execute('SELECT * FROM subjectlist ORDER BY serial')
data = c.fetchall()
conn.close()

root = Tk()

dictio = {} # Empty dictionary to keep reference of appended values

listbox = Listbox(root)
listbox.pack()

a = 0 # A normally increasing number as the key of the dict
tot_rows = len(data) # Total number of rows
for i in range(tot_rows):
    if data[i][3]: # If is_active == 1
        dictio[a] = [data[i][0],data[i][1]] # Append the subject as the a-th item to dict, along with its id number
        listbox.insert(END, data[i][1]) # Inseert the data #add the subject to listbox
        a += 1 # Increase the number by 1

def get_serial():
    conn = sqlite3.connect('database.db')
    c = conn.cursor()
    val = listbox.curselection()[0] # Index of our current selection
    sel = dictio[val] # Get value from the dictionary based on the indexed number
    ids = sel[0] # Index the first item of the list
        
    c.execute('SELECT * FROM subjectlist WHERE `id`=?',(ids,)) # Search the database based on id of item
    print(c.fetchall()) # Print the item out as a tuple
    conn.close() # Close the connection

btn = Button(root, text="Show row", command=get_serial)
btn.pack()

listbox.bind('<Double-Button-1>',lambda e=None:get_serial()) # Bonus :p

mainloop()

我已经对代码做了很多扩展,以使它更容易理解,我希望这也是您所说的问题的意思。我已经对代码进行了评论,以使它在执行过程中也可以理解。

输出:

代码语言:javascript
运行
复制
(1,'Dogs', 5, 1) #(Id, subject, serial, is_active) 

虽然如果要使用ttk.Treeview,实际上可以创建两列,一列带有id,另一列带有主题,因此从其中提取数据要容易得多,而不是使用列表框将信息保存在字典中,然后使用它搜索数据库。

票数 1
EN

Stack Overflow用户

发布于 2020-12-10 04:34:06

您可以使用row_factory of sqlite3创建字典游标并获得类似的输出:

代码语言:javascript
运行
复制
import sqlite3
from tkinter import *

def dict_factory(cursor, row):
    return {col[0]:row[idx] for idx, col in enumerate(cursor.description)}

conn = sqlite3.connect('database.db')
conn.row_factory = dict_factory
c = conn.cursor()

c.execute('SELECT * FROM subjectlist WHERE is_active = 1 ORDER BY serial')
data = c.fetchall()

c.close
conn.close()


root = Tk()

listbox = Listbox(root)
listbox.pack()

for rec in data:
    listbox.insert(END, rec["subject"])

def get_serial():
    selected = listbox.curselection()
    if selected:
        print(data[selected[0]])
    else:
        print("No item selected")

btn = Button(root, text="Show row", command=get_serial)
btn.pack()

mainloop()

以及产出:

代码语言:javascript
运行
复制
{'id': 1, 'subject': 'Dogs', 'serial': 5, 'is_active': 1}
票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/65224957

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档