Tkinter GUI not functioning properly

Post here if you need help with creating a Graphical User Interface in Python.

Tkinter GUI not functioning properly

Postby weatherman » Sat Jan 18, 2014 7:52 pm

All,

I am somewhat familiar with python, but new to Tkinter and GUI creation. I am trying to create a simple radio button and use the resultant variable later in my code. With the code below I am able to get a GUI to pop up, however, here are my troubles:
1) The program proceeds without making a GUI selection, i.e. it keeps the set value and goes into the "def checked" without interacting with the submit button.
2) The GUI never goes away without clicking the "x".
What I want:
1) The script to wait for me to make a radiobutton selection and hit submit
2) GUI goes away
3) Enter def checked
4) Exit the mainloop()
5) Proceed with the rest of the code (which it is also not doing)

here is the code:

Code: Select all
import os
from os import path
from Tkinter import *
import tkMessageBox
import Tkinter

class Procedure (SmartScript.SmartScript):
def __init__(self, dbss):
SmartScript.SmartScript.__init__(self, dbss)

def clicked(self):
RunType = self.Runtype.get()
os.system('echo '+RunType+' > /data/local/NWPS/var/test/runtype')
self.customGUI.destroy()

def makeGUI(self, customGUI):
self.RunType = StringVar()
self.RunType.set("ShortTerm")
ST = Radiobutton(customGUI, text = "Short Term", indicatoron = 0, width = 20, variable = self.RunType, value = "ShortTerm")
LT = Radiobutton(customGUI, text = "Long Term", indicatoron= 0, width = 20, variable = self.RunType, value = "LongTerm")
okButton = Button(customGUI, text = "Submit", command = self.clicked())
ST.pack()
LT.pack()
okButton.pack()

def execute(self, editArea, timeRange, varDict):

customGUI = Tk()
makeIt = self.makeGUI(customGUI)
customGUI.mainloop()

much more irrelevant code below..............
Last edited by stranac on Sat Jan 18, 2014 8:07 pm, edited 1 time in total.
Reason: First post lock.
weatherman
 
Posts: 9
Joined: Sat Jan 18, 2014 7:29 pm

Re: Tkinter GUI not functioning properly

Postby Yoriz » Sat Jan 18, 2014 8:25 pm

Your command is being set as a called method
Code: Select all
okButton = Button(customGUI, text = "Submit", command = self.clicked())

remove the () so when the button is pressed it calls the method itself
Code: Select all
okButton = Button(customGUI, text = "Submit", command = self.clicked)
New Users, Read This
Join the #python-forum IRC channel on irc.freenode.net!
Spam topic disapproval technician
Windows7, Python 2.7.4., WxPython 2.9.5.0., some Python 3.3
User avatar
Yoriz
 
Posts: 832
Joined: Fri Feb 08, 2013 1:35 am
Location: UK

Re: Tkinter GUI not functioning properly

Postby weatherman » Mon Jan 20, 2014 3:29 am

OK, so that stopped the program from running through before I made a selection, but the problem I'm having now is that one the GUI appears and I make my selection nothing happens and the GUI won't go away until I click the "x".
weatherman
 
Posts: 9
Joined: Sat Jan 18, 2014 7:29 pm

Re: Tkinter GUI not functioning properly

Postby weatherman » Mon Jan 20, 2014 11:06 am

Ok, was able to debug quite a bit tonight. Here are the current issues with the script:
1) The value never gets stored to the variable in the Radiobutton call. I get an empty string when I try to dump it into a file.
2) There is some sort of issue with the customGUI.mainloop() placement, or the way I try to exit the mainloop. The GUI needs to be called from the execute method because this is a script that is initialized when it is saved and it awaits another script to call the execute method upon user request. If the GUI call is outside of the execute, GUIs start popping up all over the place on everyone's computers once I save haha. So, the issue is that once I destroy the GUI in the submitted method the script doesn't proceed past the mainloop. I verified this by moving the mainloop below all the other stuff in the execute method and the remainder of the script executes before the GUI selection is made. I will be expanding the code in the execute section and it will need the variable returned from the GUI. So, I need to be able to get the user input, exit the mainloop and continue through the script. I CANNOT FIGURE IT OUT!!!! Help! Here is the latest version of the code. I did a major overhaul from the previous version. Thanks in advance!

