【问题标题】:How to limit how many characters in input boxes Pygame?Pygame如何限制输入框中的字符数?
【发布时间】:2021-06-26 04:07:10
【问题描述】:

嗨,所以我想限制矩形内的文本,如果文本超过矩形的尺寸,那么它会缩小自身以适应。我使用类来使代码更易于阅读并更容易添加更多输入框。当我运行代码时,应该有不同的输入框,我可以在其中编辑文本,如果文本太长,它会缩小自身(最后一个字符)以适合输入框。但是当我运行代码时,文本可以超过矩形 1 个字符,之后的任何字母都会删除一整块文本。这是代码。

'''python

import pygame
import datetime

pygame.init()
clock = pygame.time.Clock()
pygame.font.init()

# Note
finish = 0
leftover = 16

# Font
numb_font = pygame.font.Font('dogicapixelbold.ttf', 14)
text_font = pygame.font.Font('dogicapixelbold.ttf', 16)

color = (233, 248, 215)
active = False

# screen resolution
Width = 800
Height = 600
bg = pygame.image.load('opennote.png')
screen = pygame.display.set_mode((Width, Height))

# Time
time_box = pygame.Rect(250, 63, 50, 30)
date_box = pygame.Rect(221, 27, 50, 30)
# boxes numb
leftover_box = pygame.Rect(265, 105, 30, 30)
finish_box = pygame.Rect(325, 105, 30, 30)


class InputBox:

    def __init__(self, x, y, w, h, text=''):
        self.rect = pygame.Rect(x, y, w, h)
        self.color = color
        self.text = text
        self.txt_surface = text_font.render(text, True, self.color)
        self.active = False

    def handle_event(self, event):
        if event.type == pygame.MOUSEBUTTONDOWN:
            # If the user clicked on the input_box rect.
            if self.rect.collidepoint(event.pos):
                # Toggle the active variable.
                self.active = not self.active
            else:
                self.active = False
        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:
                    self.text = self.text[:-1]
                else:
                    self.text += event.unicode
                # Re-render the text.
                self.txt_surface = text_font.render(self.text, True, self.color)

    def draw(self, screen):
        # Blit the text.
        screen.blit(self.txt_surface, (self.rect.x+5, self.rect.y+10))
        # Blit the rect.
        pygame.draw.rect(screen, self.color, self.rect, 2)

    def update(self):
        # Limit character
        if self.txt_surface.get_width() > self.rect.w:
            self.text = self.text[:-1]


def main():
    clock = pygame.time.Clock()
    input_box1 = InputBox(115, 170, 250, 36)
    input_box2 = InputBox(115, 224, 250, 36)
    input_box3 = InputBox(115, 278, 250, 36)
    input_box4 = InputBox(115, 333, 250, 36)
    input_box5 = InputBox(115, 386, 250, 36)
    input_box6 = InputBox(115, 440, 250, 36)
    input_box7 = InputBox(115, 494, 250, 36)
    input_boxes = [input_box1, input_box2, input_box3, input_box4, input_box5, input_box6, input_box7]
    done = False

    while not done:
        # Background
        screen.fill((0, 0, 0))
        screen.blit(bg, (0, 0))
        now = datetime.datetime.now()
        date_now = now.strftime("%d/%m/%Y")
        time_now = now.strftime("%H:%M:%S")
        for event in pygame.event.get():
            if event.type == pygame.QUIT:
                done = True
            for box in input_boxes:
                box.handle_event(event)

        for box in input_boxes:
            box.update()

        for box in input_boxes:
            box.draw(screen)
            # Real Time
            # Date
        pygame.draw.rect(screen, 'white', date_box, -1)
        datebox_surface = numb_font.render(date_now, True, color)
        screen.blit(datebox_surface, (date_box.x + 5, date_box.y + 5))
        # Time
        pygame.draw.rect(screen, 'white', time_box, -1)
        timebox_surface = numb_font.render(time_now, True, color)
        screen.blit(timebox_surface, (time_box.x + 5, time_box.y + 5))

        # finish &Leftover
        # finish box
        pygame.draw.rect(screen, 'white', finish_box, -1)
        finishbox_surface = numb_font.render(str(finish), True, color)
        screen.blit(finishbox_surface, finish_box)
        # Leftover box
        pygame.draw.rect(screen, 'white', leftover_box, -1)
        leftover_box_surface = numb_font.render(str(leftover), True, color)
        screen.blit(leftover_box_surface, leftover_box)

        pygame.display.update()
        clock.tick(120)


if __name__ == '__main__':
    main()
    pygame.quit()

'''

但是当字母超出矩形宽度时,它会删除一大堆文本,而不仅仅是宽度之外的字母。

【问题讨论】:

  • 您没有提供可能的测试点,因此我们无法真正帮助您:/
  • 我在那里更新了代码:3

标签: python python-3.x pygame


【解决方案1】:

切换您的更新并重新渲染内容。

    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:
                self.text = self.text[:-1]
            else:
                self.text += event.unicode
                # Limit characters           -20 for border width
                if self.txt_surface.get_width() > self.rect.w -20:
                    self.text = self.text[:-1]

