1from gi.repository import Gtk 2import sys 3 4 5class MyWindow(Gtk.ApplicationWindow): 6 7 def __init__(self, app): 8 Gtk.Window.__init__(self, title="Calculator", application=app) 9 self.set_default_size(350, 200) 10 self.set_border_width(10) 11 12 # an entry 13 self.entry = Gtk.Entry() 14 # with an initial text 15 self.entry.set_text('0') 16 # text aligned on the right 17 self.entry.set_alignment(1) 18 # the text in the entry cannot be modified writing in it 19 self.entry.set_can_focus(False) 20 21 # a grid 22 grid = Gtk.Grid() 23 grid.set_row_spacing(5) 24 25 # to attach the entry 26 grid.attach(self.entry, 0, 0, 1, 1) 27 28 # the labels for the buttons 29 buttons = [7, 8, 9, '/', 30 4, 5, 6, '*', 31 1, 2, 3, '-', 32 'C', 0, '=', '+'] 33 34 # each row is a ButtonBox, attached to the grid 35 for i in range(4): 36 hbox = Gtk.ButtonBox.new(Gtk.Orientation.HORIZONTAL) 37 hbox.set_spacing(5) 38 grid.attach(hbox, 0, i + 1, 1, 1) 39 # each ButtonBox has 4 buttons, connected to the callback function 40 for j in range(4): 41 button = Gtk.Button(label=buttons[i * 4 + j]) 42 button.set_can_focus(False) 43 button.connect("clicked", self.button_clicked) 44 hbox.add(button) 45 46 # some variables for the calculations 47 self.first_number = 0 48 self.second_number = 0 49 self.counter = 0 50 self.operation = "" 51 52 # add the grid to the window 53 self.add(grid) 54 55 # callback function for all the buttons 56 def button_clicked(self, button): 57 # for the operations 58 if button.get_label() == '+': 59 self.counter += 1 60 if self.counter > 1: 61 self.do_operation() 62 self.entry.set_text('0') 63 self.operation = "plus" 64 elif button.get_label() == '-': 65 self.counter += 1 66 if self.counter > 1: 67 self.do_operation() 68 self.entry.set_text('0') 69 self.operation = "minus" 70 elif button.get_label() == '*': 71 self.counter += 1 72 if self.counter > 1: 73 self.do_operation() 74 self.entry.set_text('0') 75 self.operation = "multiplication" 76 elif button.get_label() == '/': 77 self.counter += 1 78 if self.counter > 1: 79 self.do_operation() 80 self.entry.set_text('0') 81 self.operation = "division" 82 # for = 83 elif button.get_label() == '=': 84 self.do_operation() 85 self.entry.set_text(str(self.first_number)) 86 self.counter = 1 87 # for Cancel 88 elif button.get_label() == 'C': 89 self.first_number = 0 90 self.second_number = 0 91 self.counter = 0 92 self.entry.set_text('') 93 self.operation = "" 94 # for a digit button 95 else: 96 new_digit = int(button.get_label()) 97 if self.entry.get_text() == 'error': 98 number = 0 99 else: 100 number = int(self.entry.get_text()) 101 number = number * 10 + new_digit 102 if self.counter == 0: 103 self.first_number = number 104 else: 105 self.second_number = number 106 self.entry.set_text(str(number)) 107 108 def do_operation(self): 109 if self.operation == "plus": 110 self.first_number += self.second_number 111 elif self.operation == "minus": 112 self.first_number -= self.second_number 113 elif self.operation == "multiplication": 114 self.first_number *= self.second_number 115 elif self.operation == "division": 116 try: 117 self.first_number /= self.second_number 118 except ZeroDivisionError: 119 self.first_number = 0 120 self.second_number = 0 121 self.counter = 0 122 self.entry.set_text('error') 123 self.operation = "" 124 return 125 else: 126 self.first_number = 0 127 self.second_number = 0 128 self.counter = 0 129 self.entry.set_text('error') 130 131 132class MyApplication(Gtk.Application): 133 134 def __init__(self): 135 Gtk.Application.__init__(self) 136 137 def do_activate(self): 138 win = MyWindow(self) 139 win.show_all() 140 141 def do_startup(self): 142 Gtk.Application.do_startup(self) 143 144app = MyApplication() 145exit_status = app.run(sys.argv) 146sys.exit(exit_status) 147