Code: Select all
import SmartScript
import os
from os import path
from Tkinter import *

customGUI = None

class Procedure (SmartScript.SmartScript):
   def __init__(self, dbss):
      SmartScript.SmartScript.__init__(self, dbss)
   
   def execute(self, editArea, timeRange, varDict):

      global customGUI
      customGUI = Tk()
      customGUI.title("Select Run Type")
      GUIapp = _GUIconfig()
      customGUI.mainloop()
      
      PCBNest = varDict["Panama City Nest:"]
      CSBNest = varDict["Cape San Blas Nest:"]
      STMNest = varDict["St. Marks Nest:"]
      CDKNest = varDict["Cedar Key Nest:"]
      PCBNest = str(PCBNest)
      CSBNest = str(CSBNest)
      STMNest = str(STMNest)
      CDKNest = str(CDKNest)
      
      nestarray = [PCBNest, CSBNest, STMNest, CDKNest]
      for index, item in enumerate(nestarray):
         if item == "Yes":
            nestnum = "NEST"+str(index+1)
            os.system('touch /data/local/NWPS/var/test/%s' % nestnum)
      self.statusBarMsg("Winds and nests have been sent to NWPS", "U")

class _GUIconfig:
   def __init__(self):
      global customGUI
      self.RunType = StringVar()
      ST = Radiobutton(customGUI, text = "Short Term", indicatoron = 0, width = 20, variable = self.RunType, value = "Short Term").pack()
      LT = Radiobutton(customGUI, text = "Long Term", indicatoron= 0, width = 20, variable = self.RunType, value = "Long Term").pack()
      submitButton = Button(customGUI, text = "Submit", command = self._submitted).pack()

   def _submitted(self):
      global customGUI
      RunType = self.RunType.get()
      os.system('echo '+RunType+' > /data/local/NWPS/var/test/runtype')
      customGUI.destroy()

weatherman
 
Posts: 9
Joined: Sat Jan 18, 2014 7:29 pm

Re: Tkinter GUI not functioning properly

Postby wuf » Mon Jan 20, 2014 2:49 pm

Hi weatherman

What is 'SmartScript'? Is it Open Source module or package? Is it possible to download? From what internet address?

Here a new setup of your skript. Of course i can't handle your Procedure class because of the missing 'SmartScript'
Code: Select all
#import SmartScript
import os
from os import path
try:
    #~~ For Python 2.x
    import Tkinter as tk
except ImportError:
    #~~ For Python 3.x
    import tkinter as tk

   
APP_WIN_XPOS = 0
APP_WIN_YPOS = 0
APP_WIN_WIDTH = 400
APP_WIN_HEIGHT = 400

CUSTOM_GUI = None

#class Procedure (SmartScript.SmartScript):
    #def __init__(self, dbss):
        #SmartScript.SmartScript.__init__(self, dbss)
   
    #def execute(self, editArea, timeRange, varDict):
        #CUSTOM_GUI = Tk()
        #CUSTOM_GUI.title("Select Run Type")
        #GUIapp = _GUIconfig()
        #CUSTOM_GUI.mainloop()

        #PCBNest = varDict["Panama City Nest:"]
        #CSBNest = varDict["Cape San Blas Nest:"]
        #STMNest = varDict["St. Marks Nest:"]
        #CDKNest = varDict["Cedar Key Nest:"]
        #PCBNest = str(PCBNest)
        #CSBNest = str(CSBNest)
        #STMNest = str(STMNest)
        #CDKNest = str(CDKNest)
     
        #nestarray = [PCBNest, CSBNest, STMNest, CDKNest]
        #for index, item in enumerate(nestarray):
            #if item == "Yes":
                #nestnum = "NEST"+str(index+1)
                #os.system('touch /data/local/NWPS/var/test/%s' % nestnum)
        #self.statusBarMsg("Winds and nests have been sent to NWPS", "U")

