SGC GUI和Pygame Widget实现 [英] SGC GUI and Pygame Widget implementation

查看:38
本文介绍了SGC GUI和Pygame Widget实现的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在尝试使用Pygame编写一个简单的应用程序.我进行了各种搜索,发现获得用户输入的最佳方法是使用3rd Party GUI.

我已经找到了用于此目的的简单游戏代码.在下面,您可以找到我的基本代码,它在脚本的相同路径内查找图像,并在屏幕上按顺序替换它们.

但是我没有这种应用程序的经验.我想从SGC的文档中了解:

Hi I am trying to code a simple application with Pygame. I have made various searches and found that best way to get an user input is to use a 3rd Party GUI.

I have found Simple Game Code for this aim. Below, you can find my base code, it looks for the images inside same path of script and replaces them in order at screen.

But I have no experience with this kind of applications. I am trying to understand from the documentation of SGC: https://github.com/codetricity/sgc/blob/master/example/test.py

It is not an easy task for me. I could develop this far, my code is running. But I couldn't understand the button implementation part.

Can you help me implement a "Scale Widget" at beginning to get user input between a range of integers. Also, a "Button Widget" to pass starting screen and begin my main code I will share with you.

Thanks for your time

import glob
import time
import numpy as np
import timeit
import pygame
import sgc 
from sgc.locals import *

start = timeit.default_timer()

maxnote = 10
maxduration = 10

pygame.init()

white = (255, 255, 255) 

path = r'C:\Path'

mylistname = [f for f in sorted(glob.glob("*.png"))]
mylistpath = [f for f in sorted(glob.glob(path + "/*.png"))]

for i in range(len(mylistname)):

    mylistname[i] = mylistname[i].replace(".png", "")
    mylistname[i] = mylistname[i].replace("h", ".")
    mylistname[i] = float(mylistname[i])

imgname = []

for i in range(len(mylistname)):
    imgname.append(str("img" + str(mylistname[i])))

imglist = []

for i in range(len(mylistpath)):

    name = str(imgname[i])
    name = pygame.image.load(mylistpath[i]) 
    imglist.append(name)

current_image = 0

display_surface = pygame.display.set_mode((400, 400)) 

while (timeit.default_timer() - start < maxduration) | (current_image < maxnote):
#for imj in range(len(imglist)+1):

    print(str(current_image) + "s")

    if current_image < len(imglist):
        print(str(current_image) + "0")

        while True:

            print(str(current_image) + "p")
            display_surface.fill(white)
            display_rect = display_surface.get_rect()    
            image_rect = imglist[current_image].get_rect()     
            image_rect.center = display_rect.center
            display_surface.blit(imglist[current_image],image_rect)
            pygame.display.update()
            pygame.display.flip()

            time.sleep(5)

            current_image = current_image + 1
            print(str(current_image) + "n")

            break
    else:

        font = pygame.font.Font('freesansbold.ttf', 32) 
        text = font.render('GeeksForGeeks', True, (0, 255, 0), (0, 0, 128))
        textRect = text.get_rect()
        textRect.center = display_rect.center
        display_surface.blit(text, textRect)
        pygame.display.update()
        pygame.display.flip()
        time.sleep(5)

        pygame.display.quit()

print("the end")

解决方案

Using your code I added SGC button which is displayed on images and it display text in console when it is clicked.

I had two problems:

  • SGC is old and works only with Python 2. For Python 3 it would need relative imports. But later it may need other changes.

  • time.sleep() was blocking loop which checks key/mouse events, updates widgets, runs function when button is clicked, etc. sleep makes this problem with all GUI frameworks (tkinter, PyQt, wxpython, etc.) and in PyGame loop which has to run all time to check and update widgets and other elements. I use clock to check if it is time to change image. This way loop can works all time and it can update Button when mouse move on button and click it.

Tested on Python 2.7, Linux Mint 19.2


import glob
import pygame
import time

import sgc 
from sgc.locals import *

# --- constants --- (UPPER_CASE)

WHITE = (255, 255, 255) 

MAXNOTE = 10
MAXDURATION = 10

PATH = r'C:\Path'

# --- functions --- (lower_case_names)

def on_click_button():
    print('on_click_button')

# ---  main ---

filenames = sorted(glob.glob(PATH + "/*.png"))

print('len:', len(filenames))

names = []
images = []
for item in filenames:
    names.append("img" + item.replace(".png", "").replace("h", "."))
    images.append(pygame.image.load(item))

current_image = 0

# --- 

pygame.init()

display_surface = sgc.surface.Screen((400, 400))
#display_surface = pygame.display.set_mode((400, 400)) 
display_rect = display_surface.get_rect()    

font = pygame.font.Font('freesansbold.ttf', 32) 

# add button 
btn = sgc.Button(label="Clicky", pos=(10, 10))#, label_font=font)
btn.add(0)

# assign function to button
btn.on_click = on_click_button

# ---

clock = pygame.time.Clock()

current_time = pygame.time.get_ticks()
end_time = current_time + MAXDURATION*1000
end_slide = current_time

running = True
while running and ((current_time < end_time) or (current_image < MAXNOTE)):

    ticks = clock.tick(30)

    for event in pygame.event.get():

        # send events to SGC so it can check if button was clicke
        sgc.event(event)

        if event.type == pygame.QUIT:
            running = False
        elif event.type == pygame.KEYDOWN:
            if event.key == pygame.K_ESCAPE:
               running = False

    current_time = pygame.time.get_ticks()

    if (end_slide <= current_time) and (current_image < len(images)):
        image = images[current_image]
        image_rect = image.get_rect()     
        image_rect.center = display_rect.center

        end_slide = current_time + 2000 # 2000ms (2s)
        current_image += 1

        display_surface.fill(WHITE)
        display_surface.blit(image, image_rect)

    # draw all widgets    
    sgc.update(ticks)

    pygame.display.flip() # doesn't need pygame.display.update() because both do the same 

# ---

display_surface.fill(WHITE)

text = font.render('GeeksForGeeks', True, (0, 255, 0), (0, 0, 128))
text_rect = text.get_rect()
text_rect.center = display_rect.center
display_surface.blit(text, text_rect)

#pygame.display.update() # no need it
pygame.display.flip()

time.sleep(5)

# --- end ---

pygame.display.quit()

print("the end")

这篇关于SGC GUI和Pygame Widget实现的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