输入半径,计算圆的周长、面积、球体体积,并画出这个圆。
拖动条、输入框和图像控件的数据保持一致!
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)
python计算圆周长,球体体积
《魔兽世界》大逃杀!60人新游玩模式《强袭风暴》3月21日上线
暴雪近日发布了《魔兽世界》10.2.6 更新内容,新游玩模式《强袭风暴》即将于3月21 日在亚服上线,届时玩家将前往阿拉希高地展开一场 60 人大逃杀对战。
艾泽拉斯的冒险者已经征服了艾泽拉斯的大地及遥远的彼岸。他们在对抗世界上最致命的敌人时展现出过人的手腕,并且成功阻止终结宇宙等级的威胁。当他们在为即将于《魔兽世界》资料片《地心之战》中来袭的萨拉塔斯势力做战斗准备时,他们还需要在熟悉的阿拉希高地面对一个全新的敌人──那就是彼此。在《巨龙崛起》10.2.6 更新的《强袭风暴》中,玩家将会进入一个全新的海盗主题大逃杀式限时活动,其中包含极高的风险和史诗级的奖励。
《强袭风暴》不是普通的战场,作为一个独立于主游戏之外的活动,玩家可以用大逃杀的风格来体验《魔兽世界》,不分职业、不分装备(除了你在赛局中捡到的),光是技巧和战略的强弱之分就能决定出谁才是能坚持到最后的赢家。本次活动将会开放单人和双人模式,玩家在加入海盗主题的预赛大厅区域前,可以从强袭风暴角色画面新增好友。游玩游戏将可以累计名望轨迹,《巨龙崛起》和《魔兽世界:巫妖王之怒 经典版》的玩家都可以获得奖励。
更新动态
- 凤飞飞《我们的主题曲》飞跃制作[正版原抓WAV+CUE]
- 刘嘉亮《亮情歌2》[WAV+CUE][1G]
- 红馆40·谭咏麟《歌者恋歌浓情30年演唱会》3CD[低速原抓WAV+CUE][1.8G]
- 刘纬武《睡眠宝宝竖琴童谣 吉卜力工作室 白噪音安抚》[320K/MP3][193.25MB]
- 【轻音乐】曼托凡尼乐团《精选辑》2CD.1998[FLAC+CUE整轨]
- 邝美云《心中有爱》1989年香港DMIJP版1MTO东芝首版[WAV+CUE]
- 群星《情叹-发烧女声DSD》天籁女声发烧碟[WAV+CUE]
- 刘纬武《睡眠宝宝竖琴童谣 吉卜力工作室 白噪音安抚》[FLAC/分轨][748.03MB]
- 理想混蛋《Origin Sessions》[320K/MP3][37.47MB]
- 公馆青少年《我其实一点都不酷》[320K/MP3][78.78MB]
- 群星《情叹-发烧男声DSD》最值得珍藏的完美男声[WAV+CUE]
- 群星《国韵飘香·贵妃醉酒HQCD黑胶王》2CD[WAV]
- 卫兰《DAUGHTER》【低速原抓WAV+CUE】
- 公馆青少年《我其实一点都不酷》[FLAC/分轨][398.22MB]
- ZWEI《迟暮的花 (Explicit)》[320K/MP3][57.16MB]