Tkinter Dialog Management problems:

M

Michael Yanowitz

Hello:

Below I have included a stripped down version of the GUI I am working on.
It contains 2 dialog boxes - one main and one settings. It has the following
problems, probably all related, that I am hoping someone knows what I am
doing wrong:

1) Pressing the Settings.. Button multiple times, brings up many instances
of the Settings Panel. I just want it to bring up one. Is there an easy
way to do that?

2) Pressing the Done button in the Settings Panel, just erases the Done
button
(and any other widgets in the Panel). It does not dismiss the Panel.
Pressing
the X button does work. What callback is that? Can I make the Done button
call
that instead? How?

3) Pressing the Done button from the Main Panel has no effect? Why not? It
used
to work (self.quit()). Again, I would like to call whatever is called
when the
X button (top Right corner) is pressed.

Thanks in advance:

"""
TkInter Test
"""

#********** Imports *********************************************

import os
import sys
import Tkinter
from Tkinter import Tk, Frame, Button, Label, Entry, Scrollbar
from Tkinter import Text, Checkbutton, IntVar
import tkFileDialog
from tkMessageBox import askyesno, showerror


# ******* runScript() *************************************
def runScript (strFilename):
""" Executes Python script file """
if (VERBOSE):
print strFilename, "is being imported"
fileText = ""
try:
fptr = open (strFilename, 'r')
fileText = fptr.read()
fptr.close()
except Exception, (errno):
print "Exception in import of file:", strFilename, "- Errno = ",
errno
print (sys.exc_info())
showerror ('Error', 'Problem importing file - see console for
details')
else:
fname = [strFilename[:-3].split('/')[-1]]
for f in fname:
__import__(f)


# ******* getGUIFilename *******************************************
def getGUIFilename():
"""
returns a tkInter File Selection Dialog
"""
strFilename = tkFileDialog.askopenfilename(initialdir='.',
filetypes=[('Python
files','*.py'),
('All Files','*.*')])
return strFilename

# ******* ScenarioPlayerDialog class *************************************
class ScriptDialog(Frame):
""" Script Dialog GUI class """
def __init__(self, parent=None):
""" Script GUI class constructor """
Frame.__init__(self, parent)
self.pack()

self.commandRow = Frame(self)
self.commandLabel = Label(self.commandRow, width=14,
text="Python Command:")
self.commandEnt = Entry(self.commandRow)
self.commandRow.pack(side=Tkinter.TOP, fill=Tkinter.X)
self.commandLabel.pack(side=Tkinter.LEFT)
self.commandEnt.pack(side=Tkinter.RIGHT, expand=Tkinter.YES,
fill=Tkinter.X)
self.commandEnt.delete('0', Tkinter.END)
self.commandEnt.pack(side=Tkinter.TOP, fill=Tkinter.X)

buttonRow3 = Frame(self)
doneBtn = Button(buttonRow3, text='Done', command=self.done)
doneBtn.pack(side=Tkinter.RIGHT)
buttonRow3.pack(side=Tkinter.BOTTOM, expand=Tkinter.YES,
fill=Tkinter.X)
buttonRow2 = Frame(self)
runBtn = Button(buttonRow2, text='Run Script',
command=self.playScript)
runBtn.pack(side=Tkinter.LEFT)
buttonRow2.pack(side=Tkinter.BOTTOM, expand=Tkinter.YES,
fill=Tkinter.X)
buttonRow1 = Frame(self)
executeBtn = Button(buttonRow1, text='Execute Command')
executeBtn.pack(side=Tkinter.LEFT)
settingsBtn = Button(buttonRow1, text='Settings...',
command=self.editSettings)
settingsBtn.pack(side=Tkinter.LEFT)
self.verbose = Tkinter.IntVar()
Checkbutton(self,text="Verbose",variable=self.verbose,
command=self.setVerbosity).pack(side=Tkinter.RIGHT)
buttonRow1.pack(side=Tkinter.BOTTOM, expand=Tkinter.YES,
fill=Tkinter.X)
self.pack(expand=Tkinter.YES, fill=Tkinter.BOTH)
self.theParent = parent
def setVerbosity(self):
""" Callback called when the 'Verbose' RadioButton is pressed """
global VERBOSE
VERBOSE = self.verbose.get()
def playScript(self):
""" Callback called when the 'Run Script' button is pressed """
sFilename = getGUIFilename()
if (VERBOSE):
print "Running script file: ", sFilename
runScript (sFilename)
def editScript(self):
""" Callback called when the 'Edit Script' button is pressed """
sFilename = getGUIFilename()
editScript (sFilename)
def executeCommand(self):
""" Callback called when the 'Execute Command' button is pressed """
strCommand = self.commandEnt.get()
if (VERBOSE):
print strCommand, "is being executed"
exec (strCommand)
def editSettings(self):
""" Callback called when the 'Edit Settings' button is pressed """
win = Tkinter.Toplevel()
settingsDlg = SettingsDialog (win)
def done(self):
""" Callback called when the 'Done' button is pressed """
self.quit()

# ******** start() ************************************************
def start():
"""
Start the Script Dialog GUI
"""
rootWindow = Tkinter.Tk()
rootWindow.title('Script Player - Version L1.0')
ScriptDialog (rootWindow)
rootWindow.mainloop()

# ******* SocketSettingsDialog class *********************************
class SettingsDialog(Frame):
""" Setttings Dialog GUI class """
def __init__(self, parent=None):
""" Settings Dialog GUI class constructor """
Frame.__init__(self, parent)
self.pack()
buttonRow2 = Frame(self)
self.theWidget = self
doneBtn = Button(buttonRow2, text='Done', command=self.destroy)
doneBtn.pack(side=Tkinter.RIGHT)
buttonRow2.pack(side=Tkinter.TOP, expand=Tkinter.YES,
fill=Tkinter.X)
self.pack(expand=Tkinter.YES, fill=Tkinter.BOTH)
def done(self):
""" Callback called when the 'Done' button is pressed """
self.destroy()

start()
 
E

Eric Brunel

Hello:

Below I have included a stripped down version of the GUI I am working
on.
It contains 2 dialog boxes - one main and one settings. It has the
following
problems, probably all related, that I am hoping someone knows what I am
doing wrong:

1) Pressing the Settings.. Button multiple times, brings up many
instances
of the Settings Panel. I just want it to bring up one. Is there an
easy
way to do that?

In fact, the two windows you created are not dialogs; they're just
windows. To turn a window into an actual "dialog", i.e basically to make
it modal, you have to do the following operations (supposing your dialog
window is named dlg and your main window in named root):

## Ensure only window can receive user events
dlg.grab_set()
## Force Dialog to stay on top of main window
dlg.transient(root)
## Wait for dialog to be destroyed
root.wait_window(dlg)
2) Pressing the Done button in the Settings Panel, just erases the Done
button
(and any other widgets in the Panel). It does not dismiss the Panel.
Pressing
the X button does work. What callback is that? Can I make the Done
button
call
that instead? How?

This is not the way it works. In fact, what you did wrong is something
that has been around for years in some Tkinter tutorial(s): you made your
classes inherit from Frame. This is a Bad Idea: a Frame is not a window,
but only a generic container. There are 2 classes for windows: Tk for the
main window and Toplevel for all others. They both also act as containers,
so you can do in them everything you do in Frames. So make your
ScriptDialog inherit from Tk, your SettingsDialog inherit from Toplevel,
remove all explicit creations of Tkinter.Tk or Tkinter.Toplevel and
instantiate your classes instead. Then calling destroy on either on the
dialogs will actually close the window.
3) Pressing the Done button from the Main Panel has no effect? Why not?
It
used
to work (self.quit()). Again, I would like to call whatever is called
when the
X button (top Right corner) is pressed.

This should work. BTW, your "done" method is not needed: creating the
Button with command=self.quit works without problem.

HTH
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Similar Threads


Members online

Forum statistics

Threads
473,968
Messages
2,570,149
Members
46,695
Latest member
StanleyDri

Latest Threads

Top