[Tkinter-discuss] pybwidget dialog bug

Michael Lange klappnase at web.de
Mon Oct 10 22:07:34 CEST 2005


Hello all,

I found a bug in some of pybwidget's dialog classes.
The affected classes are MessageDialog, PasswordDialog, SelectFont and SelectColor;
it seems like there is no way to get the result the dialog box returns.

The problem is the call to Tkinter.Widget.__init__() , which itself calls
Tkinter.BaseWidget.__init__(), where the result of self.tk.call() gets lost.

I tried to avoid this by creating a separate constructor class for these dialogs
where self.tk.call() is called by a separate show() method, which allows to catch the
return value (see the code below).
It's probably not perfect, but as far as I have tried, it seems to work.

However, the resulting syntax looked a little weird to me, so I added shortcut functions
that turn e.g
    
        dialog = SelectFont(master)
        newfont = dialog.show()
resp.:
        newfont = SelectFont(master).show()

into

        newfont = selectfont(master)
.

BTW, the SelectColorMenu() function doesn't seem to work either, however if
I haven't missed something, it is the same as SelectColor(master, type='popup'),
so I'm not sure if it is necessary at all.

Regards

Michael

################################################################################################

class _QuestionDialog(ButtonBox, _Frame):
    '''Internal class for use in dialog boxes that should return the result of the
    corresponding tk command. This is mostly copied from Tkinter.BaseWidget.__init__(),
    but the tk command is only called if explicitely requested by calling self.show().'''
    def __init__(self, master, widgetName, cnf={}, **kw):
        self.widgetName = widgetName
        self.master = master
        if kw:
            self._cnf = Tkinter._cnfmerge((cnf, kw))
        else:
            self._cnf = cnf
        Tkinter.BaseWidget._setup(self, master, self._cnf)
        classes = []
        for k in self._cnf.keys():
            if type(k) is Tkinter.ClassType:
                classes.append((k, self._cnf[k]))
                del self._cnf[k]
                
    def show(self):
        result = self.tk.call((self.widgetName, self._w) + self._options(self._cnf))
        return result


class MessageDialog(_QuestionDialog):
    def __init__(self, master, cnf={}, **kw):
        self._require(master)
        _QuestionDialog.__init__(self, master, "MessageDlg", cnf, **kw)

def messagedialog(master, cnf={}, **kw):
    return MessageDialog(master, cnf, **kw).show()

class PasswordDialog(_QuestionDialog):
    def __init__(self, master, cnf={}, **kw):
        self._require(master)
        _QuestionDialog.__init__(self, master, "PasswdDlg", cnf, **kw)

def passworddialog(master, cnf={}, **kw):
    return PasswordDialog(master, cnf, **kw).show()

class SelectFont(_QuestionDialog):
    def __init__(self, master, cnf={}, **kw):
        _QuestionDialog.__init__(self, master, "SelectFont", cnf, **kw)
        if kw.has_key('type') and kw['type'] == 'toolbar':
            # create the toolbar widget 
            self.show()
    
    def loadfont(self):
        return self.tk.call("SelectFont::loadfont")
    
def selectfont(master, cnf={}, **kw):
    kw['type'] = 'dialog'
    return SelectFont(master, cnf, **kw).show()

class SelectColor(_QuestionDialog):
    def __init__(self, master, cnf={}, **kw):
        _QuestionDialog.__init__(self, master, "SelectColor", cnf, **kw)
    
    def setcolor(self, index, color):
        self.tk.call("SelectColor::setcolor", index, color)

def selectcolor(master, cnf={}, **kw):
    return SelectColor(master, cnf, **kw).show()

#########################################################################################


More information about the Tkinter-discuss mailing list