全部。我对编码还很陌生,直到 4 周前我才写过一段代码,我有 2 个问题。
首先,我一直在努力弄清楚如何从包含 3 个表的数据库中提取特定的数据。其次,我一直在尝试弄清楚如何在 GUI 中显示该数据。我读过的所有教程和观看的视频都展示了如何使用 GUI 从表中输入和删除值,但我还没有找到有关在 GUI 中检索和显示这些值的任何内容。我得到的最接近的是在终端中检索并显示所需的信息。
我正在使用 Python 3.12.0 和 CustomTkinter 为我的 MySQL 8.3 数据库制作 GUI。我的数据库是“HardwareDB”,包含表“doitbest”、“truevalue”和“reference”。这些表包含带有标题的列,例如 SKU、描述、价格、型号、PrimaryUPC 等。基本想法是我扫描 UPC 条形码或在 GUI 上的输入框中输入型号或 SKU 编号,然后来自 Do-It Best 和 True Value 的所有相关信息都会在所述 GUI 中弹出。这样我就可以在执行每周订单时将两者并排进行比较。 “参考”表应该允许我比较“doitbest”和“truevalue”表之间相似但不一定相同的产品。
当谈到检索特定数据时,这是我最接近的:
search = "SELECT Description FROM doitbest, truevalue, reference WHERE PrimaryUPC = UPC_entry.get()"
mycursor.execute(search)
myresult = mycursor.fetchall()
for x in myresult:
print(x)
这背后的想法是,我将条形码扫描到由 UPC_entry = customtkinter.CTkEntry 表示的输入框中,但这不起作用。它说,“mysql.connector.errors.ProgrammingError:1630(42000):FUNCTION upc_entry.get不存在。”但是,如果我用条形码替换 UPC_entry.get(),它会在终端中返回相关数据。
第二个问题是如何在 GUI 中而不是仅在终端中显示这些数据。正如我上面所说,我还没有真正找到任何相关信息。出于美观原因,我想使用输入框/小部件,但我想检索数据并将其显示在框中,而不是使用它们来输入信息。我的另一个想法是使用框架、背景颜色和 CTklabel 的组合来模仿输入框/小部件的外观。不过,我对此并没有死心塌地。我会选择任何可以轻松比较信息的东西。我只是不知道你们对此有何建议。哎呀。如果你们有更好的建议,我什至都不会死心塌地地使用 CustomTkinter。
我们重点关注从数据库返回的错误信息。
FUNCTION upc_entry.get does not exist.
您假设数据库能够识别 Python 代码中定义的函数。事实并非如此。
在 SQL 字符串中调用的函数需要存在于正在执行查询的数据库服务器上。它们是使用
CREATE FUNCTION
语句用 SQL 编写的。对于像您所描述的这样的简单应用程序,您不需要编写 SQL 函数。但是,您可以参数化您的 SQL 字符串,以便它将包含 python 函数返回的值。
有一些警告,特别是必须清理输入以防止SQL注入。最简单的方法是确保输入字符串中的每个字符都是数字,并且字符串的长度合理(例如 13 个字符)。
假设您有一个 python 函数
scan_barcode
,它从条形码扫描仪读取输入并将其作为字符串变量返回。
def scan():
barcode = <get stuff from scanner>
<make sure barcode consists only of numbers>
return barcode
然后,您想要在包含条形码的数据库表中查找扫描值,以获取与该条形码关联的一些属性,例如产品名称、价格等
假设该表名为
Product
,其结构如下:
Id /* integer, primary key */
Barcode /* string */
Name /* string */
Price /* float */
要获取扫描产品的名称,您可以尝试如下操作:
def get_name(cursor, barcode):
query = "SELECT [Name] FROM Product WHERE Barcode = " + scan(barcode)
name = cursor.execute(query)
return name
这绝不是一个完美的例子,它忽略了很多,例如错误处理、连接管理等。但是当您了解更多内容时,您可以了解这些主题。
关于如何在 tkinter GUI 中显示信息,这应该是一个单独的问题。
但是,这是Hello World:
from tkinter import *
from tkinter import ttk
root = Tk()
frm = ttk.Frame(root, padding=10)
frm.grid()
ttk.Label(frm, text="Hello World!").grid(column=0, row=0)
ttk.Button(frm, text="Quit", command=root.destroy).grid(column=1, row=0)
root.mainloop()
我们可以像这样合并条形码扫描:
from tkinter import *
from tkinter import ttk
root = Tk()
frm = ttk.Frame(root, padding=10)
frm.grid()
label = ttk.Label(frm, text="Hello World!")
label.grid(column=0, row=0)
ttk.Button(frm, text="Quit", command=root.destroy).grid(column=1, row=0)
def scan():
return "I'm a barcode."
def get_name(barcode):
return "This is a product name." if barcode == "I'm a barcode." else "I'm not sure about this..."
def display_text(some_string):
label.config(text = some_string)
def display_barcode():
display_text(get_name(scan()))
ttk.Button(frm, text="Scan", command=display_barcode).grid(column=1, row=1)
root.mainloop()
我在这里省略了数据库连接,但我看到你已经可以正常工作了,所以你可以填写空白;)