简体   繁体   English

SGC GUI 和 Pygame Widget 实现

[英]SGC GUI and Pygame Widget implementation

Hi I am trying to code a simple application with Pygame.嗨,我正在尝试使用 Pygame 编写一个简单的应用程序。 I have made various searches and found that best way to get an user input is to use a 3rd Party GUI.我进行了各种搜索,发现获取用户输入的最佳方式是使用 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我试图从 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.使用您的代码,我添加了 SGC 按钮,该按钮显示在图像上,并在单击时在控制台中显示文本。

I had two problems:我有两个问题:

  • SGC is old and works only with Python 2. For Python 3 it would need relative imports. SGC很旧,只能与 Python 2 一起使用。对于 Python 3,它需要相对导入。 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. time.sleep()是阻塞循环,它检查键/鼠标事件、更新小部件、单击按钮时运行函数等。 sleep使所有 GUI 框架(tkinter、PyQt、wxpython 等)和 PyGame 循环中出现此问题必须一直运行以检查和更新小部件和其他元素。 I use clock to check if it is time to change image.我使用clock来检查是否需要更改图像。 This way loop can works all time and it can update Button when mouse move on button and click it.这种方式循环可以一直工作,并且可以在鼠标移动到按钮上并单击它时更新 Button。

Tested on Python 2.7, Linux Mint 19.2在 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")

在此处输入图片说明

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM