先来复习一下之前写的两个例程:
1. 绘制网格线
import pyglet
window = pyglet.window.Window(800, 600)
color = (255, 255, 255, 255) # 白色
lines = []
for y in range(0, window.height, 40):
lines.append(pyglet.shapes.Line(0, y, window.width, y, color=color))
for x in range(0, window.width, 40):
lines.append(pyglet.shapes.Line(x, 0, x, window.height, color=color))
@window.event
def on_draw():
window.clear()
for line in lines:
line.draw()
pyglet.app.run()
2. 模拟按钮
import pyglet
window = pyglet.window.Window(800, 600)
GRAY = (220, 220, 220, 255)
BLACK = (0, 0, 0, 255)
RED = (255, 0, 0, 255)
pattern = pyglet.image.SolidColorImagePattern(color=GRAY)
image = pattern.create_image(100,50)
button1 = pyglet.sprite.Sprite(image, 280, 200)
button2 = pyglet.sprite.Sprite(image, 280+150, 200)
labelb1 = pyglet.text.Label('按钮1', font_size=16, x=305, y=216, color=BLACK)
labelb2 = pyglet.text.Label('按钮2', font_size=16, x=455, y=216, color=BLACK)
message = pyglet.text.Label('', font_size=16, x=20, y=16)
widgets = [message]
widgets.extend([button1, button2, labelb1, labelb2])
@window.event
def on_draw():
window.clear()
for widget in widgets:
widget.draw()
@window.event
def on_mouse_press(x, y, button, modifier):
X, Y, W, H = button1.x, button1.y, button1.width, button1.height
if x in range(X,X+W+1) and y in range(Y,Y+H+1):
message.text = '你点击了按钮1'
elif x in range(X+150,X+W+151) and y in range(Y,Y+H+1):
message.text = '你点击了按钮2'
@window.event
def on_mouse_motion(x, y, dx, dy):
X, Y, W, H = button1.x, button1.y, button1.width, button1.height
if x in range(X,X+W+1) and y in range(Y,Y+H+1):
labelb1.color = RED
elif x in range(X+150,X+W+151) and y in range(Y,Y+H+1):
labelb2.color = RED
else:
labelb1.color = BLACK
labelb2.color = BLACK
pyglet.app.run()
以上两个例程,都使用了控件列表,然后在on_draw事件中遍历,基本上实现了“批处理”画图的功能。但是,实现上pyglet库本身就带有这种批处理功能,这就是各个控件都带有的batch参数。看一个pyglet自带的实例:
import pyglet
from pyglet import shapes
window = pyglet.window.Window(960, 540)
batch = pyglet.graphics.Batch()
circle = shapes.Circle(700, 150, 100, color=(50, 225, 30), batch=batch)
square = shapes.Rectangle(200, 200, 200, 200, color=(55, 55, 255), batch=batch)
rectangle = shapes.Rectangle(250, 300, 400, 200, color=(255, 22, 20), batch=batch)
rectangle.opacity = 128
rectangle.rotation = 33
line = shapes.Line(100, 100, 100, 200, width=19, batch=batch)
line2 = shapes.Line(150, 150, 444, 111, width=4, color=(200, 20, 20), batch=batch)
star = shapes.Star(800, 400, 60, 40, num_spikes=20, color=(255, 255, 0), batch=batch)
@window.event
def on_draw():
window.clear()
batch.draw()
pyglet.app.run()
是不是更简单,使用了pyglet.graphics.Batch()对象,把需要一起画的控件都装进Batch()里,然后再一起画出来。与以下代码的效果是一样的,但省掉了widgets元组和遍历过程,还是原生的批处理参数batch更简单。
import pyglet
from pyglet import shapes
window = pyglet.window.Window(960, 540)
circle = shapes.Circle(700, 150, 100, color=(50, 225, 30))
square = shapes.Rectangle(200, 200, 200, 200, color=(55, 55, 255))
rectangle = shapes.Rectangle(250, 300, 400, 200, color=(255, 22, 20))
rectangle.opacity = 128
rectangle.rotation = 33
line = shapes.Line(100, 100, 100, 200, width=19)
line2 = shapes.Line(150, 150, 444, 111, width=4, color=(200, 20, 20))
star = shapes.Star(800, 400, 60, 40, num_spikes=20, color=(255, 255, 0))
widgets = circle, square, rectangle, line, line2, star
@window.event
def on_draw():
window.clear()
for batch in widgets:
batch.draw()
pyglet.app.run()
接下来说说group分组参数,先看一个实例:
import pyglet
window = pyglet.window.Window(800, 500 , caption='Batch&Group')
batch = pyglet.graphics.Batch() # 创建一个Batch对象
group = [pyglet.graphics.Group(i) for i in range(4)] # 创建一组Group对象
circle1 = pyglet.shapes.Circle(x=250, y=250, radius=80, color=(255, 0, 0, 255), batch=batch, group=group[0])
rectangle1 = pyglet.shapes.Rectangle(x=150, y=200, width=200, height=100, color=(0, 0, 255, 255), batch=batch, group=group[1])
circle2 = pyglet.shapes.Circle(x=550, y=250, radius=80, color=(255, 0, 0, 255), batch=batch, group=group[3])
rectangle2 = pyglet.shapes.Rectangle(x=450, y=200, width=200, height=100, color=(0, 0, 255, 255), batch=batch, group=group[2])
@window.event
def on_draw():
window.clear()
batch.draw() # 在窗口上绘制batch中的所有图形对象
pyglet.app.run()
运行效果:
group参数主要用于控制控件的显示顺序,与pyglet.graphics.Group(order=i)配合使用,这里order数值越大越在上层,越小则越在下层。当然group除了排序的功能,还有包括同组绑定纹理、着色器或设置任何其他参数的功能,这些功能以后再安排学习。
到此已基本了解pyglet控件参数batch和group的用法,再来看一下graphics.Batch和graphics.Group的自带说明:
class Batch
class Group
最后,使用Batch()修改一下之前两个例程:
import pyglet
window = pyglet.window.Window(800, 600, caption='绘制网络线')
color = (255, 255, 255, 255)
lines = pyglet.graphics.Batch()
for y in range(0, window.height, 40):
exec(f'y{y//40} = pyglet.shapes.Line(0, y, window.width, y, color=color, batch=lines)')
for x in range(0, window.width, 40):
exec(f'x{x//40} = pyglet.shapes.Line(x, 0, x, window.height, color=color, batch=lines)')
@window.event
def on_draw():
window.clear()
lines.draw()
pyglet.app.run()
import pyglet
window = pyglet.window.Window(800, 600, caption='按钮模拟')
GRAY = (220, 220, 220, 255)
BLACK = (0, 0, 0, 255)
RED = (255, 0, 0, 255)
batch = pyglet.graphics.Batch()
pattern = pyglet.image.SolidColorImagePattern(color=GRAY)
image = pattern.create_image(100,50)
button1 = pyglet.sprite.Sprite(image, 280, 200, batch = batch)
button2 = pyglet.sprite.Sprite(image, 280+150, 200, batch = batch)
labelb1 = pyglet.text.Label('按钮1', font_size=16, x=305, y=216, color=BLACK, batch = batch)
labelb2 = pyglet.text.Label('按钮2', font_size=16, x=455, y=216, color=BLACK, batch = batch)
message = pyglet.text.Label('', font_size=16, x=20, y=16, batch = batch)
@window.event
def on_draw():
window.clear()
batch.draw()
@window.event
def on_mouse_press(x, y, button, modifier):
X, Y, W, H = button1.x, button1.y, button1.width, button1.height
if x in range(X,X+W+1) and y in range(Y,Y+H+1):
message.text = '你点击了按钮1'
elif x in range(X+150,X+W+151) and y in range(Y,Y+H+1):
message.text = '你点击了按钮2'
@window.event
def on_mouse_motion(x, y, dx, dy):
X, Y, W, H = button1.x, button1.y, button1.width, button1.height
if x in range(X,X+W+1) and y in range(Y,Y+H+1):
labelb1.color = RED
elif x in range(X+150,X+W+151) and y in range(Y,Y+H+1):
labelb2.color = RED
else:
labelb1.color = BLACK
labelb2.color = BLACK
pyglet.app.run()
完。