Tkinter - Получить текст ввода по двойному щелчку (для цикла) - PullRequest
0 голосов
/ 26 января 2019

Я делаю программу, которая получает записи базы данных с помощью модуля PyMySQL, а затем я хочу отобразить эти записи в записях Tkinter. У меня уже есть код для этого, но я хочу добавить функциональность.

Я хочу дать пользователю функциональность для двойной щелчок на элементе Entry строки и получить весь текст Entry для этой строки и проанализировать их в текстовые поля, которые я объявил до цикла For (UserID, First_Name и т. Д. ). Скажем, у меня есть 5 записей в строке. Если пользователь дважды щелкнет на (например) записи № 2 строки 1, я хочу получить текст из всех записей строки 1 и проанализировать их в текстовых полях соответственно.

Это код, который у меня сейчас есть:

window = tk.Tk()
window.title("Flexbase") #Give window a name
window.update_idletasks()
width = 640
height = 480
x = (window.winfo_screenwidth() // 2) - (width // 2)
y = (window.winfo_screenheight() // 2) - (height // 2)
window.geometry('+{}+{}'.format(x, y))

GetRows_StringVariable = "SELECT * FROM SEC_USER"
cursor.execute(GetRows_StringVariable)
results = cursor.fetchall()

RowCounter = 1
ColumnCounter = -1
ListCounter = 0
RowListCounter = 0

rows = []

id_list = []
firstname_list = []
surname_list = []
username_list = []
email_list = []
password_list = []

tk.Label(window, text="Testing").grid(row=0, column=0, sticky=NSEW)
UserID_TextBox = tk.Entry(window, width=20, bg="white") #Create text box
UserID_TextBox.grid(row=1, column=0, sticky=W) #Give the text box a position in the window
FirstName_TextBox = tk.Entry(window, width=60, bg="white")
FirstName_TextBox.grid(row=2, column=0, sticky=W)
Surname_TextBox = tk.Entry(window, width=60, bg="white")
Surname_TextBox.grid(row=3, column=0, sticky=W)
Email_TextBox = tk.Entry(window, width=60, bg="white")
Email_TextBox.grid(row=4, column=0, sticky=W)
Username_TextBox = tk.Entry(window, width=20, bg="white")
Username_TextBox.grid(row=5, column=0, sticky=W)
Password_TextBox = tk.Entry(window, show="*", width=20, bg="white")
Password_TextBox.grid(row=6, column=0, sticky=W)

notebook = ttk.Notebook(window)
notebook.grid(row=7, column=0, sticky=NSEW)

page1 = ttk.Frame(notebook)
notebook.add(page1, text="Mass Editing Mode")
tk.Label(page1, text=SQL_ID, fg="black", font="Arial 8 bold").grid(row=0, column=0, sticky=W)
tk.Label(page1, text=SQL_FIRSTNAME, fg="black", font="Arial 8 bold").grid(row=0, column=1, sticky=W)
tk.Label(page1, text=SQL_SURNAME, fg="black", font="Arial 8 bold").grid(row=0, column=2, sticky=W)
tk.Label(page1, text=SQL_USERNAME, fg="black", font="Arial 8 bold").grid(row=0, column=3, sticky=W)
tk.Label(page1, text=SQL_EMAIL, fg="black", font="Arial 8 bold").grid(row=0, column=4, sticky=W)


for row in results: # Page 1 TAB
    ColumnCounter += 1
    id_list.append(row[SQL_ID])
    a = tk.Entry(page1, fg="black", font="Arial 8 bold")
    a.grid(row=RowCounter, column=ColumnCounter, sticky=W)
    a.insert(0, row[SQL_ID])
    ColumnCounter += 1
    firstname_list.append(row[SQL_FIRSTNAME])
    b = tk.Entry(page1, fg="black", font="Arial 8 bold")
    b.grid(row=RowCounter,column=ColumnCounter,sticky=W)
    b.insert(0, row[SQL_FIRSTNAME])
    ColumnCounter += 1
    surname_list.append(row[SQL_SURNAME])
    c = tk.Entry(page1, fg="black", font="Arial 8 bold")
    c.grid(row=RowCounter,column=ColumnCounter,sticky=W)
    c.insert(0, row[SQL_SURNAME])
    ColumnCounter += 1
    username_list.append(row[SQL_USERNAME])
    d = tk.Entry(page1, fg="black", font="Arial 8 bold")
    d.grid(row=RowCounter, column=ColumnCounter, sticky=W)
    d.insert(0, row[SQL_USERNAME])
    ColumnCounter += 1
    email_list.append(row[SQL_EMAIL])
    e = tk.Entry(page1, fg="black", font="Arial 8 bold")
    e.grid(row=RowCounter, column=ColumnCounter, sticky=W)
    e.insert(0, row[SQL_EMAIL])

    RowCounter += 1
    ColumnCounter = -1
    ListCounter += 1
    RowListCounter += 1

Этот код создает окно с 5 записями на строку.

Ответы [ 2 ]

0 голосов
/ 26 января 2019

Как уже объяснил @Florian Weimer, вам нужно определить одну или несколько функций обратного вызова и прикрепить их / их к каждому Entry.

Кроме того, я думаю, что вы могли бы (и должны) исключить столько избыточного кода, который у вас есть, что сделает его намного меньше, а также проще для работы и улучшения. В разработке программного обеспечения это называется DRY , для принципа "не повторяйся", принцип.

Поскольку у меня нет вашей базы данных, мне пришлось добавить эту строку:

db_keys = results[0].keys()  # Get list of keys from the first result.

для получения необходимого списка ключей в каждой записи / строке. Возможно, у вас уже есть такой список в схеме базы данных или вы хотите создать его другим способом.

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


window = tk.Tk()
window.title("Flexbase") #Give window entry name
window.update_idletasks()
width = 640
height = 480
x = (window.winfo_screenwidth() // 2) - (width // 2)
y = (window.winfo_screenheight() // 2) - (height // 2)
window.geometry('+{}+{}'.format(x, y))

GetRows_StringVariable = "SELECT * FROM SEC_USER"
#cursor.execute(GetRows_StringVariable)
#results = cursor.fetchall()

db_keys = results[0].keys()  # Get list of keys from the first result.

tk.Label(window, text="Testing").grid(row=0, column=0, sticky=NSEW)

# Create textbox Entry widgets.
textbox_ids = list(db_keys) + ['Password']
textbox_widths = 20, 60, 60, 60, 20, 20
textbox_shows  = '', '', '', '', '', '*'
textboxes = {}
for i, (id, width, show) in enumerate(zip(textbox_ids, textbox_widths, textbox_shows), 1):
    textboxes[id] = tk.Entry(window, width=width, show=show, bg="white")
    textboxes[id].grid(row=i, column=0, sticky=W)

# Double-click callback function for items in result rows.
def double_click_cb(ev, row):
    # Replace current values in textboxes with those from the selected row.
    for key, value in row.items():
        textboxes[key].delete(0, END)
        textboxes[key].insert(0, value)

notebook = ttk.Notebook(window)
notebook.grid(row=7, column=0, sticky=NSEW)

page1 = ttk.Frame(notebook)
notebook.add(page1, text="Mass Editing Mode")
nb_font = "Arial 8 bold"

# Create header row.
for i, key in enumerate(db_keys):
    tk.Label(page1, text=key, fg="black", font=nb_font).grid(row=0, column=i, sticky=W)

# Display results.
id_list = []
RowCounter = 1
for row in results:
    for ColumnCounter, key in enumerate(db_keys):
        id_list.append(row[key])
        entry = tk.Entry(page1, fg="black", font=nb_font)
        entry.grid(row=RowCounter, column=ColumnCounter, sticky=W)
        entry.insert(0, row[key])
        entry.bind("<Double-Button>", lambda e, r=row: double_click_cb(e, r))
    RowCounter += 1

window.mainloop()
0 голосов
/ 26 января 2019

Вы можете добавить это после создания объектов tk.Entry:

    for obj in (a, b, c, d):
        def double_click(ev, RowCounter=RowCounter):
            print("selected row:", RowCounter)
        obj.bind("<Double-Button>", double_click)

(RowCounter=RowCounter необходимо для захвата текущего значения строки.)

С номером строки вы сможете получить то, что вам нужно, от объекта results.

...