问题描述
我的程序中有一个 RectangleShape,它应该显示在某处,但由于某种原因,该 RectangleShape 没有显示。程序中没有错误,只是 RectangleShape 没有显示。我有三个文件:main.cpp、button.h 和 textBox.h。 RectangleShape 在 textBox.h 头文件中声明。以下是文件:
main.cpp
#include <SFML/Graphics.hpp>
#include <iostream>
#include <windows.h>
#include "button.h"
#include "textBox.h"
using namespace std;
using namespace sf;
static const float viewHeight = 500.f;
void resizeView(const RenderWindow &window,View &view){
float aspectRatio = float(window.getSize().x) / float(window.getSize().y);
view.setSize(viewHeight * aspectRatio,viewHeight);
}
int main(){
View view(Vector2f(0.f,0.f),Vector2f(viewHeight,viewHeight));
Event event;
bool isstartOpen = false;
RenderWindow window(VideoMode(500,500),"Operating System",Style::Close | Style::Resize);
RectangleShape player(Vector2f(500.0f,30.0f));
RectangleShape startmenu(Vector2f(300.0f,400.0f));
Texture startTexture;
if(!startTexture.loadFromFile("startButton.png")){
MessageBox(NULL,"Error loading image file: startButton.png in the system","Image File Error",MB_OK | MB_ICONERROR);
}
startmenu.setFillColor(Color(0,200));
startmenu.setPosition(0.0f,500.0f);
player.setFillColor(Color::Black);
player.setPosition(0.0f,473.0f);
Font font;
if(!font.loadFromFile("Calibri Regular.ttf")){
MessageBox(NULL,"Error loading font file: buttonFont.ttf in the system","Font File Error",MB_OK | MB_ICONERROR);
}
TextBox passCreate(15,Color::Black,false,Color::White,4,{100,100});
Button openNotepad("Notepad",{90,90},14,Color::Green,startTexture,font);
Button opencalc("Calculator",font);
Button startButton("",{30,30},20,font);
startButton.setPosition({0,473});
openNotepad.setPosition({0,500});
opencalc.setPosition({0,500});
passCreate.setFont(font);
passCreate.setPosition({100,100});
passCreate.setLimit(true,10);
while (window.isopen())
{
if(Keyboard::isKeypressed(Keyboard::Return)){
passCreate.setSelected(true);
}else if(Keyboard::isKeypressed(Keyboard::Escape)){
passCreate.setSelected(false);
}
while (window.pollEvent(event))
{
switch(event.type){
case Event::Resized:
resizeView(window,view);
break;
case Event::TextEntered:
passCreate.typedOn(event);
break;
case Event::Closed:
window.close();
cout << "Window has been removed" << endl;
break;
case Event::MouseMoved:
if(openNotepad.isMouSEOver(window)){
openNotepad.setBackColor(Color(42,150,83));
openNotepad.setoutThick(1.5f);
openNotepad.setoutColor(Color(255,255,170));
}else{
openNotepad.setBackColor(Color(0,110,51));
openNotepad.setoutThick(0);
}if(opencalc.isMouSEOver(window)){
opencalc.setBackColor(Color(42,83));
opencalc.setoutThick(1.5f);
opencalc.setoutColor(Color(255,170));
}else{
opencalc.setBackColor(Color(0,51));
opencalc.setoutThick(0);
}if(startButton.isMouSEOver(window)){
startButton.setBackColor(Color(1,159,255));
}else{
startButton.setBackColor(Color::White);
}
break;
case Event::MouseButtonpressed:
if(openNotepad.isMouSEOver(window)){
; system("notepad");
}else if(startButton.isMouSEOver(window) && !isstartOpen){
startmenu.setPosition(0.f,75.f);
openNotepad.setPosition({18,90});
opencalc.setPosition({116,90});
isstartOpen = true;
}else if(startButton.isMouSEOver(window) && isstartOpen){
startmenu.setPosition(0.f,500.f);
openNotepad.setPosition({0,500});
opencalc.setPosition({0,500});
isstartOpen = false;
}else if(opencalc.isMouSEOver(window)){
system("calc");
}
break;
}
view.setCenter(250.f,250.f);
window.setView(view);
window.draw(startmenu);
passCreate.drawTo(window);
window.draw(player);
openNotepad.drawTo(window);
opencalc.drawTo(window);
startButton.drawTo(window);
window.display();
window.clear(Color(144,255));
}
}
}
button.h
#pragma once
#include <iostream>
#include <SFML/graphics.hpp>
using namespace sf;
using namespace std;
class Button{
public:
Button(){
}
Button(string t,Vector2f size,int charSize,Color bgColor,Texture &texture,Font &font){
text.setString(t);
text.setColor(Color::White);
text.setCharacterSize(charSize);
text.setFont(font);
button.setSize(size);
button.setFillColor(bgColor);
button.setPosition(0.f,500.f);
button.setTexture(&texture);
}
void setBackColor(Color color){
button.setFillColor(color);
}
void setTextColor(Color color){
text.setColor(color);
}
void setPosition(Vector2f pos){
button.setPosition(pos);
float yPos = (pos.y + button.getLocalBounds().height / 1.3);
text.setPosition({pos.x + 5,yPos});
}
void drawTo(RenderWindow &window){
window.draw(button);
window.draw(text);
}
void setoutColor(Color outColor){
button.setoutlineColor(outColor);
}
void setoutThick(float outThick){
button.setoutlineThickness(outThick);
}
bool isMouSEOver(RenderWindow &window){
float mouseX = Mouse::getPosition(window).x;
float mouseY = Mouse::getPosition(window).y;
float btnPosX = button.getPosition().x;
float btnPosY = button.getPosition().y;
float btnxPosWidth = button.getPosition().x + button.getLocalBounds().width;
float btnyPosWidth = button.getPosition().y + button.getLocalBounds().height;
if(mouseX < btnxPosWidth && mouseX > btnPosX && mouseY < btnyPosWidth && mouseY > btnPosY){
return true;
}
return false;
}
private:
RectangleShape button;
Text text;
};
textBox.h
#pragma once
#include <iostream>
#include <SFML/Graphics.hpp>
#include <sstream>
#include <fstream>
#include <windows.h>
#define DELETE_KEY 8
#define ENTER_KEY 13
#define ESCAPE_KEY 27
using namespace std;
class TextBox{
public:
TextBox(){
}
TextBox(int size,Color textColor,bool sel,Color BoxColor,int borderThick,Vector2f BoxSize,Font &font,bool tof,int lim){
textBox.setCharacterSize(size);
textBox.setColor(textColor);
textBox.setFont(font);
hasLimit = tof;
limit = lim - 1;
typeArea.setFillColor(BoxColor);
typeArea.setoutlineThickness(borderThick);
typeArea.setScale(BoxSize);
isSelected = sel;
if(sel){
textBox.setString("|");
}else{
textBox.setString("");
}
string passAttempt;
string password;
ifstream getpassword("password.txt");
getline(getpassword,password);
cout << "Enter your password";
cin >> passAttempt;
passAttempt.compare(password) == 0 ? cout << "correct password" : cout << "incorrect password";
getpassword.close();
}
void setPosition(Vector2f pos){
textBox.setPosition(pos);
typeArea.setPosition(pos);
}
void setLimit(bool tof){
hasLimit = tof;
}
void setSelected(bool sel){
isSelected = sel;
if(!sel){
string t = text.str();
string newT = "";
for(int i = 0;i < t.length();i++){
newT += t[i];
}
textBox.setString(newT);
}
}
string getText(){
return text.str();
}
void drawTo(RenderWindow &window){
window.draw(textBox);
window.draw(typeArea);
}
void typedOn(Event input){
if(isSelected){
int charTyped = input.text.unicode;
if(charTyped < 128){
if(hasLimit){
if(text.str().length() <= limit){
inputLogic(charTyped);
}else if(text.str().length() > limit && charTyped == DELETE_KEY){
deleteLastChar();
}
}else{
inputLogic(charTyped);
}
}
}
}
void saveText(){
if(isSelected){
ofstream passFile("password.txt");
passFile.is_open() ? MessageBox(NULL,"Sucessfully saved password","Saved Password",MB_OK | MB_ICONinformatION) : MessageBox(NULL,"Error saving password: Password is in password.txt","File Error",MB_OK | MB_ICONERROR);
passFile << text.str();
passFile.close();
}
}
private:
Text textBox;
RectangleShape typeArea;
ostringstream text;
bool isSelected = false;
bool hasLimit = false;
int limit;
void inputLogic(int charTyped){
if(charTyped != DELETE_KEY && charTyped != ENTER_KEY && charTyped != ESCAPE_KEY){
text << static_cast<char>(charTyped);
}else if(charTyped == DELETE_KEY){
if(text.str().length() > 0){
deleteLastChar();
}
}
textBox.setString(text.str() + "|");
}
void deleteLastChar(){
string t = text.str();
string newT = "";
for(int i = 0; i < t.length() - 1; i++){
newT += t[i];
}
text.str("");
text << newT;
textBox.setString(text.str());
}
};
请帮助修复显示 RectangleShape 的程序
解决方法
我将您的项目加载到我的 Code::Blocks 环境中,不包括 textbox.h 并调用它。我用原来的code::blocks logo cb.bmp 替换了图像调用。我选择了手头的替换字体。
当我编译项目时,我发现了一个任务栏式按钮,带有两个子按钮。悬停子按钮时,会出现一个白色边框。您的 sf::RectangleShape(没有显示?)被称为 button。
这是预期的行为吗?
如果这是预期的行为,如果您还没有(删除所有目标文件),请尝试从头开始重建您的项目。也许这会让编译器告诉您是否有任何它不知道的错误。
>孤立的 .o 文件(意味着它们不再有源文件)会导致很多麻烦。删除源文件时不会删除对应的.o文件。
,更新帖子后: 我发现
using namespace sf;
不在你的 textbox.h 中
您还有两种不同的 SFML 图形标头包含类型
#include <SFML/graphics.hpp>
和
#include <SFML/Graphics.hpp>
假设您有 SFML 的库存安装,
#include <SFML/Graphics.hpp>
通常是正确的。
提示: 使用命名空间调用可能非常危险,因为您可能会忘记函数的来源。您可以通过在调用前加上命名空间名称来调用命名空间中的命令。例如:
RectangleShape typeArea;
会变成
sf::RectangleShape typeArea;
编辑:修复这些东西后,我做了一些调试:
error: class 'Textbox' has no member named 'setFont';
这是真的。当你调用 .setFont();在您的实例 passCreate 上,您没有调用 .setFont();来自 SFML,但是 .setFont();在您的班级 Textbox 中 - 不存在。将此添加到您的类中解决了这个问题。
void setFont(sf::Font font){
textbox.setFont(font);
};
这实质上是获取您传递给它的字体,并将其应用到您调用 setFont() 的实例文本框;
编译器还抱怨 textbox.setLimit(bool,int) 没有候选。您现在正在传递一个 bool AND 整数。这是因为类 Textbox 中的函数 setLimit() 没有整数传递。 我变了
void setLimit(bool tof){
hasLimit = tof;
}
到
void setLimit(bool tof,int setlimit){
hasLimit = tof;
limit = setlimit;
}
现在 setLimit 接受您发送的整数,并将其分配给类 Textbox 中的整数变量“limit”。
此后,不再有编译器错误。剩下的交给你!故障排除可能很有趣。看看编译器怎么说。它会告诉你出了什么问题。
最后提示: 我是否还补充说,输入错误的密码并不能阻止我“登录”; 当控制台询问我的密码时,主屏幕显示为冻结状态。也许您可以设置一个消隐精灵来覆盖所有内容?不过我相信有更好的解决方案!
,尝试包含