You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

SFML矩形文本框无法显示的原因及解决方法

问题分析与修复方案

矩形框不显示的原因

  • 你仅在主循环启动前调用了一次window.draw(rectangle),但SFML的渲染是一次性的:每次window.clear()会清空整个窗口画布,之后必须重新绘制所有元素才能保留显示。主循环内没有重复绘制矩形,窗口刷新后矩形自然消失。
  • 矩形默认位置是(0,0),若和文本重叠,即使绘制也可能被遮挡,需要调整两者位置避免重叠。

修复后的完整代码

#include <SFML/Graphics.hpp>
#include <iostream>
#include <cctype>

int main()
{
    sf::RenderWindow window({ 640 ,480}, "Window");

    std::string input_text;
    sf::Font font;
    if (!font.loadFromFile("arial.ttf")) { // 增加字体加载失败判断
        std::cerr << "Failed to load font!" << std::endl;
        return 1;
    }
    sf::Text text("", font);
    text.setCharacterSize(24); // 设置合适字号
    text.setFillColor(sf::Color::Black);

    // 初始化输入框矩形
    sf::RectangleShape rectangle(sf::Vector2f(300, 150)); // 调整合适大小
    rectangle.setPosition(50, 50); // 设置矩形位置,避免边缘/文本重叠
    rectangle.setFillColor(sf::Color(240, 240, 240)); // 浅灰色背景更贴近输入框样式
    rectangle.setOutlineThickness(2);
    rectangle.setOutlineColor(sf::Color(100, 100, 100));

    // 文本放在矩形内部,留10px内边距
    text.setPosition(rectangle.getPosition().x + 10, rectangle.getPosition().y + 10);

    sf::Clock clock;
    static sf::Time text_effect_time;
    static bool show_cursor;

    while (window.isOpen())
    {
        sf::Event event;
        while (window.pollEvent(event))
        {
            if (event.type == sf::Event::Closed)
                window.close();
            else if (event.type == sf::Event::TextEntered) {
                if (std::isprint(event.text.unicode)) {
                    // 预拼接字符,判断是否需要换行
                    std::string temp_text = input_text + static_cast<char>(event.text.unicode);
                    text.setString(temp_text);
                    // 矩形可用宽度 = 总宽度 - 左右内边距总和
                    float available_width = rectangle.getSize().x - 20;
                    if (text.getLocalBounds().width <= available_width) {
                        input_text += event.text.unicode;
                    } else {
                        // 超出范围则插入换行符
                        input_text += '\n' + static_cast<char>(event.text.unicode);
                    }
                }
            }
            else if (event.type == sf::Event::KeyPressed) {
                if (event.key.code == sf::Keyboard::BackSpace) {
                    if (!input_text.empty()) {
                        input_text.pop_back();
                        // 若删除的是换行符,额外再删一次
                        if (!input_text.empty() && input_text.back() == '\n') {
                            input_text.pop_back();
                        }
                    }
                }
                if (event.key.code == sf::Keyboard::Return) {
                    std::cout << input_text << std::endl;
                    input_text.clear(); // 回车后清空输入框
                }
            }
        }

        text_effect_time += clock.restart();
        if (text_effect_time >= sf::seconds(0.5f))
        {
            show_cursor = !show_cursor;
            text_effect_time = sf::Time::Zero;
        }

        // 设置带光标显示的文本
        std::string display_text = input_text + (show_cursor ? "_" : " ");
        text.setString(display_text);

        // 每次循环重新绘制所有元素
        window.clear(sf::Color::White);
        window.draw(rectangle);
        window.draw(text);
        window.display();
    }
    return 0;
}

关键修复点说明

  • 矩形绘制逻辑:把window.draw(rectangle)移到主循环内,放在window.clear()之后、window.draw(text)之前,确保每次窗口刷新都重新绘制矩形。
  • 位置调整:给矩形和文本设置setPosition,让文本显示在矩形内部,避免重叠遮挡。
  • 字体加载判断:增加字体加载失败的错误提示,避免因字体未找到导致文本不显示的隐性问题。

文本自动换行实现思路

  1. 预判断宽度:添加新字符前,先拼接成临时文本,用text.getLocalBounds().width计算文本宽度。
  2. 对比可用范围:将文本宽度和矩形的可用宽度(总宽度减去左右内边距)对比,超出则插入换行符'\n'。
  3. 退格键兼容:删除字符时,若删除的是换行符,额外处理一次,确保换行符被正确移除。

内容的提问来源于stack exchange,提问作者Himanshu

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.19 16:10:31