【问题标题】:Python Tkinter Loop to validate entry before INSERT SQLITEPython Tkinter 循环在 INSERT SQLITE 之前验证条目
【发布时间】:2020-12-20 10:35:39
【问题描述】:

我试图在将该信息插入 SQLITE 数据库之前验证一个条目。 我有一个带按钮的主要 Tkinter 画布。在这种情况下,该按钮会打开另一个窗口,用户可以在其中输入必填字段。我的想法是避免用户提交空字段。 我设法有一个消息框说出了点问题,但是一旦我按下“确定”,代码就会继续并关闭输入窗口。 第 1 步 - 打开输入窗口:

def open_add_ship_window():
    global ship_window
    ship_window = Tk()
    ship_window.title('Add Ship')
    ship_window.iconbitmap(
        'C:/Users/eduardo.js.ramos/Desktop/VSCode/img directory/ship_icon_1.ico')
    ship_window.geometry("400x200")
    global ship_name_ship_window
    global ship_imo_ship_window
    global ISM_ship_window
    global ISM_IMO_ship_window
    # Create Text Boxes
    ship_name_ship_window = Entry(ship_window, width=40)
    ship_name_ship_window.grid(row=0, column=1, pady=(10, 0))
    ship_imo_ship_window = Entry(ship_window, width=40)
    ship_imo_ship_window.grid(row=1, column=1)
    ISM_ship_window = Entry(ship_window, width=40)
    ISM_ship_window.grid(row=2, column=1)
    ISM_IMO_ship_window = Entry(ship_window, width=40)
    ISM_IMO_ship_window.grid(row=3, column=1)
    # Create Labels
    ship_name_ship_window_label = Label(
        ship_window, text="Vessel Name")
    ship_name_ship_window_label.grid(row=0, column=0, pady=(10, 0))
    ship_imo_ship_window_label = Label(
        ship_window, text="Vessel IMO")
    ship_imo_ship_window_label.grid(row=1, column=0)
    ISM_ship_window_label = Label(ship_window, text="ISM Company")
    ISM_ship_window_label.grid(row=2, column=0)
    ISM_IMO_ship_window_label = Label(
        ship_window, text="ISM IMO Number")
    ISM_IMO_ship_window_label.grid(row=3, column=0)
    # Create Save New Ship Button
    save_ship_btn = Button(
        ship_window, text="Add New Ship", command=add_ship)
    save_ship_btn.grid(row=4, column=0, columnspan=2,
                       pady=10, padx=10, ipadx=50)

第 2 步 - 将数据提交到 SQLITE 数据库:

def add_ship():
    # connect to database
    conn = sqlite3.connect('PSC.sdb')
    # create cursor
    c = conn.cursor()
    while True:
        if len(ship_name_ship_window.get()) != 0 \
                or len(ship_imo_ship_window.get()) != 0 \
                or len(ISM_ship_window.get()) != 0 \
                or len(ISM_IMO_ship_window.get()) != 0:
            c.execute("INSERT INTO ships VALUES(:name, :imoship, :ism, :ismimo , null, null)",
                      {
                          'name': ship_name_ship_window.get(),
                          'imoship': ship_imo_ship_window.get(),
                          'ism': ISM_ship_window.get(),
                          'ismimo': ISM_IMO_ship_window.get()
                      })
        else:
            messagebox.showwarning(title='Review Needed', message='Please complete all fieds.')
            continue
    conn.commit()
    conn.close()
    ship_window.destroy()

大家有什么建议吗?

【问题讨论】:

  • 这行得通吗?问题是什么?以及为什么不使用sqlite 占位符而不是这种在VALUES(:name, ........) 中传递值的方法
  • 我是这方面的初学者,没有任何 IT 背景,正在努力学习和制作一些可能会产生额外收入的东西。
  • 我也是一个初学者,但您必须详细说明您的问题,以便有人能够提供帮助
  • 您应该在if 语句中使用and 而不是or
  • 我打开了第二个 tkinter 窗口,其中有 4 个输入框和 1 个按钮。该按钮在 SQLITE 数据库中插入新行。如果一个或多个输入框未完成,我希望弹出消息框以提醒用户并将其带回窗口,在那里他可以继续输入剩余信息

标签: python sqlite loops tkinter


【解决方案1】:
  • 您应该将add_ship() 中的最后三行移到if 块中
  • if 语句中将or 更改为and
  • 删除while循环

下面是修改后的add_ship()

def add_ship():
    # get the information
    ship_name = ship_name_ship_window.get().strip()
    ship_imo = ship_imo_ship_window.get().strip()
    ism_ship = ISM_ship_window.get().strip()
    ism_imo = ISM_IMO_ship_window.get().strip()
    # if all is input
    if ship_name and ship_imo and ism_ship and ism_imo:
        # connect to database
        conn = sqlite3.connect('PSC.sdb')
        # create cursor
        c = conn.cursor()
        c.execute("INSERT INTO ships VALUES (:name, :imoship, :ism, :ismimo, NULL, NULL)",
                  {
                      'name': ship_name,
                      'imoship': ship_imo,
                      'ism': ism_ship,
                      'ismimo': ism_imo
                  })
        conn.commit()
        conn.close()
        ship_window.destroy()
    else:
        messagebox.showwarning(title='Review Needed', message='Please complete all fieds.')

【讨论】:

  • 完美运行并解决了我的问题。非常感谢您的时间和耐心@acw1668
【解决方案2】:

关闭消息框后,主循环结束,因此您可能必须将上述代码放入循环中,这样一旦消息框显示错误,循环就不会结束。

一种可能的方式是:

While True :
"""Input tags here"""
if len(ship_name_ship_window.get()) != 0 \
                or len(ship_imo_ship_window.get()) != 0 \
                or len(ISM_ship_window.get()) != 0 \
                or len(ISM_IMO_ship_window.get()) != 0:
            c.execute("INSERT INTO ships VALUES(:name, :imoship, :ism, :ismimo , null, null)",
                      {
                          'name': ship_name_ship_window.get(),
                          'imoship': ship_imo_ship_window.get(),
                          'ism': ISM_ship_window.get(),
                          'ismimo': ISM_IMO_ship_window.get()
                      })
            break
else:
     messagebox.showwarning(title='Review Needed', message='Please complete all fieds.')
     continue

【讨论】:

  • “消息框关闭后主循环结束”root.mainloop() 仅在应用关闭时结束。
  • 我已经尝试过这种方式,但是我不断地一遍又一遍地收到消息框!
  • @CoolCloud 关闭的循环不是主要循环,而是输入框为空的循环。
  • 把输入框放到我做的循环里再试一次
  • @VedantMatanhelia 输入标签是什么意思?这个“'名称':ship_name_ship_window.get()”?
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2020-11-14
  • 1970-01-01
相关资源
最近更新 更多