【问题标题】:How to insert a slider in Pygame?如何在 Pygame 中插入滑块?
【发布时间】:2022-01-15 21:00:07
【问题描述】:

我目前正在 Python 上进行物理模拟,使用 Pygame 模拟室内的气体云。 我的问题是我无法在我的代码中插入一个工作滑块来更改参数的值。 我有一个运行模拟的“运行时”循环,当我想在其中插入一个工作滑块时,模拟停止。我不能同时使用模拟和滑块。

下面是滑块的代码:

#!/usr/bin/python
import os
import pygame, sys
from pygame.locals import *

# set window size
width = 640
height = 100

# initilaise pygame
pygame.init()
windowSurfaceObj = pygame.display.set_mode((width,height),1,16)
redColor = pygame.Color(255,0,0)
blackColor = pygame.Color(0,0,0)

#starting position
x = 100
pygame.draw.rect(windowSurfaceObj,redColor,Rect(x,5,10,90))
pygame.display.update(pygame.Rect(0,0,width,height))

s = 0
while s == 0:
    button = pygame.mouse.get_pressed()
    if button[0] != 0:
       pos = pygame.mouse.get_pos()
       x = pos[0]
       y = pos[1]
       a = x - 5
       if a < 0:
          a = 0
       pygame.draw.rect(windowSurfaceObj,blackColor,Rect(0,0,width,height))
       #pygame.display.update(pygame.Rect(0,0,width,height))
       pygame.draw.rect(windowSurfaceObj,redColor,Rect(a,5,10,90))
       pygame.display.update(pygame.Rect(0,0,width,height))


   # check for ESC key pressed, or pygame window closed, to quit
    for event in pygame.event.get():
       if event.type == QUIT:
          pygame.quit()
          sys.exit()
       elif event.type == KEYDOWN:
          if event.key == K_ESCAPE:
             pygame.quit()
             sys.exit()

