#python #sqlite #for-loop #tkinter #listbox
#python #sqlite #для цикла #tkinter #поле со списком
Вопрос:
У меня есть программа Python, подключенная к базе данных SQLite 3 с помощью Tkinter во внешнем интерфейсе. Моя таблица базы данных (subjectlist) состоит из трех столбцов: [id (уникальный interger), subject (текст), serial (уникальное целое число)]. Вот моя программа:
import sqlite3
from tkinter import *
conn = sqlite3.connect('database.db')
c = conn.cursor()
c.execute('SELECT COUNT() FROM subjectlist')
number = (c.fetchone()[0])
c.execute('SELECT * FROM subjectlist 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 serial", command=lambda: get_serial())
btn.pack()
mainloop()
В настоящее время во время выполнения, когда я нажимаю элемент в listbox (ведьма в основном показывает все значения столбца subject), а затем нажимаю кнопку Tkinter, я получаю тему, которую я нажал. Вместо этого я хочу получить serial, соответствующий теме. Обратите внимание, что столбец subject может иметь одинаковое значение в двух или более разных строках. Как мне добиться этого?
Вот еще один пример; Если у меня есть эта таблица:
Я хочу, чтобы графический интерфейс сначала отображал все объекты в списке. Затем я нажимаю «Кошки» (в строке идентификатора 3), а затем нажимаю кнопку, я хочу, чтобы программа напечатала мне серийный номер 4.
Комментарии:
1. Используется ли эта же таблица и с listbox?
2. Нет. Listbox показывает только собак, кошек, кошек, птиц друг под другом. Таким образом, идентификатор и серийный номер не будут видны конечному пользователю.
3. Был бы признателен, если бы взглянул на ответы, приведенные ниже: D
4. Извините, что отнял время. Был ночной сон, работа на целый день, дополнительные встречи по вечерам и тодлеры, висящие на моей ноге в середине. Я видел ваш ответ примерно 12 часов назад, но не смог его прокомментировать, так как тогда я тоже не мог его протестировать.
Ответ №1:
Ну, это тоже должно быть легко. Но поскольку в вашем коде есть база данных, которую я в настоящее время не могу протестировать с ее помощью, я сделал некоторые предположения. Попробуйте это:
def get_letter():
conn = sqlite3.connect('database.db')
c = conn.cursor()
ids = listbox.curselection()[0] 1 # Getting the index number starting from 1
c.execute('SELECT * FROM subjectlist WHERE `id`=?;',(ids,)) # Searching the database for items with selected items index
rows = c.fetchall()
print(rows[0]) # Print the first and hopefully the only item in the list
conn.close() # Close the connection
При этом должны быть напечатаны строки, соответствующие идентификатору, а поскольку обычно id является уникальным номером, будет распечатана только одна строка. Я также предполагаю, что у вас есть и база данных, и список в том же порядке, иначе это может не сработать.
Комментарии:
1. Это дало мне всю строку, а не только serial. Я все еще могу извлечь этот serial из этой строки просто отлично, так что никаких проблем нет. Поэтому я должен принять ваш ответ. Спасибо. Однако я снова сыграл себя, написав вопрос. Я забыл упомянуть, что таблица упорядочена по serial, а не по id. Тогда я мог бы просто заменить id из select stament на serial, и это сработало бы, так что проблем тоже нет. Однако все же у меня может отсутствовать serial в таблице, если, например, я удаляю строку Dogs. Тогда я думаю, что это сломается. Однако вы дали правильный ответ на представленный вопрос.
Ответ №2:
Вы можете использовать индекс элемента внутри listbox
, чтобы получить serial
from data
:
import sqlite3
from tkinter import *
conn = sqlite3.connect('database.db')
c = conn.cursor()
c.execute('SELECT * FROM subjectlist 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[1])
def get_serial():
selected = listbox.curselection()
if selected:
idx = selected[0]
print(data[idx][2]) # print serial of selected item
btn = Button(root, text="Show serial", command=get_serial)
btn.pack()
mainloop()
Обратите внимание, что вы должны убедиться data
, listbox
что они синхронизированы.