简体   繁体   English

如何一次从多个 Tkinter GUI 窗口写入 Excel 文件?

[英]How to write from multiple Tkinter GUI windows to an Excel file at a time?

I'm new to Tkinter.我是 Tkinter 的新手。 Trying to write the user inputs from my multiple tkinter GUI to an Excel file using the below, still the latest value is getting overridden.尝试使用以下命令将我的多个 tkinter GUI 中的用户输入写入 Excel 文件,但最新值仍然被覆盖。 I'm not able to keep the previous input values from the user to the Excel.我无法将用户以前的输入值保留到 Excel。 Requesting your help here.在此请求您的帮助。 I have used numofvm() to create number of tkinter windows, accordingly GUI's will get created and then after User will enter the values through GUI.我已经使用 numofvm() 创建了多个 tkinter 窗口,因此将创建 GUI,然后用户将通过 GUI 输入值。

from tkinter import *
import xlwt


# designing window for vmdetails

def Vmdetails():
    global vmdetails_screen
    for i in range(1,N+1):
        t=i
        numb=str(t)
        vmdetails_screen = Toplevel(numofvm_screen)
        vmdetails_screen.title("VM_Details_"+ numb)
        vmdetails_screen.geometry("400x950")

        global cluster_name
        global vm_template
        global clustername_entry



        # Set text variables
        cluster_name = StringVar()
        vm_template = StringVar()


        # Set label for user's instruction
        Label(vmdetails_screen, text="Please enter details below", bg="blue").pack()
        Label(vmdetails_screen, text="").pack()

        Cluster_Name_lable = Label(vmdetails_screen, text="Cluster_Name "+ numb +"* ")
        Cluster_Name_lable.pack()

        # Set textvariables entry

        clustername_entry = Entry(vmdetails_screen, textvariable=cluster_name)
        clustername_entry.pack()

        Button(vmdetails_screen, text="Submit", width=10, height=1, command=check).pack()


def check():
    # Retrieve the value from the entry and store it to a variable
    global var
    if cluster_name.get() == '':
        invalid_value()
    else:
     write_to_xls()

def invalid_value():
    global invalid_value_screen
    invalid_value_screen = Toplevel(vmdetails_screen)
    invalid_value_screen.title("Invalid Entry")
    invalid_value_screen.geometry("250x100")
    Label(invalid_value_screen, text="Enter valid values for all the required fields").pack()
    Button(invalid_value_screen, text="OK", command=delete_invalid_value).pack()


def delete_invalid_value():
    invalid_value_screen.destroy()


# designing window to provide the number of vm's to be created

def numofvm():

    global numofvm_screen
    numofvm_screen = Toplevel(main_screen)
    numofvm_screen.title("VM_NUM")
    numofvm_screen.geometry("300x250")

    global vmnumber
    global vmnumber_entry
    vmnumber = StringVar()

    Label(numofvm_screen, text="Please enter the Number of VM's you wishes to create ", bg="blue").pack()
    Label(numofvm_screen, text="").pack()

    vmnumber_lable = Label(numofvm_screen, text="Number of VM's to be created * ")
    vmnumber_lable.pack()

    vmnumber_entry = Entry(numofvm_screen, textvariable=vmnumber)
    vmnumber_entry.pack()

    Button(numofvm_screen, text="Submit", width=10, height=1, command=screen_duplicate).pack()


def screen_duplicate():
    global N
    N = int(vmnumber.get())
    if N > 0  :
      Vmdetails()

#exporting the user inputs into an excel sheet

def write_to_xls():
    # create new workbook
    wb = xlwt.Workbook()

    for i in range(1,N+1):
        t=i
        numb=str(t)
    # add sheet using given name
        ws = wb.add_sheet("VM_"+numb+"_DETAILS")

    # write text to cell
        ws.write(0, 0, "Cluster_Name")
        ws.write(1, 0,cluster_name.get())


    # save to given file name
    wb.save('my_file.xls')


def main_account_screen():
    global main_screen
    main_screen = Tk()
    main_screen.geometry("300x250")
    main_screen.title("Welcome")
    Label(text="Select Your Choice", bg="blue", width="300", height="2", font=("Calibri", 13)).pack()
    Label(text="").pack()
    Button(text="Enter", height="2", width="30", command=numofvm).pack()
    Label(text="").pack()
    main_screen.mainloop()


main_account_screen()

As I explained in a comment, the data writing problem is because you need to store the StringVar s and related information is list s instead of overwriting the previous values by only using a single-value variables.正如我在评论中解释的,数据写入问题是因为您需要存储StringVar和相关信息是list而不是仅使用单值变量覆盖以前的值。

While fixing that would be possible without doing so, your use of so many global variables makes the code hard to understand, debug, and modify—which are all reason the common wisdom is to avoid them as much as possible.虽然不这样做也可以解决这个问题,但您使用如此多的全局变量会使代码难以理解、调试和修改——这都是常识是尽可能避免它们的原因。

Here's a list the ones the code in your question uses:这是您问题中的代码使用的列表:

cluster_name , clustername_entry , vm_template , vmdetails_screen , invalid_value_screen , numofvm_screen , vmnumber , vmnumber_entry , N , main_screen cluster_nameclustername_entryvm_templatevmdetails_screeninvalid_value_screennumofvm_screenvmnumbervmnumber_entryNmain_screen

