pygame中的段落输入
Paragraph input in pygame
我尝试使用 pygame 制作一个 python gui 应用程序,但现在我意识到它专门用于游戏而不是常规应用程序......我已经完成了大部分但现在我卡在了我想从用户的段落框中获取输入,但我真的找不到办法做到这一点,真的有办法做到这一点,还是我必须切换到一个完全不同的模块并从头开始
import pygame
pygame.init()
screen = pygame.display.set_mode((600,600))
app_fps = pygame.time.Clock()
bg = pygame.image.load('Moment-Book/GUI/assets/login_bg.jpg')
font = pygame.font.Font(None,32)
active_color = pygame.Color('dodgerblue2')
inactive_color = pygame.Color('white')
back_button = pygame.image.load('Moment-Book/GUI/assets/back_button.png')
class InputBox():
def __init__(self,max_len,x,y,width,height,text = ''):
self.color = inactive_color
self.len = max_len
self.rect = pygame.Rect(x,y,width,height)
self.text = text
self.text_surf = font.render(text,True,self.color)
self.active = False
def event_handler(self,event):
if event.type == pygame.MOUSEBUTTONDOWN:
if self.rect.collidepoint(event.pos):
self.active = not self.active
else:
self.active = False
self.color = active_color if self.active else inactive_color
if event.type == pygame.KEYDOWN:
if self.active:
if event.key == pygame.K_RETURN:
print(self.text)
self.text = ''
elif event.key == pygame.K_BACKSPACE or len(self.text)>self.len:
self.text = self.text[:-1]
else:
self.text += event.unicode
self.text_surf = font.render(self.text,True,self.color)
def draw(self,screen):
screen.blit(self.text_surf, (self.rect.x+5,self.rect.y+5))
pygame.draw.rect(screen,self.color,self.rect,2,border_radius=2)
def update(self):
width = max(200, self.text_surf.get_width()+10)
self.rect.w = width
back_rect = pygame.Rect(30,30,45,45)
def login():
inputbox = InputBox(15,180,305,140,32)
running = True
while running:
for event in pygame.event.get():
if event.type == pygame.QUIT:
pygame.quit()
if event.type == pygame.KEYDOWN:
if event.key == pygame.K_ESCAPE:
running = False
if event.type == pygame.MOUSEBUTTONDOWN:
if back_rect.collidepoint(event.pos):
running = False
inputbox.event_handler(event)
screen.blit(bg,(-167,0))
screen.blit(back_button,(back_rect.topleft,back_rect.bottomleft))
inputbox.draw(screen)
inputbox.update()
pygame.display.update()
app_fps.tick(60)
这是我的登录页面的示例代码,我在其中输入,但它只是用户名和密码,我如何在段落中输入,因为当我尝试这个时,文本会超出屏幕
您必须结合以下问题的答案:
使用文本输入框形式的代码 并使用 中的 drawText
函数渲染纹理。
基于问题代码的最小示例:
import pygame
pygame.init()
screen = pygame.display.set_mode((600,600))
app_fps = pygame.time.Clock()
font = pygame.font.SysFont(None,32)
active_color = pygame.Color('dodgerblue2')
inactive_color = pygame.Color('white')
textAlignLeft = 0
textAlignRight = 1
textAlignCenter = 2
textAlignBlock = 3
def drawText(surface, text, color, rect, font, align=textAlignLeft, aa=False, bkg=None):
lineSpacing = -2
spaceWidth, fontHeight = font.size(" ")[0], font.size("Tg")[1]
listOfWords = text.split(" ")
if bkg:
imageList = [font.render(word, 1, color, bkg) for word in listOfWords]
for image in imageList: image.set_colorkey(bkg)
else:
imageList = [font.render(word, aa, color) for word in listOfWords]
maxLen = rect[2]
lineLenList = [0]
lineList = [[]]
for image in imageList:
width = image.get_width()
lineLen = lineLenList[-1] + len(lineList[-1]) * spaceWidth + width
if len(lineList[-1]) == 0 or lineLen <= maxLen:
lineLenList[-1] += width
lineList[-1].append(image)
else:
lineLenList.append(width)
lineList.append([image])
lineBottom = rect[1]
lastLine = 0
for lineLen, lineImages in zip(lineLenList, lineList):
lineLeft = rect[0]
if align == textAlignRight:
lineLeft += + rect[2] - lineLen - spaceWidth * (len(lineImages)-1)
elif align == textAlignCenter:
lineLeft += (rect[2] - lineLen - spaceWidth * (len(lineImages)-1)) // 2
elif align == textAlignBlock and len(lineImages) > 1:
spaceWidth = (rect[2] - lineLen) // (len(lineImages)-1)
if lineBottom + fontHeight > rect[1] + rect[3]:
break
lastLine += 1
for i, image in enumerate(lineImages):
x, y = lineLeft + i*spaceWidth, lineBottom
surface.blit(image, (round(x), y))
lineLeft += image.get_width()
lineBottom += fontHeight + lineSpacing
if lastLine < len(lineList):
drawWords = sum([len(lineList[i]) for i in range(lastLine)])
remainingText = ""
for text in listOfWords[drawWords:]: remainingText += text + " "
return remainingText
return ""
class InputBox():
def __init__(self,max_len,x,y,width,height,text = ''):
self.color = inactive_color
self.len = max_len
self.rect = pygame.Rect(x,y,width,height)
self.text = text
self.text_surf = font.render(text,True,self.color)
self.active = False
def event_handler(self,event):
if event.type == pygame.MOUSEBUTTONDOWN:
if self.rect.collidepoint(event.pos):
self.active = not self.active
else:
self.active = False
self.color = active_color if self.active else inactive_color
if event.type == pygame.KEYDOWN:
if self.active:
if event.key == pygame.K_RETURN:
self.text = ''
elif event.key == pygame.K_BACKSPACE:
self.text = self.text[:-1]
else:
self.text += event.unicode
def draw(self,screen):
pygame.draw.rect(screen, self.color, self.rect, 1)
drawTextRect = self.rect.inflate(-5, -5)
drawText(screen, self.text, self.color, drawTextRect, font, textAlignLeft, True)
def update(self):
pass
back_rect = pygame.Rect(30,30,45,45)
inputbox = InputBox(15,180,305,140,96)
running = True
while running:
for event in pygame.event.get():
if event.type == pygame.QUIT:
pygame.quit()
inputbox.event_handler(event)
screen.fill(0)
inputbox.update()
inputbox.draw(screen)
pygame.display.update()
app_fps.tick(60)
我尝试使用 pygame 制作一个 python gui 应用程序,但现在我意识到它专门用于游戏而不是常规应用程序......我已经完成了大部分但现在我卡在了我想从用户的段落框中获取输入,但我真的找不到办法做到这一点,真的有办法做到这一点,还是我必须切换到一个完全不同的模块并从头开始
import pygame
pygame.init()
screen = pygame.display.set_mode((600,600))
app_fps = pygame.time.Clock()
bg = pygame.image.load('Moment-Book/GUI/assets/login_bg.jpg')
font = pygame.font.Font(None,32)
active_color = pygame.Color('dodgerblue2')
inactive_color = pygame.Color('white')
back_button = pygame.image.load('Moment-Book/GUI/assets/back_button.png')
class InputBox():
def __init__(self,max_len,x,y,width,height,text = ''):
self.color = inactive_color
self.len = max_len
self.rect = pygame.Rect(x,y,width,height)
self.text = text
self.text_surf = font.render(text,True,self.color)
self.active = False
def event_handler(self,event):
if event.type == pygame.MOUSEBUTTONDOWN:
if self.rect.collidepoint(event.pos):
self.active = not self.active
else:
self.active = False
self.color = active_color if self.active else inactive_color
if event.type == pygame.KEYDOWN:
if self.active:
if event.key == pygame.K_RETURN:
print(self.text)
self.text = ''
elif event.key == pygame.K_BACKSPACE or len(self.text)>self.len:
self.text = self.text[:-1]
else:
self.text += event.unicode
self.text_surf = font.render(self.text,True,self.color)
def draw(self,screen):
screen.blit(self.text_surf, (self.rect.x+5,self.rect.y+5))
pygame.draw.rect(screen,self.color,self.rect,2,border_radius=2)
def update(self):
width = max(200, self.text_surf.get_width()+10)
self.rect.w = width
back_rect = pygame.Rect(30,30,45,45)
def login():
inputbox = InputBox(15,180,305,140,32)
running = True
while running:
for event in pygame.event.get():
if event.type == pygame.QUIT:
pygame.quit()
if event.type == pygame.KEYDOWN:
if event.key == pygame.K_ESCAPE:
running = False
if event.type == pygame.MOUSEBUTTONDOWN:
if back_rect.collidepoint(event.pos):
running = False
inputbox.event_handler(event)
screen.blit(bg,(-167,0))
screen.blit(back_button,(back_rect.topleft,back_rect.bottomleft))
inputbox.draw(screen)
inputbox.update()
pygame.display.update()
app_fps.tick(60)
这是我的登录页面的示例代码,我在其中输入,但它只是用户名和密码,我如何在段落中输入,因为当我尝试这个时,文本会超出屏幕
您必须结合以下问题的答案:
使用文本输入框形式的代码 drawText
函数渲染纹理。
基于问题代码的最小示例:
import pygame
pygame.init()
screen = pygame.display.set_mode((600,600))
app_fps = pygame.time.Clock()
font = pygame.font.SysFont(None,32)
active_color = pygame.Color('dodgerblue2')
inactive_color = pygame.Color('white')
textAlignLeft = 0
textAlignRight = 1
textAlignCenter = 2
textAlignBlock = 3
def drawText(surface, text, color, rect, font, align=textAlignLeft, aa=False, bkg=None):
lineSpacing = -2
spaceWidth, fontHeight = font.size(" ")[0], font.size("Tg")[1]
listOfWords = text.split(" ")
if bkg:
imageList = [font.render(word, 1, color, bkg) for word in listOfWords]
for image in imageList: image.set_colorkey(bkg)
else:
imageList = [font.render(word, aa, color) for word in listOfWords]
maxLen = rect[2]
lineLenList = [0]
lineList = [[]]
for image in imageList:
width = image.get_width()
lineLen = lineLenList[-1] + len(lineList[-1]) * spaceWidth + width
if len(lineList[-1]) == 0 or lineLen <= maxLen:
lineLenList[-1] += width
lineList[-1].append(image)
else:
lineLenList.append(width)
lineList.append([image])
lineBottom = rect[1]
lastLine = 0
for lineLen, lineImages in zip(lineLenList, lineList):
lineLeft = rect[0]
if align == textAlignRight:
lineLeft += + rect[2] - lineLen - spaceWidth * (len(lineImages)-1)
elif align == textAlignCenter:
lineLeft += (rect[2] - lineLen - spaceWidth * (len(lineImages)-1)) // 2
elif align == textAlignBlock and len(lineImages) > 1:
spaceWidth = (rect[2] - lineLen) // (len(lineImages)-1)
if lineBottom + fontHeight > rect[1] + rect[3]:
break
lastLine += 1
for i, image in enumerate(lineImages):
x, y = lineLeft + i*spaceWidth, lineBottom
surface.blit(image, (round(x), y))
lineLeft += image.get_width()
lineBottom += fontHeight + lineSpacing
if lastLine < len(lineList):
drawWords = sum([len(lineList[i]) for i in range(lastLine)])
remainingText = ""
for text in listOfWords[drawWords:]: remainingText += text + " "
return remainingText
return ""
class InputBox():
def __init__(self,max_len,x,y,width,height,text = ''):
self.color = inactive_color
self.len = max_len
self.rect = pygame.Rect(x,y,width,height)
self.text = text
self.text_surf = font.render(text,True,self.color)
self.active = False
def event_handler(self,event):
if event.type == pygame.MOUSEBUTTONDOWN:
if self.rect.collidepoint(event.pos):
self.active = not self.active
else:
self.active = False
self.color = active_color if self.active else inactive_color
if event.type == pygame.KEYDOWN:
if self.active:
if event.key == pygame.K_RETURN:
self.text = ''
elif event.key == pygame.K_BACKSPACE:
self.text = self.text[:-1]
else:
self.text += event.unicode
def draw(self,screen):
pygame.draw.rect(screen, self.color, self.rect, 1)
drawTextRect = self.rect.inflate(-5, -5)
drawText(screen, self.text, self.color, drawTextRect, font, textAlignLeft, True)
def update(self):
pass
back_rect = pygame.Rect(30,30,45,45)
inputbox = InputBox(15,180,305,140,96)
running = True
while running:
for event in pygame.event.get():
if event.type == pygame.QUIT:
pygame.quit()
inputbox.event_handler(event)
screen.fill(0)
inputbox.update()
inputbox.draw(screen)
pygame.display.update()
app_fps.tick(60)