I'm having difficulty with Python 3.6.1 and a GUI utilizing TKinter that I built with the help of the PAGE GUI builder. When I try to get the output of radio buttons or check boxes, I'm getting an error such as:
Exception in Tkinter callback
Traceback (most recent call last):
File "C:\Users\...\Python\Python36-32\lib\tkinter\__init__.py", line 1699, in __call__
return self.func(*args)
File "C:\Users\...\Test\DemTRAN_SpecInstrs.py", line 252, in click_btnNext
stateSpecInstrs = selectRdo.get()
NameError: name 'selectRdo' is not defined
>>>
In my program, the user is asked whether any additional special information is required for a medical exam. Two radio buttons at the top prompt the user to select either No (default) or Yes. There are also a series of checkboxes and a text field for "Other" information, with "Next" and "Cancel" buttons at the bottom. When the user clicks the "Next" button at the bottom of the GUI, one of two things should happen based on the radio button selection:
- If the user selects "No," one set of data will go to a text file, and Notepad will open so the user can copy the data into the Remarks block of another program.
- If the user selects "Yes," another set of data will go to the text file, based on which checkboxes are selected and if the user writes in the text field.
(I tried but failed to add a photo of the GUI. Sorry!)
Unlike the examples I've come across in StackExchange and the rest of the Internet, PAGE does not build everything in a single .py file. It builds the GUI in the main .py file and puts global variables into the support file. I suspect this is where the problem arises, but I can't figure out the resolution.
Here is the code for the support.py file:
#! /usr/bin/env python
#
# Support module generated by PAGE version 4.9
# In conjunction with Tcl version 8.6
# Jun 07, 2017 04:00:21 PM
import sys
try:
from Tkinter import *
except ImportError:
from tkinter import *
try:
import ttk
py3 = 0
except ImportError:
import tkinter.ttk as ttk
py3 = 1
def set_Tk_var():
global combobox
combobox = StringVar()
global vSpecInstrsCheck1
vSpecInstrsCheck1 = StringVar()
global vSpecInstrsCheck2
vSpecInstrsCheck2 = StringVar()
global vSpecInstrsCheck3
vSpecInstrsCheck3 = StringVar()
global vSpecInstrsCheck4
vSpecInstrsCheck4 = StringVar()
global vSpecInstrsCheck5
vSpecInstrsCheck5 = StringVar()
global vSpecInstrsCheck6
vSpecInstrsCheck6 = StringVar()
global vListofInstrs
vListofInstrs = StringVar()
global vSpecInstrs
vSpecInstrs = StringVar()
def init(top, gui, *args, **kwargs):
global w, top_level, root
w = gui
top_level = top
root = top
def destroy_window():
# Function which closes the window.
global top_level
top_level.destroy()
top_level = None
if __name__ == '__main__':
import DemTRAN_SpecInstrs
DemTRAN_SpecInstrs.vp_start_gui()
Here is some of the code from the main file:
#! /usr/bin/env python
#
# GUI module generated by PAGE version 4.9
# In conjunction with Tcl version 8.6
# Jun 07, 2017 04:00:12 PM
import sys
import os
# try deleted from this sample
import DemTRAN_SpecInstrs_support
def vp_start_gui():
'''Starting point when module is the main routine.'''
global val, w, root
root = Tk()
DemTRAN_SpecInstrs_support.set_Tk_var()
top = SPECIAL_INSTRUCTIONS (root)
DemTRAN_SpecInstrs_support.init(root, top)
root.mainloop()
w = None
def create_SPECIAL_INSTRUCTIONS(root, *args, **kwargs):
'''Starting point when module is imported by another program.'''
global w, w_win, rt
rt = root
w = Toplevel (root)
DemTRAN_SpecInstrs_support.set_Tk_var()
top = SPECIAL_INSTRUCTIONS (w)
DemTRAN_SpecInstrs_support.init(w, top, *args, **kwargs)
return (w, top)
def destroy_SPECIAL_INSTRUCTIONS():
global w
w.destroy()
w = None
class SPECIAL_INSTRUCTIONS:
def __init__(self, top=None):
'''This class configures and populates the toplevel window.
top is the toplevel containing window.'''
# Code relating to background/foreground color omitted for clarity
# Re-define global variable to fix radio button issue
selectRdo = IntVar()
selectRdo = DemTRAN_SpecInstrs_support.vSpecInstrs
selectRdo.set(0)
self.btnNext = Button(top)
self.btnNext.place(relx=0.28, rely=0.9, height=34, width=87)
self.btnNext.configure(activebackground="#d9d9d9")
self.btnNext.configure(activeforeground="#000000")
self.btnNext.configure(background="#d9d9d9")
self.btnNext.configure(disabledforeground="#a3a3a3")
self.btnNext.configure(foreground="#000000")
self.btnNext.configure(highlightbackground="#d9d9d9")
self.btnNext.configure(highlightcolor="black")
self.btnNext.configure(pady="0")
self.btnNext.configure(text='''Next''')
self.btnNext.configure(command=self.click_btnNext)
# Only one checkbutton shown. Others omitted for clarity
self.gSpecInstrsCheck5 = ttk.Checkbutton(top)
self.gSpecInstrsCheck5.place(relx=0.22, rely=0.5, relwidth=0.3
, relheight=0.0, height=21)
self.gSpecInstrsCheck5.configure(variable=DemTRAN_SpecInstrs_support.vSpecInstrsCheck5)
self.gSpecInstrsCheck5.configure(takefocus="")
self.gSpecInstrsCheck5.configure(text='''Send to provider in Bend area''')
self.gSpecInstrsNo = Radiobutton(top)
self.gSpecInstrsNo.place(relx=0.45, rely=0.1, relheight=0.05
, relwidth=0.07)
self.gSpecInstrsNo.configure(activebackground="#d9d9d9")
self.gSpecInstrsNo.configure(activeforeground="#000000")
self.gSpecInstrsNo.configure(background="#d9d9d9")
self.gSpecInstrsNo.configure(disabledforeground="#a3a3a3")
self.gSpecInstrsNo.configure(foreground="#000000")
self.gSpecInstrsNo.configure(highlightbackground="#d9d9d9")
self.gSpecInstrsNo.configure(highlightcolor="black")
self.gSpecInstrsNo.configure(justify=LEFT)
self.gSpecInstrsNo.configure(text='''No''')
self.gSpecInstrsNo.configure(value=0)
# self.gSpecInstrsNo.configure(variable=DemTRAN_SpecInstrs_support.vSpecInstrs)
self.gSpecInstrsNo.configure(variable=selectRdo)
self.gSpecInstrsNo.configure(command=self.btnNext)
self.gSpecInstrsYes = Radiobutton(top)
self.gSpecInstrsYes.place(relx=0.45, rely=0.14, relheight=0.05
, relwidth=0.08)
self.gSpecInstrsYes.configure(activebackground="#d9d9d9")
self.gSpecInstrsYes.configure(activeforeground="#000000")
self.gSpecInstrsYes.configure(background="#d9d9d9")
self.gSpecInstrsYes.configure(disabledforeground="#a3a3a3")
self.gSpecInstrsYes.configure(foreground="#000000")
self.gSpecInstrsYes.configure(highlightbackground="#d9d9d9")
self.gSpecInstrsYes.configure(highlightcolor="black")
self.gSpecInstrsYes.configure(justify=LEFT)
self.gSpecInstrsYes.configure(text='''Yes''')
self.gSpecInstrsYes.configure(value=1)
# self.gSpecInstrsYes.configure(variable=DemTRAN_SpecInstrs_support.vSpecInstrs)
self.gSpecInstrsYes.configure(variable=selectRdo)
self.gSpecInstrsYes.configure(command=self.btnNext)
def click_btnNext(self):
# stateSpecInstrs = selectRdo.get()
# if stateSpecInstrs == 1:
# f = open("output.txt","w")
# f.write("Test output for DemTRAN \n")
# f.write("More test output for DemTRAN \n")
# f.write("********************************")
# f.close()
# os.startfile('output.txt')
# else:
# f = open("output.txt","w")
# f.write("Special instructions: No \n")
# f.write("Continue with other text \n")
# f.write("********************************")
# f.close()
# os.startfile('output.txt')
x = vSpecInstrsCheck5.get()
if x == "1":
f = open("output.txt","w")
f.write("******************************** \n")
f.write("SPECIAL INSTRUCTIONS \n")
f.write("Send to provider in Bend area \n")
f.write("******************************** \n")
f.close()
os.startfile('output.txt')
I commented out the "if" statements for the radio button just to see if the behavior was different with the check box. It wasn't.
Curiously, I had to hack this a bit because when I'd run the program, both the No and Yes radio buttons were selected. The user could still select Yes or No and only the active button would be blacked out, but I found this behavior bothersome. I found an article online where a user had the same problem, and the recommended fix was to create a new variable in the class to stand in for the original variable. That fixed the problem. In troubleshooting, I removed that and restored the original variable to see if that made a difference. Assuming I restored every reference to the original value, it didn't change anything.
The "Next" and "Cancel" buttons at the bottom work. To test the "Next" button, I simply had it print dummy data to a text file and then open that file to display the contents. Things broke down when I tried to make the "Next" button send data based on the No or Yes radio button selection.
Any help on where I'm going wrong with my [variable].get()? Thanks!
Aucun commentaire:
Enregistrer un commentaire