class App(object):
    def __init__(self, title):
        # GUI Mainwindow
        self.win = tk.Tk()
        self.win.title(title)
       
        self.win.screen_width = self.win.winfo_screenwidth()
        self.win.screen_height = self.win.winfo_screenheight()

        self.win.geometry('{0}x{1}+{2}+{3}'.format(APP_WIN_WIDTH,
            APP_WIN_HEIGHT, *self.center_win()))
        self.win.protocol("WM_DELETE_WINDOW", self.close)
               
        main_frame = tk.Frame(self.win)
        main_frame.pack(expand=True)

        CUSTOM_GUI = self.win
       
        # GUIconfig
        self.RunType = tk.StringVar()
        ST = tk.Radiobutton(main_frame, text="Short Term", indicatoron=0,
            width=20, variable=self.RunType, value="Short Term")
        ST.pack(fill='x')
       
        LT = tk.Radiobutton(main_frame, text="Long Term", indicatoron=0,
            width=20, variable=self.RunType, value="Long Term")
        LT.pack(fill='x')
       
        submitButton = tk.Button(main_frame, text="Submit",
            command=self._submitted).pack(fill='x')

    def _submitted(self):
        RunType = self.RunType.get()
        os.system('echo '+RunType+' > /data/local/NWPS/var/test/runtype')
        self.close()

    def center_win(self):
      xpos = int((self.win.screen_width - APP_WIN_WIDTH) / 2)
      ypos = int((self.win.screen_height - APP_WIN_HEIGHT) / 2)
      return xpos, ypos
     
    def run(self):
        self.win.mainloop()
   
    def close(self):
        print("Do something before shutdown")
        self.win.destroy()
           
App("My Application").run()

wuf ;)
wuf
 
Posts: 38
Joined: Fri Feb 08, 2013 6:42 am

Re: Tkinter GUI not functioning properly

Postby weatherman » Tue Jan 21, 2014 3:56 am

I appreciate the alternate version of code, I will use some of the suggestions when it comes time to clean up the GUI and make it pretty. Did you happen to pick out any errors in my attached code? My general structure will have to remain intact. I am somewhat limited in what I can do because the main scripts that look for these "Procedures" are root access only on our server. All we can do is make new Procedures. So the def execute is required, and the procedure class is required, but that's about it. Although the GUI needs to be called in the def execute otherwise it runs the second the script is saved. Kinda stinks.
weatherman
 
Posts: 9
Joined: Sat Jan 18, 2014 7:29 pm

Re: Tkinter GUI not functioning properly

Postby wuf » Tue Jan 21, 2014 10:18 am

weatherman wrote:1) The value never gets stored to the variable in the Radiobutton call. I get an empty string when I try to dump it into a file.

The two radiobuttons work together as group. After the initialization of class _GUIconfig no one of these radiobutton will be activated. Now when you press the 'Submit' button without an activated radiiobutton your StringVar RunType does contain just an emty string. That means to have a value to be saved in the file one of these two radiobuttons 'Short Term' or 'Long Term' must be activated. Try to activate one of these two radiobuttons before you press the 'Submit' button. Of course you can activate one of the radiobuttons already by the initialization of the class _GUIconfig with adding following script line:
Code: Select all
self.RunType.set("Short Term")
This should activate the radiobutton 'Short Term'

wuf ;)
wuf
 
Posts: 38
Joined: Fri Feb 08, 2013 6:42 am

Re: Tkinter GUI not functioning properly

Postby weatherman » Tue Jan 21, 2014 12:43 pm

I've been making a selection before clicking submit. I do not want a radio button selected to start.
weatherman
 
Posts: 9
Joined: Sat Jan 18, 2014 7:29 pm

Re: Tkinter GUI not functioning properly

Postby wuf » Tue Jan 21, 2014 1:03 pm

weatherman wrote:I've been making a selection before clicking submit. I do not want a radio button selected to start.
Is this so then the StringVar 'RunType' does contain the name of the activated radiobutton. But you say:
The value never gets stored to the variable in the Radiobutton call
This can't be. Print out the StringVar 'RunType' when you press the 'Submit' Button and call 'def _submitted(self)' for instance with:
Code: Select all
   def _submitted(self):
      global customGUI
      RunType = self.RunType.get()
      print RunType
      os.system('echo '+RunType+' > /data/local/NWPS/var/test/runtype')
      customGUI.destroy()