def draw(self, screen):
    # Blit the text.
    screen.blit(self.txt_surface, (self.rect.x+5, self.rect.y+10))
    # Blit the rect.
    pygame.draw.rect(screen, self.color, self.rect, 2)

def update(self):
    # Re-render the text.
    self.txt_surface = text_font.render(self.text, True, self.color)


编辑:哦,现在是凌晨 3 点;我现在快睡着了,如果我错过了发布一些我不记得的编辑过的东西。不得不将背景换成一个纯黑色的矩形,然后将其 blit 以进行测试,但我可以肯定它在这里运行良好。下载相同的字体和一切。这就是它的样子。

#! /usr/bin/env python3

import pygame
import datetime

pygame.init()
clock = pygame.time.Clock()
pygame.font.init()

# Note
finish = 0
leftover = 16

# Font
numb_font = pygame.font.Font('dogicapixelbold.ttf', 14)
text_font = pygame.font.Font('dogicapixelbold.ttf', 16)

color = (233, 248, 215)
active = False

# screen resolution
Width = 800
Height = 600
bg = pygame .Surface( [Width,  Height] )
pygame .draw .rect( bg,  (0, 0, 0),  [0,  0,  Width,  Height] )
##  bg = pygame.image.load('opennote.png')
screen = pygame.display.set_mode((Width, Height))

# Time
time_box = pygame.Rect(250, 63, 50, 30)
date_box = pygame.Rect(221, 27, 50, 30)
# boxes numb
leftover_box = pygame.Rect(265, 105, 30, 30)
finish_box = pygame.Rect(325, 105, 30, 30)


class InputBox:

    def __init__(self, x, y, w, h, text=''):
        self.rect = pygame.Rect(x, y, w, h)
        self.color = color
        self.text = text
        self.txt_surface = text_font.render(text, True, self.color)
        self.active = False

    def handle_event(self, event):
        if event.type == pygame.MOUSEBUTTONDOWN:
            # If the user clicked on the input_box rect.
            if self.rect.collidepoint(event.pos):
                # Toggle the active variable.
                self.active = not self.active
            else:
                self.active = False
        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:
                    self.text = self.text[:-1]
                else:
                    self.text += event.unicode
                    # Limit characters           -20 for border width
                    if self.txt_surface.get_width() > self.rect.w -20:
                        self.text = self.text[:-1]

    def draw(self, screen):
        # Blit the text.
        screen.blit(self.txt_surface, (self.rect.x+5, self.rect.y+10))
        # Blit the rect.
        pygame.draw.rect(screen, self.color, self.rect, 2)

    def update(self):
        # Re-render the text.
        self.txt_surface = text_font.render(self.text, True, self.color)


def main():
    clock = pygame.time.Clock()
    input_box1 = InputBox(115, 170, 250, 36)
    input_box2 = InputBox(115, 224, 250, 36)
    input_box3 = InputBox(115, 278, 250, 36)
    input_box4 = InputBox(115, 333, 250, 36)
    input_box5 = InputBox(115, 386, 250, 36)
    input_box6 = InputBox(115, 440, 250, 36)
    input_box7 = InputBox(115, 494, 250, 36)
    input_boxes = [input_box1, input_box2, input_box3, input_box4, input_box5, input_box6, input_box7]
    done = False

    while not done:
        # Background
        screen.fill((0, 0, 0))
        screen.blit(bg, (0, 0))
        now = datetime.datetime.now()
        date_now = now.strftime("%d/%m/%Y")
        time_now = now.strftime("%H:%M:%S")
        for event in pygame.event.get():
            if event.type == pygame.QUIT:
                done = True
            for box in input_boxes:
                box.handle_event(event)

        for box in input_boxes:
            box.update()

        for box in input_boxes:
            box.draw(screen)
            # Real Time
            # Date
        pygame.draw.rect(screen, 'white', date_box, -1)
        datebox_surface = numb_font.render(date_now, True, color)
        screen.blit(datebox_surface, (date_box.x + 5, date_box.y + 5))
        # Time
        pygame.draw.rect(screen, 'white', time_box, -1)
        timebox_surface = numb_font.render(time_now, True, color)
        screen.blit(timebox_surface, (time_box.x + 5, time_box.y + 5))

        # finish &Leftover
        # finish box
        pygame.draw.rect(screen, 'white', finish_box, -1)
        finishbox_surface = numb_font.render(str(finish), True, color)
        screen.blit(finishbox_surface, finish_box)
        # Leftover box
        pygame.draw.rect(screen, 'white', leftover_box, -1)
        leftover_box_surface = numb_font.render(str(leftover), True, color)
        screen.blit(leftover_box_surface, leftover_box)

        pygame.display.update()
        clock.tick(120)


if __name__ == '__main__':
    main()
    pygame.quit()

【讨论】:

  • 嗨,当它碰到边界时,它仍然会吃掉一堆文本
  • 很确定所有更改的内容是将这些行 # Limit characters# Re-render the text. 翻转。在那之前是吃角色的。您可以尝试使用纯色背景表面,看看是否对它有任何影响。
猜你喜欢
  • 2020-12-01
  • 2012-01-29
  • 2011-02-27
  • 1970-01-01
  • 2011-04-02
  • 1970-01-01
  • 1970-01-01
  • 2019-04-13
相关资源
最近更新 更多