Oct-07-2021, 02:52 PM
(This post was last modified: Oct-07-2021, 02:52 PM by deanhystad.)
Next time you have a problem make a small example that demonstrates the problem. Usually this will expose the problem so you can solve it yourself. If it doesn't expose the problem at least you have a nice example to post. Here is my short example that demonstrates your problem.
Now for the rant.
Your code is awful. I can see why you could not find the error because it is really hard to see what your code does. You have code that makes a window, then you define a function. That is followed by code that adds some widgets to the window and another function, I am going to call this the "stream of thought" design pattern. Whenever you think of anything to add to the program you add it to the bottom of the source file. Like stream of thought, this results in a tangled mess that is in need of editing.
The very first thing to do is delete this line.
Your next step should be to take all the functions and move them to the top of your file. When you move the files group them by functions that work together or functions that do the same kind of thing. Maybe openNew and openNewWindow should be grouped. And maybe they should have a better name. What is openWindow used for? What is openNewWindow used for? Why don't any of your functions have docstrings that say what they do? As you are organizing your functions you will add a docstring to each to describe what it does. And if the name of the function does not match the docstring description, you will rename the function.
The third step is to review your main code body and see if it contains anything else that should be a function. Do you have duplicate code? Maybe you need a function. A quick review shows a bunch of database queries. I would think about making these functions.
While doing this review I would also look at code like this:
It would almost make me think you don't like adding variables, but then you have code like this:
import tkinter as tk from tkinter import ttk def vita(): if shadeguide.get()== 2: incisalentry.configure(state="normal") valuentry.configure(state="disable") else: incisalentry.configure(state="disable") valuentry.configure(state="normal") root = tk.Tk() incisalentry = ttk.Combobox(root, state="readonly", width=6, values=("A1","A2")) incisalentry.pack() valuentry = ttk.Combobox(root, state="readonly", width=6, values=("0","1")) valuentry.pack() shadeguide = tk.IntVar(value=1) tk.Radiobutton(root, text="Vita Classic", variable=shadeguide, value=1, command=vita()).pack() tk.Radiobutton(root, text="Vita 3D", variable=shadeguide, value=2, command=vita()).pack() root.mainloop()As you say, changing the radio cluster does nothing. I wondered if I set up the radio buttons correctly. To test I added a print statement to vita().
ef vita(): print(shadeguide.get()) if shadeguide.get()== 2: incisalentry.configure(state="normal") valuentry.configure(state="disable") else: incisalentry.configure(state="disable") valuentry.configure(state="normal")When I ran the program it immediately printed 1 twice, but did not print anything when I pressed either of the radio buttons.
Output:1
1
So I am calling vita() twice when I create the window, but not when I press the button. Knowing this it is obvious what the problem is. See it?tk.Radiobutton(root, text="Vita Classic", variable=shadeguide, value=1, command=vita()) tk.Radiobutton(root, text="Vita 3D", variable=shadeguide, value=2, command=vita())Instead of binding the radio buttons to vita, I was calling vita() and binding the radio buttons to the return value (None). Removing the parenthesis fixes the problem.
tk.Radiobutton(root, text="Vita Classic", variable=shadeguide, value=1, command=vita).pack() tk.Radiobutton(root, text="Vita 3D", variable=shadeguide, value=2, command=vita).pack() vita() # Call to initially enable/disable controlsThis is what you should be doing whenever you encounter a problem. If you cannot see the source of the problem try adding a few print statements to verify that the code works as you expect. If the print statements don't uncover something (this time they did), make a simplified version of your program that still demonstrates the problem. This step nearly always exposes the problem because you have far less code to examine.
Now for the rant.
Your code is awful. I can see why you could not find the error because it is really hard to see what your code does. You have code that makes a window, then you define a function. That is followed by code that adds some widgets to the window and another function, I am going to call this the "stream of thought" design pattern. Whenever you think of anything to add to the program you add it to the bottom of the source file. Like stream of thought, this results in a tangled mess that is in need of editing.
The very first thing to do is delete this line.
from tkinter import *Never, ever do import *. This imports every name (variables and functions) defined in tkinter. Do you know every variable in tkinter? Do you know every function? I you don't how do you know that your program isn't overriding some important tkinter function or redefining some important tkinter variable. After deleting this line you will have to sprinkle some "tk." here an there because your program will not know where to find "W" or "RadioButton". This small amount of pain will serve as a lesson, a lesson far less painful than the one you were doomed to face in the future when a tiny change to your code somehow ended up breaking everything.
Your next step should be to take all the functions and move them to the top of your file. When you move the files group them by functions that work together or functions that do the same kind of thing. Maybe openNew and openNewWindow should be grouped. And maybe they should have a better name. What is openWindow used for? What is openNewWindow used for? Why don't any of your functions have docstrings that say what they do? As you are organizing your functions you will add a docstring to each to describe what it does. And if the name of the function does not match the docstring description, you will rename the function.
The third step is to review your main code body and see if it contains anything else that should be a function. Do you have duplicate code? Maybe you need a function. A quick review shows a bunch of database queries. I would think about making these functions.
While doing this review I would also look at code like this:
incisalentry['values']=("A1","A2","A3","A3.5","A4","B1","B2","B3","B4","C1","C2","C3","C4","D2","D3","D4") incisalentry.current() middleentry =ttk.Combobox(root,state="readonly",width=6,textvariable=middlevalue) middleentry['values']=("A1","A2","A3","A3.5","A4","B1","B2","B3","B4","C1","C2","C3","C4","D2","D3","D4")Why do you repeat that list? What do those combinations of letters and numbers mean? You use them in multiple places, so why not make a variable for that list and use the variable name.
It would almost make me think you don't like adding variables, but then you have code like this:
#Text for our form lab = Label(root, text=" Lab. Name",bg="light blue") patientname=Label(root, text=" Patient.Name",bg="light blue") ... lab.grid(row=1, column=0,padx=5,pady=5) patientname.grid(row=1, column=2,padx=5,pady=5)patientname is a good variable name. I would probably want to use that to be the name of the patient. You waste it on a label. A variable that is only used once; to place the label in the grid. You don't need this variable. Make the label and place it in the grid in the same line. You don't need a variable for this label because you NEVER use that variable again. Sorry, that is wrong. You do use the variable again. Later on it is used for another label and again it is only used once: to place the label in the grid. Hey, wait. Is there duplicate code here?