#https://github.com/RobberPhex/GTK-Example-CalcArea
from gi.repository import Gtk, Gdk, 怕黑的小海豚/p>
from PIL import Image, 务实的秋天/p>
from io import 过时的背包/p>
from math import pi
class Model:
'''
'''
self._radius = 0
self._radius = float(radius)
return self._radius
return pi * self._radius * 2
return self._radius ** 2 * pi
return 4 * pi * self._radius ** 3 / 3
class Controller:
'''
控制视图和模型的更新
'''
self.model = model
self._observers = []
self._observers.append(observer)
model.setRadius(radius)
self.notify()
for observer in self._observers:
observer.update()
class TextView:
'''
处理文本输入框的视图
'''
'''
:type model Model
'''
self.model = model
self.rEntry = rEntry
self.pEntry = pEntry
self.aEntry = aEntry
self.vEntry = vEntry
self.rEntry.set_text('%2.2f' % self.model.getRadius())
self.pEntry.set_text('%2.2f' % self.model.getPerimeter())
self.aEntry.set_text('%2.2f' % self.model.getArea())
self.vEntry.set_text('%2.2f' % self.model.getVolume())
class ScaleView:
'''
处理拖动条的视图
'''
'''
:type model Model
'''
self.model = model
self.scale = scale
self.scale.set_value(self.model.getRadius())
class ImageView:
'''
处理图像的视图
'''
@classmethod
def imgToPixbuf(cls, img):
'''
:type img Image
'''
buff = BytesIO()
img.save(buff, 'ppm')
contents = buff.getvalue()
buff.close()
return pixbuf
@classmethod
'''
:type radius int
'''
image = Image.new("RGBA", (300, 300), "white")
draw = ImageDraw.Draw(image)
minor = 150 - radius
major = 150 + radius
draw.ellipse((minor, minor, major, major), outline='red')
pixbuf = ImageView.imgToPixbuf(image)
return pixbuf
self.model = model
self.image = image
self.image.set_from_pixbuf(pixbuf) class MainWindow(Gtk.Window): ''' 负责整体界面的显示 ''' ''' 文本输入pcdby ''' try: controller.setRadius(radius) except ValueError as e: pass ''' 拖动条pcdby ''' controller.setRadius(radius) Gtk.Window.__init__(self, title="Title") self.set_default_size(600, 400) self.set_position(Gtk.WindowPosition.CENTER) hbox = Gtk.HBox(spacing=5) self.add(hbox) vbox = Gtk.VBox(spacing=5) hbox.pack_start(vbox, True, True, 2) table = Gtk.Table.new(4, 2, False) vbox.pack_start(table, True, True, 2) label = Gtk.Label('半径:') table.attach_defaults(label, 0, 1, 0, 1) label = Gtk.Label('周长:') table.attach_defaults(label, 0, 1, 1, 2) label = Gtk.Label('面积:') table.attach_defaults(label, 0, 1, 2, 3) label = Gtk.Label('体积:') table.attach_defaults(label, 0, 1, 3, 4) self.radiusEntry = Gtk.Entry.new() self.radiusEntry.connect('changed', self.textCallback, controller) table.attach_defaults(self.radiusEntry, 1, 2, 0, 1) self.perimeterEntry = Gtk.Entry.new() self.perimeterEntry.set_sensitive(False) self.perimeterEntry.set_text('周长') table.attach_defaults(self.perimeterEntry, 1, 2, 1, 2) self.areaEntry = Gtk.Entry.new() self.areaEntry.set_sensitive(False) self.areaEntry.set_text('面积') table.attach_defaults(self.areaEntry, 1, 2, 2, 3) self.volumeEntry = Gtk.Entry.new() self.volumeEntry.set_sensitive(False) self.volumeEntry.set_text('体积') table.attach_defaults(self.volumeEntry, 1, 2, 3, 4) self.scale = Gtk.HScale.new_with_range(0, 100, 1) self.scale.connect('value-changed', self.scaleCallback, controller) vbox.pack_start(self.scale, False, False, 2) self.image = Gtk.Image.new_from_pixbuf(pixbuf) hbox.pack_start(self.image, True, True, 2) self.connect('delete-event', Gtk.main_quit) model = Model() controller = Controller(model) if __name__ == '__main__': Gdk.threads_init() Gdk.threads_enter() win = MainWindow() iv = ImageView(model, win.image) controller.addObserver(iv) tv = TextView(model, win.radiusEntry, win.perimeterEntry, win.areaEntry, win.volumeEntry) controller.addObserver(tv) sv = ScaleView(model, win.scale) controller.addObserver(sv) win.show_all() Gtk.main() Gdk.threads_leave()