так что я работаю с SFML здесь, и я в основном хочу сделать строку из введенных букв. В SFML есть встроенная функция для проверки нажатия клавиш внутри окна, а также для определения, является ли она чем-то конкретным, например, символом возврата, поэтому я хотел скомбинировать их, чтобы сделать возможным ввод и возврат строки (так как без определения возврата, он ничего не сделает, если вы нажмете на него).
Вот мой код:
#include <iostream>
#include "SFML/Window.hpp"#include <vector>
using namespace std;
using namespace sf;
int main() {
// Initializes the class and creates the window
Window window;
window.create(VideoMode(800, 600), "Test window", Style::Close | Style::Titlebar | Style::Resize);
// Run while the window is open
vector <char> sentence;
while (window.isOpen()) {
Event event;
// Check if an event is triggered
while (window.pollEvent(event)) {
// If the event is to close it, close it
if (event.type == Event::Closed) {
window.close();
}
// If the backspace key is pressed
else if (event.type == Event::KeyPressed) {
if (event.key.code == Keyboard::BackSpace) {
sentence.pop_back();
}
}
// If text is entered in the window
else if (event.type == Event::TextEntered) {
sentence.push_back(static_cast <char> (event.text.unicode));
cout << "Sentence = ";
for (int i = 0; i < sentence.size(); i++) {
cout << sentence[i];
}
cout << endl;
}
}
}
return 0;
}
По сути, он создает окно, затем проверяет, закрыто ли оно, и затем проверяет, была ли нажата клавиша возврата, и затем проверяет, не была ли нажата клавиша возврата, но была ли другая клавиша.
И поэтому все это прекрасно работает в моей среде IDE (сообщество Visual Studio 2017), однако, когда я нажимаю клавишу Backspace более одного раза (это работает в первый раз), он не удаляет символ.
Я предполагаю, что это происходит из-за того, что событие не очищается, но это не имеет смысла, поскольку вы все равно можете делать такие вещи, как закрытие окна после нажатия клавиши Backspace и тому подобное. Почему это только вызывает возврат if
function
один раз, даже если вы нажмете его несколько раз?
Backspace — это тоже персонаж, даже если он невидим. Таким образом, когда вы нажимаете клавишу Backspace, он удаляет последний символ из буфера и добавляет в буфер невидимый символ.
Таким образом, вы должны игнорировать символ возврата на TextEntered
событие.
Кроме того, вам нужна проверка на всплывающее окно, поэтому вы не пытаетесь всплыть, когда нет элемента.
Вот моя обновленная версия вашего кода.
#include <iostream>
#include <SFML/Graphics.hpp>
void print_scentence(const std::vector<char>& sentence) {
std::cout << "Sentence = ";
for (auto c : sentence)
{
std::cout << c;
}
std::cout << "\n";
}
int main() {
// Initializes the class and creates the window
sf::Window window;
window.create(sf::VideoMode(800, 600), "Test window", sf::Style::Close | sf::Style::Titlebar | sf::Style::Resize);
// Run while the window is open
std::vector<char> sentence;
while (window.isOpen()) {
sf::Event event;
// Check if an event is triggered
while (window.pollEvent(event)) {
// If the event is to close it, close it
if (event.type == sf::Event::Closed) {
window.close();
}
// If the backspace key is pressed
else if (event.type == sf::Event::KeyPressed) {
if (event.key.code == sf::Keyboard::BackSpace && !sentence.empty()) {
sentence.pop_back();
print_scentence(sentence);
}
}
// If text is entered in the window
else if (event.type == sf::Event::TextEntered) {
if (event.text.unicode == 8) {
continue;
}
sentence.push_back(static_cast<char>(event.text.unicode));
print_scentence(sentence);
}
}
}
}
Как видно из кода, я рекомендую не использовать using namespace
, используйте range-base для цикла, чтобы перебрать вектор и использовать \n
вместо std::endl
, так как вы хотите новую строку, а не принудительный сброс.
Кроме того, если вы не собираетесь использовать OpenGL напрямую или использовать дескриптор окна другим способом, вы, вероятно, захотите использовать sf::RenderWindow
вместо.
Других решений пока нет …