【问题讨论】:

    标签: python slider pygame


    【解决方案1】:

    您可以复杂地使用响应鼠标事件的矩形和圆形创建自己的滑块,但我建议您改用 Kivy 滑块。

    【讨论】:

      【解决方案2】:

      滑块代码对我来说似乎很好,并且可以在我的计算机上运行。模拟代码是否在单独的 while 循环中?如果是这样,您必须将两个循环合二为一,因为滑块循环永远不会中断。

      例如,如果滑块控制增长率,您可以这样写并将气体云绘制到windowSurfaceObj。为使其正常工作,您可以使windowSurfaceObj 更大,并为滑块和气体云设置两个单独的表面。在这种情况下,您将绘制到单独的表面并将单独的表面blit 到windowSurfaceObj。您还必须进行碰撞检测以确定鼠标是否在滑块内单击。

      # imports and Pygame initialization here
      
      a = 0
      size_of_gas_cloud = 30
      
      while True:
      
          if pygame.mouse.get_pressed()[0] != 0:
              # collision detection also needed here
              a = pygame.mouse.get_pos()[0] - 5
              if a < 0:
                  a = 0
      
          size_of_gas_cloud += a
      
          pygame.draw.rect(windowSurfaceObj, blackColor, Rect(0, 0, width, height))
          pygame.draw.rect(windowSurfaceObj, redColor, Rect(a, 5, 10, 90))
          pygame.display.update()
      
          # Pygame event loop here
      

      【讨论】:

      • 问题是,如果我在主循环中组合滑块循环,模拟不会开始:只有滑块循环处于活动状态并且永远不会结束。如何将滑块循环集成到我的模拟中而不会卡在滑块循环中?感谢您的回答
      • 为了让这个与 Pygame 一起工作,你应该只有一个循环,所有的模拟逻辑、鼠标事件处理和屏幕绘制都在其中发生。请参阅示例。此外,一切都必须发生在一个窗口中。您是否要制作一个带有滑块的弹出窗口?我认为这不适用于 Pygame。您可以通过编写自己的小部件来完成这项工作,但 Malik Brahimi 的回答中提到的库也值得考虑。
      【解决方案3】:

      我以自己的方式改进了原始代码。这里是。它是这样构建的,因此您只需使用两行代码来定义循环中的滑块(一行用于初始化它 (sliderInit()),另一行用于执行它 (slier()))。

      import pygame
      import sys
      from pygame.locals import *
      
      pygame.init()
      screen = pygame.display.set_mode((1920, 1080))
      # screen = pygame.display.set_mode((0, 0), pygame.FULLSCREEN)
      screenColor = (255,255,255)
      screen.fill(screenColor)
      pygame.display.update(pygame.Rect(0,0,1920,1080))
      
      def slider(sx,sy,action,width,height,buttonColor,sliderColor,buttonBorderThickness,sliderBorderThickness,buttonWidth,sliderBarHeight,maxValue):
          if mouse[0] > sx and mouse[0] < sx+width and mouse[1] > sy and mouse[1] < sy+height:
              if click[0] == 1:
                  mouseX = mouse[0] - 5
                  if mouseX < sx:
                      mouseX = sx
                  elif mouseX > sx+width-buttonWidth:
                      mouseX = sx+width-buttonWidth
                  pygame.draw.rect(screen,screenColor,(sx,sy,width,height))
                  pygame.draw.rect(screen,sliderColor,(sx,sy+height/2-sliderBarHeight/2,width,sliderBarHeight))
                  pygame.draw.rect(screen,buttonColor,(mouseX,sy,buttonWidth,height))
                  if buttonBorderThickness != 0:
                      pygame.draw.rect(screen,(0,0,0),(mouseX,sy,buttonWidth,height),buttonBorderThickness)
                  if sliderBorderThickness != 0:
                      pygame.draw.rect(screen,(0,0,0),(sx,sy+height/2-sliderBarHeight/2,width,sliderBarHeight),sliderBorderThickness)
                  pygame.display.update(pygame.Rect(sx,sy,width,height))
                  
                  if action == "test1":
                      sliderValue = (mouseX-sx)/((width-buttonWidth)/maxValue)
                      print("test1:")
                      print(sliderValue)
                  elif action == "test2":
                      sliderValue = (mouseX-sx)/((width-buttonWidth)/maxValue)
                      print("test2:")
                      print(sliderValue)
      
      def sliderInit(sx,sy,width,height,buttonColor,sliderColor,buttonBorderThickness,sliderBorderThickness,buttonWidth,sliderBarHeight,maxValue,startValue):
              pygame.draw.rect(screen,screenColor,(sx,sy,width,height))
              pygame.draw.rect(screen,sliderColor,(sx,sy+height/2-sliderBarHeight/2,width,sliderBarHeight))
              pygame.draw.rect(screen,buttonColor,(sx+startValue*((width-buttonWidth)/maxValue),sy,buttonWidth,height))
              if buttonBorderThickness != 0:
                  pygame.draw.rect(screen,(0,0,0),(sx+startValue*((width-buttonWidth)/maxValue),sy,buttonWidth,height),buttonBorderThickness)
              if sliderBorderThickness != 0:
                  pygame.draw.rect(screen,(0,0,0),(sx,sy+height/2-sliderBarHeight/2,width,sliderBarHeight),sliderBorderThickness)
              pygame.display.update(pygame.Rect(sx,sy,width,height))
      
      firstLoop = True
      
      while True:
          for event in pygame.event.get():
              if event.type == pygame.QUIT:
                  pygame.quit()
                  sys.exit()
          elif event.type == KEYDOWN:
              if event.key == K_ESCAPE:
                  pygame.quit()
                  sys.exit()
          mouse = pygame.mouse.get_pos()
          click = pygame.mouse.get_pressed()
          
          if firstLoop == True:
              sliderInit(100,50,1000,50,(255,255,255),(220,220,220),1,0,25,10,100,50)
              sliderInit(100,120,1000,50,(255,255,255),(220,220,220),1,0,25,10,100,50)
              firstLoop = False
          
          slider(100,50,"test1",1000,50,(255,255,255),(220,220,220),1,0,25,10,100)
          slider(100,120,"test2",1000,50,(255,255,255),(220,220,220),1,0,25,10,100)
      

      这里也是创建一个有 10 个步骤的滑块的代码。

      import pygame
      import sys
      from pygame.locals import *
      
      pygame.init()
      screen = pygame.display.set_mode((1920, 1080))
      # screen = pygame.display.set_mode((0, 0), pygame.FULLSCREEN)
      screenColor = (255,255,255)
      screen.fill(screenColor)
      pygame.display.update(pygame.Rect(0,0,1920,1080))
      
      def slider(sx,sy,width,height,action,
                     buttonColor,buttonBorderThickness,buttonWidth,
                     sliderBarColor,sliderBarBorderThickness,sliderBarHeight,
                     sliderStepColor,sliderStepBorderThickness,sliderStepWidth,sliderStepHeight,sliderStepSnap,
                     maxValue):
          
          if mouse[0] > sx and mouse[0] < sx+width and mouse[1] > sy and mouse[1] < sy+height:
              if click[0] == 1:
                  mouseX = mouse[0] - 5
                  if mouseX < sx+sliderStepSnap:
                      mouseX = sx
                  
                  elif mouseX > (round(sx+10*((width)/100))-sliderStepSnap) and mouseX < (round(sx+10*((width)/100))+sliderStepSnap):
                      mouseX = round(sx+10*((width)/100)-buttonWidth/2)
                  elif mouseX > (round(sx+20*((width)/100))-sliderStepSnap) and mouseX < (round(sx+20*((width)/100))+sliderStepSnap):
                      mouseX = round(sx+20*((width)/100)-buttonWidth/2) 
                  elif mouseX > (round(sx+30*((width)/100))-sliderStepSnap) and mouseX < (round(sx+30*((width)/100))+sliderStepSnap):
                      mouseX = round(sx+30*((width)/100)-buttonWidth/2)
                  elif mouseX > (round(sx+40*((width)/100))-sliderStepSnap) and mouseX < (round(sx+40*((width)/100))+sliderStepSnap):
                      mouseX = round(sx+40*((width)/100)-buttonWidth/2)
                  elif mouseX > (round(sx+50*((width)/100))-sliderStepSnap) and mouseX < (round(sx+50*((width)/100))+sliderStepSnap):
                      mouseX = round(sx+50*((width)/100)-buttonWidth/2)
                  elif mouseX > (round(sx+60*((width)/100))-sliderStepSnap) and mouseX < (round(sx+60*((width)/100))+sliderStepSnap):
                      mouseX = round(sx+60*((width)/100)-buttonWidth/2)
                  elif mouseX > (round(sx+70*((width)/100))-sliderStepSnap) and mouseX < (round(sx+70*((width)/100))+sliderStepSnap):
                      mouseX = round(sx+70*((width)/100)-buttonWidth/2)
                  elif mouseX > (round(sx+80*((width)/100))-sliderStepSnap) and mouseX < (round(sx+80*((width)/100))+sliderStepSnap):
                      mouseX = round(sx+80*((width)/100)-buttonWidth/2)
                  elif mouseX > (round(sx+90*((width)/100))-sliderStepSnap) and mouseX < (round(sx+90*((width)/100))+sliderStepSnap):
                      mouseX = round(sx+90*((width)/100)-buttonWidth/2)
                  
                  elif mouseX > sx+width-buttonWidth-sliderStepSnap:
                      mouseX = sx+width-buttonWidth
                  
                  pygame.draw.rect(screen,screenColor,(sx,sy,width,height))
                  
                  for i in range(1,10):
                      pygame.draw.rect(screen,sliderStepColor,(round(sx+i*10*((width)/100)),sy+(height-sliderStepHeight)/2,sliderStepWidth,sliderStepHeight))
                      if sliderStepBorderThickness != 0:
                          pygame.draw.rect(screen,(0,0,0),(round(sx+i*10*((width)/100)),sy+(height-sliderStepHeight)/2,sliderStepWidth,sliderStepHeight),sliderStepBorderThickness)
                  pygame.draw.rect(screen,sliderBarColor,(sx,sy+height/2-sliderBarHeight/2,width,sliderBarHeight))
                  
                  pygame.draw.rect(screen,buttonColor,(mouseX,sy,buttonWidth,height))
                  if buttonBorderThickness != 0:
                      pygame.draw.rect(screen,(0,0,0),(mouseX,sy,buttonWidth,height),buttonBorderThickness)
                  if sliderBarBorderThickness != 0:
                      pygame.draw.rect(screen,(0,0,0),(sx,sy+height/2-sliderBarHeight/2,width,sliderBarHeight),sliderBarBorderThickness)
                  pygame.display.update(pygame.Rect(sx,sy,width,height))
                  
                  if action == "test1":
                      sliderValue = (mouseX-sx)/((width-buttonWidth)/maxValue)
                      print("test1:")
                      print(sliderValue)
                  elif action == "test2":
                      sliderValue = (mouseX-sx)/((width-buttonWidth)/maxValue)
                      print("test2:")
                      print(sliderValue)
      
      def sliderInit(sx,sy,width,height,
                     buttonColor,buttonBorderThickness,buttonWidth,
                     sliderBarColor,sliderBarBorderThickness,sliderBarHeight,
                     sliderStepColor,sliderStepBorderThickness,sliderStepWidth,sliderStepHeight,
                     maxValue,startValue):
              
              pygame.draw.rect(screen,screenColor,(sx,sy,width,height))
              
              for i in range(1,10):
                  pygame.draw.rect(screen,sliderStepColor,(round(sx+i*10*((width)/100)),sy+(height-sliderStepHeight)/2,sliderStepWidth,sliderStepHeight))
                  if sliderStepBorderThickness != 0:
                      pygame.draw.rect(screen,(0,0,0),(round(sx+i*10*((width)/100)),sy+(height-sliderStepHeight)/2,sliderStepWidth,sliderStepHeight),sliderStepBorderThickness)
              pygame.draw.rect(screen,sliderBarColor,(sx,sy+height/2-sliderBarHeight/2,width,sliderBarHeight))
          
              pygame.draw.rect(screen,buttonColor,(sx+startValue*((width-buttonWidth)/maxValue),sy,buttonWidth,height))
              if buttonBorderThickness != 0:
                  pygame.draw.rect(screen,(0,0,0),(sx+startValue*((width-buttonWidth)/maxValue),sy,buttonWidth,height),buttonBorderThickness)
              if sliderBarBorderThickness != 0:
                  pygame.draw.rect(screen,(0,0,0),(sx,sy+height/2-sliderBarHeight/2,width,sliderBarHeight),sliderBorderThickness)
              pygame.display.update(pygame.Rect(sx,sy,width,height))
      
      firstLoop = True
      
      while True:
          for event in pygame.event.get():
              if event.type == pygame.QUIT:
                  pygame.quit()
                  sys.exit()
              elif event.type == KEYDOWN:
                  if event.key == K_ESCAPE:
                      turnOffMotors()
                      pygame.quit()
                      sys.exit()
          mouse = pygame.mouse.get_pos()
          click = pygame.mouse.get_pressed()
          
          if firstLoop == True:
              sliderInit(100,50,1000,50,
                     (255,255,255),1,25,
                     (220,220,220),0,10,
                     (0,0,0),0,5,40,
                     100,50)
              sliderInit(100,120,1000,50,
                     (255,255,255),1,25,
                     (220,220,220),0,10,
                     (0,0,0),0,5,40,
                     100,50)
              firstLoop = False
          
          slider(100,50,1000,50,"test1",
                 (255,255,255),1,25,
                 (220,220,220),0,10,
                 (0,0,0),0,5,40,30,
                 100)
          slider(100,120,1000,50,"test2",
                 (255,255,255),1,25,
                 (220,220,220),0,10,
                 (0,0,0),0,5,40,30,
                 100)
      

      【讨论】:

        【解决方案4】:

        我做了一个滑块,用作背景音乐的音量控制器

        我做了一个滑块,用作背景音乐的音量控制器

        class Slider:
            def __init__(self, x, y, w, h):
                self.circle_x = x
                self.volume = 0
                self.sliderRect = pg.Rect(x, y, w, h)
        
            def draw(self, screen):
                pg.draw.rect(screen, (255, 255, 255), self.sliderRect)
                pg.draw.circle(screen, (255, 240, 255), (self.circle_x, (self.sliderRect.h / 2 + self.sliderRect.y)), self.sliderRect.h * 1.5)
        
            def get_volume(self):
                return self.volume
        
            def set_volume(self, num):
                self.volume = num
        
            def update_volume(self, x):
                if x < self.sliderRect.x:
                    self.volume = 0
                elif x > self.sliderRect.x + self.sliderRect.w:
                    self.volume = 100
                else:
                    self.volume = int((x - self.sliderRect.x) / float(self.sliderRect.w) * 100)
        
            def on_slider(self, x, y):
                if self.on_slider_hold(x, y) or self.sliderRect.x <= x <= self.sliderRect.x + self.sliderRect.w and self.sliderRect.y <= y <= self.sliderRect.y + self.sliderRect.h:
                    return True
                else:
                    return False
        
            def on_slider_hold(self, x, y):
                if ((x - self.circle_x) * (x - self.circle_x) + (y - (self.sliderRect.y + self.sliderRect.h / 2)) * (y - (self.sliderRect.y + self.sliderRect.h / 2)))\
                       <= (self.sliderRect.h * 1.5) * (self.sliderRect.h * 1.5):
                    return True
                else:
                    return False
        
            def handle_event(self, screen, x):
                if x < self.sliderRect.x:
                    self.circle_x = self.sliderRect.x
                elif x > self.sliderRect.x + self.sliderRect.w:
                    self.circle_x = self.sliderRect.x + self.sliderRect.w
                else:
                    self.circle_x = x
                self.draw(screen)
                self.update_volume(x)
                print(self.volume)
        

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 2021-10-16
          • 2019-08-02
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2021-01-13
          相关资源
          最近更新 更多