May-01-2024, 06:24 AM
I have a Python application that can create a graph based on input that the user enters into a form(GUI) that is created via Tkinter. This application is actually made as an Excel addin. It works by creating a custom addin via xlwings and creating a custom ribbon with a button via RibbonXEditor. When the user presses this button, the python function show_form is launched via the VBA function, which actually displays the form. And now the problem is that when the form is displayed, then Excel does not work properly, it is not possible to write in the cells, I have to close the form and only then it works normally, is there any way to fix it?Here is for example the VBA code than is launching the python function.
Sub show_form(control As IRibbonControl) Dim mymodule As String mymodule = Left(ThisWorkbook.Name, _ (InStrRev(ThisWorkbook.Name, ".", -1, vbTextCompare) - 1)) RunPython "import " & mymodule & ";" & _ mymodule & ".show_form()"And here is the my_show function:
def show_form(): window = tk.Tk() window.title("Calculation and Display of p-value") window.resizable(width=False, height=False) frame = tk.Frame(window) frame.pack(padx=10, pady=10) # First Section: Distribution Selection distribution_frame = tk.LabelFrame(frame, text="Distribution Selection") distribution_frame.grid(row=0, column=0, padx=20, pady=10, sticky="news") distribution_label = tk.Label(distribution_frame, text="Distribution: ") distribution_label.grid(row=0, column=0, padx=20, pady=20) distribution_select = ttk.Combobox(distribution_frame, values=["t-distribution", "F-distribution", "chi-square distribution", "z-distribution(0,1)"], state="readonly") distribution_select.grid(row=0, column=1, padx=(0,20), pady=10) # Second Section: Test Statistic Value value_frame = tk.LabelFrame(frame, text="Test Statistic Value") value_frame.grid(row=2, column=0, padx=20, pady=10, sticky="news") # Third Section: Test Parameters parameters_frame = tk.LabelFrame(frame, text="Statistical Test Parameters") parameters_frame.grid(row=1, column=0, padx=20, pady=(0,5), sticky="news") def update_parameters(event): global value_number, parameter1_number, parameter2_number # Clearing previous elements for widget in parameters_frame.winfo_children(): widget.destroy() # Creating new elements based on selection in combobox if distribution_select.get() == "t-distribution": parameter1_label = tk.Label(parameters_frame, text="n₁: ") parameter1_label.grid(row=0, column=0, padx=(20,5), pady=10, sticky='w') parameter1_number = tk.Entry(parameters_frame) parameter1_number.grid(row=0, column=1, padx=(0,20), pady=10, sticky="e") value_label = tk.Label(value_frame, text="t₀: ") value_label.grid(row=0, column=0, padx=20, pady=20) value_number = tk.Entry(value_frame) value_number.grid(row=0, column=1, padx=(0,20), pady=10) elif distribution_select.get() == "F-distribution": parameter1_label = tk.Label(parameters_frame, text="n₁: ") parameter1_label.grid(row=0, column=0, padx=(20,5), pady=10, sticky='w') parameter1_number = tk.Entry(parameters_frame) parameter1_number.grid(row=0, column=1, padx=(0,20), pady=10) parameter2_label = tk.Label(parameters_frame, text="n₂: ") parameter2_label.grid(row=1, column=0, padx=(20,5), pady=10, sticky='w') parameter2_number = tk.Entry(parameters_frame) parameter2_number.grid(row=1, column=1, padx=(0,20), pady=10) value_label = tk.Label(value_frame, text="F₀: ") value_label.grid(row=0, column=0, padx=20, pady=20) value_number = tk.Entry(value_frame) value_number.grid(row=0, column=1, padx=(0,20), pady=10) elif distribution_select.get() == "chi-square distribution": parameter1_label = tk.Label(parameters_frame, text="n₁: ") parameter1_label.grid(row=0, column=0, padx=(20,5), pady=10, sticky='w') parameter1_number = tk.Entry(parameters_frame) parameter1_number.grid(row=0, column=1, padx=(0,20), pady=10) value_label = tk.Label(value_frame, text="x²₀: ") value_label.grid(row=0, column=0, padx=20, pady=20) value_number = tk.Entry(value_frame) value_number.grid(row=0, column=1, padx=(0,20), pady=10) elif distribution_select.get() == "z-distribution(0,1)": value_label = tk.Label(value_frame, text="z₀: ") value_label.grid(row=0, column=0, padx=20, pady=20) value_number = tk.Entry(value_frame) value_number.grid(row=0, column=1, padx=(0,20), pady=10) # Call the update_parameters function when there is a change in the combobox distribution_select.bind("<<ComboboxSelected>>", update_parameters) # Third Section: Test Type type_frame = tk.LabelFrame(frame, text="Test Type") type_frame.grid(row=3, column=0, padx=20, pady=(0,5), sticky="news") left_sided_value = tk.IntVar() right_sided_value = tk.IntVar() two_sided_value = tk.IntVar() alpha_value = tk.IntVar() test_type = tk.IntVar() def set_test_type(): if test_type.get() == 1: left_sided_value.set(1) right_sided_value.set(0) two_sided_value.set(0) elif test_type.get() == 2: left_sided_value.set(0) right_sided_value.set(1) two_sided_value.set(0) else: left_sided_value.set(0) right_sided_value.set(0) two_sided_value.set(1) test_type.set(1) # Sets the default value to left-sided test set_test_type() left_sided_button = tk.Radiobutton(type_frame, text="Left-sided", variable=test_type, value=1, command=set_test_type) left_sided_button.grid(row=0, column=0, padx=(20, 5), pady=10, sticky='w') right_sided_button = tk.Radiobutton(type_frame, text="Right-sided", variable=test_type, value=2, command=set_test_type) right_sided_button.grid(row=1, column=0, padx=(20, 5), pady=10, sticky='w') two_sided_button = tk.Radiobutton(type_frame, text="Two-sided", variable=test_type, value=3, command=set_test_type) two_sided_button.grid(row=2, column=0, padx=(20, 5), pady=10, sticky='w') def update_alpha_widgets(): global alpha_number if alpha_value.get() == 1: alpha_label = tk.Label(alpha_frame, text="Alpha value: ") alpha_label.grid(row=1, column=0, padx=(20,5), pady=10, sticky='w') alpha_number = tk.Entry(alpha_frame) alpha_number.grid(row=1, column=1, padx=(0,20), pady=10) else: for widget in alpha_frame.winfo_children(): widget.destroy() alpha_button = tk.Checkbutton(alpha_frame, text="Show Alpha", variable=alpha_value, onvalue=1, offvalue=0, command=update_alpha_widgets) alpha_button.grid(row=0, column=0, padx=(20,5), pady=10, sticky='w') # Fourth Section alpha_frame = tk.LabelFrame(frame, text="Alpha") alpha_frame.grid(row=4, column=0, padx=20, pady=(0,5), sticky="news") alpha_button = tk.Checkbutton(alpha_frame, text="Show Alpha", variable=alpha_value, onvalue=1, offvalue=0, command=update_alpha_widgets) alpha_button.grid(row=0, column=0, padx=(20,5), pady=10, sticky='w') def check_values(): # Checking if all values are defined if distribution_select.get() == "t-distribution": if len(parameter1_number.get()) == 0 or len(value_number.get()) == 0: messagebox.showerror("Error", "Parameter or test value is not provided") elif not parameter1_number.get().isnumeric() or not is_float(value_number.get()): messagebox.showerror("Error", "Parameter and test value cannot contain letters") else: if alpha_value.get() == 1: if len(alpha_number.get()) == 0: messagebox.showerror("Error","Alpha value must be provided") elif not is_float(alpha_number.get()): messagebox.showerror("Error","Alpha value cannot contain letters") elif float(alpha_number.get()) <= 0 or float(alpha_number.get()) > 1: messagebox.showerror("Error","Alpha value must be between 0 and 1") else: p_from_t(float(value_number.get()),int(parameter1_number.get()),left_sided_value.get(),right_sided_value.get(),two_sided_value.get(),float(alpha_number.get())) else: p_from_t(float(value_number.get()),int(parameter1_number.get()),left_sided_value.get(),right_sided_value.get(),two_sided_value.get(),None) elif distribution_select.get() == "z-distribution(0,1)": if len(value_number.get()) == 0: messagebox.showerror("Error", "Test value is not provided") elif not is_float(value_number.get()): messagebox.showerror("Error", "Test value cannot contain letters") else: if alpha_value.get() == 1: if len(alpha_number.get()) == 0: messagebox.showerror("Error","Alpha value must be provided") elif not is_float(alpha_number.get()): messagebox.showerror("Error","Alpha value cannot contain letters") elif float(alpha_number.get()) <= 0 or float(alpha_number.get()) > 1: messagebox.showerror("Error","Alpha value must be between 0 and 1") else: p_from_z(float(value_number.get()),left_sided_value.get(),right_sided_value.get(),two_sided_value.get(),float(alpha_number.get())) else: p_from_z(float(value_number.get()),left_sided_value.get(),right_sided_value.get(),two_sided_value.get(),None) elif distribution_select.get() == "F-distribution": if len(parameter1_number.get()) == 0 or len(value_number.get()) == 0 or len(parameter2_number.get()) == 0: messagebox.showerror("Error", "Parameter or test value is not provided") elif not parameter1_number.get().isnumeric() or not is_float(value_number.get()) or not parameter2_number.get().isnumeric(): messagebox.showerror("Error", "Parameter and test value cannot contain letters") else: if alpha_value.get() == 1: if len(alpha_number.get()) == 0: messagebox.showerror("Error","Alpha value must be provided") elif not is_float(alpha_number.get()): messagebox.showerror("Error","Alpha value cannot contain letters") elif float(alpha_number.get()) <= 0 or float(alpha_number.get()) > 1: messagebox.showerror("Error","Alpha value must be between 0 and 1") else: p_from_f(float(value_number.get()),int(parameter1_number.get()),int(parameter2_number.get()),left_sided_value.get(),right_sided_value.get(),two_sided_value.get(),float(alpha_number.get())) else: p_from_f(float(value_number.get()),int(parameter1_number.get()),int(parameter2_number.get()),left_sided_value.get(),right_sided_value.get(),two_sided_value.get(),None) elif distribution_select.get() == "chi-square distribution": if len(parameter1_number.get()) == 0 or len(value_number.get()) == 0: messagebox.showerror("Error", "Parameter or test value is not provided") elif not parameter1_number.get().isnumeric() or not is_float(value_number.get()): messagebox.showerror("Error", "Parameter and test value cannot contain letters") else: if alpha_value.get() == 1: if len(alpha_number.get()) == 0: messagebox.showerror("Error","Alpha value must be provided") elif not is_float(alpha_number.get()): messagebox.showerror("Error","Alpha value cannot contain letters") elif float(alpha_number.get()) <= 0 or float(alpha_number.get()) > 1: messagebox.showerror("Error","Alpha value must be between 0 and 1") else: p_from_chi_square(float(value_number.get()),int(parameter1_number.get()),left_sided_value.get(),right_sided_value.get(),two_sided_value.get(),float(alpha_number.get())) else: p_from_chi_square(float(value_number.get()),int(parameter1_number.get()),left_sided_value.get(),right_sided_value.get(),two_sided_value.get(),None) button = tk.Button(frame, text="Generate", height=4, width=8, command=check_values) button.grid(row=5, column=0, padx=20, pady=20) window.mainloop()Sorry for messy code