クラスを正しく使用しているかどうかはわかりません。pygame を使用して簡単なメニューを作成しようとしています。これは、GUI に関する私の最初の進出です。コードを構成する方法がわかりません。
マウス オーバー/マウス クリックのすべてを処理する一般的な Button クラスを作成し、それをボタンごとにサブクラス化し、do_action
メソッドをオーバーライドして各ボタンに特定のアクションを与えることができることがわかりました。
class Button(pygame.sprite.Sprite):
global screen_flags
def __init__(self, images, pos):
pygame.sprite.Sprite.__init__(self)
self.images = images
self.image = images[0]
self.rect = self.image.get_rect()
self.rect.move_ip(pos)
def update(self, events, surface):
# if not screen_flags['config']:
for event in events:
if event.type == MOUSEMOTION:
if self.rect.collidepoint(event.pos):
self.image = self.images[1]
else:
self.image = self.images[0]
elif event.type == MOUSEBUTTONDOWN:
if event.button == 1 and self.rect.collidepoint(event.pos):
self.image = self.images[-1]
screen_flags['config'] = 1
self.do_action()
self.set_flag()
elif event.type == MOUSEBUTTONUP:
self.image = self.images[0]
screen.blit(self.image, self.rect)
def do_action(self):
pass
def set_flag(self):
pass
class CheckBox(Button):
def __init__(self, images, pos):
Button.__init__(self, images, pos)
self.is_clicked = False
def update(self, events, surface):
for event in events:
if event.type == MOUSEMOTION:
if not self.is_clicked:
if self.rect.collidepoint(event.pos):
self.image = self.images[1]
else:
self.image = self.images[0]
elif event.type == MOUSEBUTTONDOWN:
if event.button == 1 and self.rect.collidepoint(event.pos):
if not self.is_clicked:
self.image = self.images[-1]
self.is_clicked = True
else:
self.image = self.images[0]
self.is_clicked = False
screen.blit(self.image, self.rect)
class Cancel(Button):
def do_action(self):
screen_flags['config'] = 0
ご覧のとおり、彼らはまだ何もしていません。チェックボックスのオンとオフを切り替えたり、1 つの「構成」ウィンドウを開いたり閉じたりすることはできますが、それは私の知る限りです。コードの残りの部分:
global count
global sTime
config_button_img = load_sliced_images(25, 25, c_buttons)
config_button = Button(config_button_img, (608,4))
input_bar = load_sliced_images(351,33, inpt_bar)
text_box = Textbox(input_bar, (144,155))
s_button = load_sliced_images(110,32, sbmt_bttn)
submit = Button(s_button, (241,301))
c_button = load_sliced_images(110,32, cncl_bttn)
cancel = Cancel(c_button, (385, 301))
c_boxes = load_sliced_images(20,19, chk_box)
check_box = CheckBox(c_boxes, (200,200))
try:
while True:
# ****************************
# Pygame section
events = pygame.event.get()
for event in events:
if event.type == QUIT:
screen_flags['alert'] = 1
ding.play(0,1000)
elif event.type == MOUSEBUTTONDOWN:
text_box.set_focus(event.button, event.pos)
screen.blit(background, (0,0))
screen.blit(client_logo, (0,30))
screen.blit(tag, (174,462))
if screen_flags['config']:
screen.blit(config_window_img, (0,0))
submit.update(events, screen)
cancel.update(events, screen)
check_box.update(events, screen)
if screen_flags['alert']:
screen.blit(alert_dialog, (0,0))
config_button.update(events, screen)
pygame.display.update()
except KeyboardInterrupt:
try:
pygame.quit()
except:
pass
したがって、これは期待どおりに機能します。ここからどこへ行けばいいのかわからない。クラス内にロジックをラップし続けますか? たとえば、次にやろうとしているのは、「キャンセル」ボタンをクリックするとチェックボックスのチェックが外れるようにすることです。
Cancel
まさにそれを行うためにクラスを変更してみました。
class Cancel(Button):
def do_action(self):
screen_flags['config'] = 0
check_box.is_clicked=False
ただし、これにより GlobalName エラーが発生します。別のクラス内からインスタンス メソッドをターゲットにするにはどうすればよいですか? これは正しい方法ですか?update()
または、マウスを処理するためのものなど、いくつかのロジックのみを使用して、さまざまなクラスとの間で変数をやり取りすることでクラスが行うmain()
ことを処理しますか? すべてのクラスでグローバル変数を使用する必要がありますか?
GUI の実践に関する良い記事はありますか。コードの構造などのようなもの..?
うまくいけば、上記は理にかなっています。