Python tkinter禁用“提交”按钮,直到填充所有字段

时间:2019-03-30 00:02:50

标签: python-3.x tkinter

我在Python领域还比较陌生,但是我正在制作一个GUI应用程序,该应用程序具有2个输入字段和2个文件对话框按钮,供用户选择要导入的文件和保存程序输出的目录。我正在尝试对输入字段进行一些验证,以确保在填写输入字段并且他们选择了要导入的文件和要保存输出的目录之前,用户无法单击“提交”按钮。

我有一些办法,但是我被困住了,恐怕我对类和方法还不够了解,无法确定为什么我不能更改Submit_button.config的状态?

我已经阅读了有关如何对输入字段进行验证的各种示例,包括使用validatecommand和在类中构建validate方法。我之所以放弃,是因为我不知道如何验证Submit_button命令中的多个字段。

这是我现在的代码。我正在为Application类中的validate方法苦苦挣扎。

import pandas as pd
import numpy as np
from tkinter import *
from tkinter import ttk
from tkinter import filedialog as fd
from tkinter import messagebox
import os

class FileLogic:

    def __init__(self, path, save_location, request_id, exeuction_id):
        self.path = path
        self.save_location = save_location
        self.request_id = request_id
        self.execution_id = execution_id

    def fileopen(self=None):
        global fileName
        global path
        path = fd.askopenfilename(title = "Select File", filetypes=( ("Excel files", "*.xlsx"),("All files", "*.*") ) )
        fileName = os.path.split(path)[1]

        if not fileName:
            messagebox.showerror("ERROR - File Not Selected", "A file was not selected to process.  Please select a file by double-clicking or select file and press Open button")
        else:
            file_select_label = Label(root, text=("File Selected: " + fileName), width=75, bg="light blue")
            file_select_label.grid(row=7, columnspan=2)

        return path

    def filesave(self=None):
        global save_location
        save_location = fd.askdirectory(title = "Select Directory")

        if not save_location:
            messagebox.showerror("ERROR - Directory Not Selected", "This upload process will build an output file.  Please select a folder where the output file can be saved")
        else:
            file_select_label = Label(root, text=("Output file will be saved: " + save_location), width=75, bg="light blue")
            file_select_label.grid(row=8, columnspan=2)

        return save_location

    def submit(self, path, save_location, request_id, execution_id):

        print("FileLogic path: " + self.path)
        print("FileLogic save: " + self.save_location)
        print("FileLogic request: " + self.request_id)
        print("FileLogic execution: " + self.execution_id)
#        FileParsing.__init__(request_id)

class FileParsing:

    def __init__(self, request_id):
        self.request_id = request_id
#        self.execution_id_entry = execution_id_entry
        print("request id2: " + request_id)

class Application(Frame):

    def __init__(self, master):
        ttk.Frame.__init__(self, master)

        self.grid()
        self.create_widgets()


    def create_widgets(self):
        global submit_button
        ##### Define the Labels ###############
        self.request_id_label = Label(root, text="Enter Rebate Request Id:", bg="light blue", bd=2, width=25).grid(row=0, column=0)
        self.execution_id_label = Label(root, text="Enter Rebate Execution Id:", bg="light blue", bd=2, width=25).grid(row=1, column=0)
        self.blank_label = Label(root, bg="light blue")
        ####### Define the Entry fields ##################


        self.request_id_entry = Entry(root,bg="light gray", bd=2, width=25, textvariable=request_id_entry).grid(row=0, column=1)
        self.execution_id_entry = Entry(root, bg="light gray", bd=2, width=25, textvariable=execution_id_entry).grid(row=1, column=1)

        ###### Define the Buttons ###############
        self.submit_button = Button(root, text="Submit", bg="gray", width=17, command= lambda: self.submit_click(path, save_location, request_id, execution_id))
        self.submit_button.config(state='disabled')

        self.open_file_button = Button(root, text="Select file to process", width = 30, command=FileLogic.fileopen).grid(row=3, column=0)
        self.save_location_button = Button(root, text="Select location to save output", width=30, command=FileLogic.filesave).grid(row=4, column=0)

        ##### Build the Grid ##################
        self.blank_label.grid(row=2, column=0)
        self.blank_label.grid(row=5, columnspan=2)
        self.submit_button.grid(row=6, column=1)

    def validate(self, *args):
        print("validate")
        button_status = self.create_widgets(submit_button)

        if request_id_entry.get():
            print("normal")
            print(button_status)
#            self.submit_button.config(state='normal')
        else:
            print("diabled")
            print(submit_button.config)
#            self.submit_button.config(state='disabled')

    def num_check(self,var):
        var = self.var.get()
        print(var)
        if var.isnumeric():
            return True
        else:
            tkinter.messagebox.showinfo("Error", "Enter Numeric Value")

    def submit_click(self, path, save_location, request_id, execution_id):
        self.request_id = request_id_entry.get()
        self.execution_id = execution_id_entry.get()

        a = FileLogic(path, save_location, request_id, execution_id)
        FileLogic.submit(a, path, save_location, request_id, execution_id)


root=Tk()

root.title("Rebate Bid Data Upload")
root.geometry("500x200")
root.configure(background="light blue")
request_id_entry = StringVar()
execution_id_entry = StringVar()

request_id_entry.trace("w", Application.validate)

app = Application(root)
root.mainloop()

我试图找到禁用提交按钮的位置,直到所有输入元素和filedialog属性完成。然后,对于输入字段,我要检查以确保它们是数字,并且要确保它们是整数。

1 个答案:

答案 0 :(得分:0)

您没有正确使用textvariable。还要注意,您并没有通过定义entry小部件并在同一行调用grid方法来保留对它们的引用。

def create_widgets(self):
    #global submit_button #you don't have to declare global here: submit_button is already an attribute

    ...

    self.request_var = StringVar() #create StringVars for request
    self.execution_var = StringVar() #ditto for execution
    self.request_id_entry = Entry(root,bg="light gray", bd=2, width=25,textvariable=self.request_var).grid(row=0, column=1) #set the textvariable to the StringVar
    self.execution_id_entry = Entry(root, bg="light gray", bd=2, width=25,textvariable=self.execution_var).grid(row=1, column=1)
    self.request_var.trace("w",self.validate) #trace changes on StringVar
    self.execution_var.trace("w",self.validate)

    ...

def validate(self, *args):
    if self.request_var.get() and self.execution_var.get(): #if both StringVars has content
        print("normal")
        self.submit_button.config(state='normal')
    else:
        print("disabled")
        self.submit_button.config(state='disabled')