python計算圓周長、面積、球體體積並畫出圓

來源:互聯網
上載者:User
輸入半徑,計算圓的周長、面積、球體體積,並畫出這個圓。
拖動條、輸入框和影像控制的資料保持一致!

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()



  • 相關文章

    聯繫我們

    該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

    如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

    A Free Trial That Lets You Build Big!

    Start building with 50+ products and up to 12 months usage for Elastic Compute Service

    • Sales Support

      1 on 1 presale consultation

    • After-Sales Support

      24/7 Technical Support 6 Free Tickets per Quarter Faster Response

    • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.