Since that's a quite a few, I decided to also eliminate them as well in the code below to make the design "cleaner" besides only showing how to store the data in list s as suggested.由于这是相当多的,我决定在下面的代码中也消除它们,以使设计“更干净”,除了只显示如何按照建议将数据存储在list Hopefully this will provide you with a better foundation for the continued development of your application.希望这将为您的应用程序的持续开发提供更好的基础。

To avoid the global s, most of them have been turned into attributes of an class representing your entire application—which is a design based on this answer to anther tkinter question by tkinter guru @Bryan Oakley.为了避免global S,其中大部分已变成代表整个应用程序,这是基于设计的类的属性这个答案花药tkinter问题由Tkinter的大师@Bryan奥克利。

from tkinter import *
import tkinter.messagebox as tkMessageBox
import os
import xlwt


class MyApp(Tk):
    LABEL_BG = "light blue"

    def __init__(self):
        Tk.__init__(self)
        self.geometry("300x250")
        self.title("Welcome")
        Label(text="Select Your Choice", bg=self.LABEL_BG, width="300", height="2",
              font=("Calibri", 13)).pack()
        Label(text="").pack()
        Button(text="Enter", height="2", width="30", command=self.numofvm).pack()
        Label(text="").pack()

    def numofvm(self):
        """ Designing window to provide the number of VMs to be created. """
        self.numofvm_screen = Toplevel(self)
        self.numofvm_screen.title("VM_NUM")
        self.numofvm_screen.geometry("300x250")

        self.vmnumber = StringVar()

        Label(self.numofvm_screen,
              text="Please enter the Number of VMs you wishes to create",
              bg=self.LABEL_BG).pack()
        Label(self.numofvm_screen, text="").pack()

        vmnumber_lable = Label(self.numofvm_screen,
                               text="Number of VMs to be created:")
        vmnumber_lable.pack()

        self.vmnumber_entry = Entry(self.numofvm_screen, textvariable=self.vmnumber)
        self.vmnumber_entry.pack()

        Button(self.numofvm_screen, text="Submit", width=10, height=1,
               command=self.screen_duplicate).pack()

        self.numofvm_screen.focus_set()

    def screen_duplicate(self):
        try:
            self.N = int(self.vmnumber.get())
        except ValueError:
            self.N = 0

        if self.N > 0:
            self.vm_details()

    def vm_details(self):
        """ Create designing windows for VM details.
        """
        # Preallocate and then create VM detail screens and data.
        self.cluster_names = [None for _ in range(self.N)]
        self.clustername_entries = [None for _ in range(self.N)]
        self.vm_templates = [None for _ in range(self.N)]
        self.vmdetails_screen = [None for _ in range(self.N)]

        for i in range(self.N):
            numb = str(i+1)
            self.vmdetails_screen[i] = Toplevel()
            self.vmdetails_screen[i].title("VM Details " + numb)
            self.vmdetails_screen[i].geometry("400x950")

            # Set text variables
            self.cluster_names[i] = StringVar()
            self.vm_templates[i] = StringVar()

            # Set label for user's instruction
            Label(self.vmdetails_screen[i], text="Please enter details below:",
                  bg=self.LABEL_BG).pack()
            Label(self.vmdetails_screen[i], text="").pack()

            Cluster_Name_lable = Label(self.vmdetails_screen[i],
                                       text="Cluster Name "+ numb + ":")
            Cluster_Name_lable.pack()

            # Set textvariables entry
            self.clustername_entries[i] = Entry(self.vmdetails_screen[i],
                                                textvariable=self.cluster_names[i])
            self.clustername_entries[i].pack()

            Button(self.vmdetails_screen[i], text="Submit", width=10, height=1,
                   command=self.validate).pack()

    def validate(self):
        """ Check values of ALL cluster name entries and save them to excel
            file if they're all valid.
        """
        if not all(cluster_name.get() for cluster_name in self.cluster_names):
            self.invalid_value()
        else:
            self.write_to_xls()
            tkMessageBox.showinfo("Info", '"%s" file written' % self.xls_filepath)

            # Get rid of all data entry screens.
            for i in range(self.N):
                self.vmdetails_screen[i].destroy()

            self.numofvm_screen.destroy()

    def invalid_value(self):
        """ Display error message screen.
        """
        self.invalid_value_screen = Toplevel()
        self.invalid_value_screen.title("Invalid Entry")
        self.invalid_value_screen.geometry("400x100")
        Label(self.invalid_value_screen,
              text="Please enter valid values for the fields in ALL\n"
                   "VM Detail windows before clicking Submit button").pack()
        Button(self.invalid_value_screen, text="OK",
               command=lambda: self.invalid_value_screen.destroy()).pack()

    def write_to_xls(self):
        """ Export all user's inputs to an excel sheet. """

        # Create new workbook.
        wb = xlwt.Workbook()

        for i in range(self.N):
            numb = str(i+1)
            # Add sheet using given name.
            ws = wb.add_sheet("VM_" + numb + "_DETAILS")

            # Write text to cell.
            ws.write(0, 0, "Cluster_Name")
            ws.write(1, 0, self.cluster_names[i].get())

        # Save excel file in same directory as script.
        self.xls_filepath = os.path.join(os.path.dirname(__file__), 'my_file.xls')
        wb.save(self.xls_filepath)


if __name__ == '__main__':
    root = MyApp()
    root.mainloop()

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM