python计算圆周长、面积、球体体积并画出圆
输入半径,计算圆的周长、面积、球体体积,并画出这个圆。
拖动条、输入框和图像控件的数据保持一致!
fedora下测试通过
#https://github.com/robberphex/gtk-example-calcarea
from gi.repository import gtk, gdk, gdkpixbuf
from pil import image, imagedraw
from io import bytesio
from math import pi
class model:
'''
模型类
存储半径,计算周长、面积、体积
'''
def __init__(self):
self._radius = 0
def setradius(self, radius):
self._radius = float(radius)
def getradius(self):
return self._radius
def getperimeter(self):
return pi * self._radius * 2
def getarea(self):
return self._radius ** 2 * pi
def getvolume(self):
return 4 * pi * self._radius ** 3 / 3
class controller:
'''
控制器类
控制视图和模型的更新
'''
def __init__(self, model):
self.model = model
self._observers = []
def addobserver(self, observer):
self._observers.append(observer)
def setradius(self, radius):
model.setradius(radius)
self.notify()
def notify(self):
for observer in self._observers:
observer.update()
class textview:
'''
文字视图类
处理文本输入框的视图
'''
def __init__(self, model, rentry, pentry, aentry, ventry):
'''
:type model model
'''
self.model = model
self.rentry = rentry
self.pentry = pentry
self.aentry = aentry
self.ventry = ventry
def update(self):
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:
'''
拖动条视图
处理拖动条的视图
'''
def __init__(self, model, scale):
'''
:type model model
'''
self.model = model
self.scale = scale
def update(self):
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()
loader = gdkpixbuf.pixbufloader.new_with_type('pnm')
loader.write(contents)
pixbuf = loader.get_pixbuf()
loader.close()
return pixbuf
@classmethod
def ellipse(cls, radius):
'''
: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
def __init__(self, model, image):
self.model = model
self.image = image
def update(self):
radius = self.model.getradius()
pixbuf = imageview.ellipse(radius)
self.image.set_from_pixbuf(pixbuf)
class mainwindow(gtk.window):
'''
主窗口类
负责整体界面的显示
'''
def textcallback(self, widget, controller):
'''
文本输入回调
'''
try:
radius = float(widget.get_text())
controller.setradius(radius)
except valueerror as e:
pass
def scalecallback(self, widget, controller):
'''
拖动条回调
'''
radius = widget.get_value()
controller.setradius(radius)
def __init__(self):
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)
pixbuf = gdkpixbuf.pixbuf.new(gdkpixbuf.colorspace.rgb, true, 8, 300, 300)
pixbuf.fill(0xaaaaaaaa)
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()
上一篇: pygame实现俄罗斯方块游戏
下一篇: Python 元组(Tuple)操作详解