def onPi(self):
self.calc.text.set(self.calc.eval.runstring('pi'))
if name == 'main':
root = Tk()
button(root, TOP, 'Quit', root.quit)
CalcGuiPlus(**getCalcArgs()).mainloop() # -bg,-fg to calcgui
Because PyCalc is coded as a Python class, you can always achieve a similar effect by
extending PyCalc in a new subclass instead of embedding it, as shown in
Example 19-23.
Example 19-23. PP4E\Lang\Calculator\calculator_plus_ext.py
"""
#############################################################################
a customization with an extra row of buttons for common operations;
a more useful customization: adds buttons for more operations (sqrt,
1/x, etc.) by subclassing to extend the original class, not embedding;
new buttons show up before frame attached to bottom by calcgui class;
#############################################################################
"""
from tkinter import *
from calculator import CalcGui, getCalcArgs
from PP4E.Gui.Tools.widgets import label, frame, button
class CalcGuiPlus(CalcGui):
def makeWidgets(self, args):
label(self, TOP, 'PyCalc Plus - Subclass')
CalcGui.makeWidgets(self, args)
frm = frame(self, BOTTOM)
extras = [('sqrt', 'sqrt(%s)'),
('x^2 ', '(%s)2'),
('x^3 ', '(%s)3'),
('1/x ', '1.0/(%s)')]
for (lab, expr) in extras:
button(frm, LEFT, lab, (lambda expr=expr: self.onExtra(expr)))
button(frm, LEFT, ' pi ', self.onPi)
def onExtra(self, expr):
try:
self.text.set(self.eval.runstring(expr % self.text.get()))
except:
self.text.set('ERROR')
def onPi(self):
self.text.set(self.eval.runstring('pi'))
if name == 'main':
CalcGuiPlus(**getCalcArgs()).mainloop() # passes -bg, -fg on
Notice that these buttons’ callbacks force floating-point division to be used for inverses
just because that’s how / operates in Python 3.X (// for integers truncates remainders
1478 | Chapter 19: Text and Language