Check the value which ist printed into the terminal.

wuf ;)
wuf
 
Posts: 38
Joined: Fri Feb 08, 2013 6:42 am

Re: Tkinter GUI not functioning properly

Postby weatherman » Tue Jan 21, 2014 1:59 pm

Now you understand my frustration :D it doesn't make sense. I click the submit button with a choice selected and the variable is empty. Unfortunately I cannot successfully run the program as is from the terminal because the procedure class and execute method are called outside of this script in the depths of the software I'm writing it for. However some additional info is that if I take away the self.RunType.get() and replace it with str(self.RunType), it prints to the file the junk that .get() filters out. So it really passing an empty string.
weatherman
 
Posts: 9
Joined: Sat Jan 18, 2014 7:29 pm

Re: Tkinter GUI not functioning properly

Postby wuf » Tue Jan 21, 2014 2:36 pm

Hi

The following script is my test script which i have altered to check your problem:
Code: Select all
#import SmartScript
import os
from os import path
from Tkinter import *

customGUI = None

#class Procedure (SmartScript.SmartScript):
   #def __init__(self, dbss):
      #SmartScript.SmartScript.__init__(self, dbss)

class Procedure (object):
    def __init__(self, dbss=None):
      pass   
       
    def execute(self, editArea, timeRange, varDict):
   
      global customGUI
      customGUI = Tk()
      customGUI.title("Select Run Type")
      GUIapp = _GUIconfig()
      customGUI.mainloop()

      #global customGUI
      #customGUI = Tk()
      #customGUI.title("Select Run Type")
      #GUIapp = _GUIconfig()
      #customGUI.mainloop()
     
      #PCBNest = varDict["Panama City Nest:"]
      #CSBNest = varDict["Cape San Blas Nest:"]
      #STMNest = varDict["St. Marks Nest:"]
      #CDKNest = varDict["Cedar Key Nest:"]
      #PCBNest = str(PCBNest)
      #CSBNest = str(CSBNest)
      #STMNest = str(STMNest)
      #CDKNest = str(CDKNest)
     
      #nestarray = [PCBNest, CSBNest, STMNest, CDKNest]
      #for index, item in enumerate(nestarray):
         #if item == "Yes":
            #nestnum = "NEST"+str(index+1)
            #os.system('touch /data/local/NWPS/var/test/%s' % nestnum)
      #self.statusBarMsg("Winds and nests have been sent to NWPS", "U")

class _GUIconfig:
   def __init__(self):
      global customGUI
      self.RunType = StringVar()
      ST = Radiobutton(customGUI, text = "Short Term", indicatoron = 0, width = 20, variable = self.RunType, value = "Short Term").pack()
      LT = Radiobutton(customGUI, text = "Long Term", indicatoron= 0, width = 20, variable = self.RunType, value = "Long Term").pack()
      submitButton = Button(customGUI, text = "Submit", command = self._submitted).pack()
      self.RunType.set("Short Term")
     
   def _submitted(self):
      global customGUI
      RunType = self.RunType.get()
      print RunType
      #os.system('echo '+RunType) #' > /data/local/NWPS/var/test/runtype')
      os.system('echo '+RunType) #' > /data/local/NWPS/var/test/runtype')

      customGUI.destroy()

Procedure().execute(None, None, {})
Ok i do not save the selected runtyp into a file. I just echo it to the console. This is working for me.

wuf ;)
wuf
 
Posts: 38
Joined: Fri Feb 08, 2013 6:42 am

Re: Tkinter GUI not functioning properly

Postby weatherman » Wed Jan 22, 2014 1:28 pm

OK! Found the problem. The software running the script has an instance of tkinter running. So where I had:

Code: Select all
RunType = StringVar()


I needed to have:

Code: Select all
RunType = StringVar(master=customGUI)


Then the variable gets passed! Thanks for all the help!
weatherman
 
Posts: 9
Joined: Sat Jan 18, 2014 7:29 pm


Return to GUI

Who is online

Users browsing this forum: John R and 2 guests