arrays on 30 editBoxes

Started by wmbuRn, 23 July 2013, 04:26:25

wmbuRn

Basicly if i want to take value of a edit box i have to do this:

tgui::Panel::Ptr Group1 = gui.get("Group1");
tgui::EditBox::Ptr Ime1 = Group1->get("Ime1");
sf::String Name = Ime1->getText();

And it takes value of EditBox named "Ime1" and stores it to variable "Name". To do that for 30 editBoxes is a lot of code.. and i have 120 EditBoxes [in 1 group, having 18 groups in total is a lot lot lot lot of code] I can do that, dont have problem with that, but i am interested in using arrays. But arrays wont work. And i dont know why. I made test console application and arrays work there but in sfml and tgui they wont.
Here is  code:

sf::String Name[30];
sf::String Group1Ime[30];
for (unsigned int i = 1; i < 30; ++i) // 30 editboxes named Ime
{
Name[i] = "Group1->get(Ime[i])";
Group1Ime[i] = "Name[i]->getText()";
}

So nothing works, i changed code thousand times, and i get tons of different errors. And i know why this one doesnt work. Basicly i am doing this:

Group1Ime[i] = "Group1->get(Ime[i])->getText()";


I tried with std::vector

std::vector<tgui::EditBox::Ptr> Group1Names;
std::vector<tgui::EditBox::Ptr> EditBoxNames;
for (unsigned int i = 1; i < 30; ++i)
{
    tgui::Panel::Ptr Group1 = gui.get("Group1");
    EditBoxNames[i] = Group1->get("Ime" + "to_string(i)"); // error here becouse of "", even with Ime[i]
    Group1Names[i] = EditBoxNames[i]->getText();
}

No go. Nothing works. Any clues or hints ? :)

texus

You don't need to write quotes around the function calls.

You aren't executing the code. You're code is just like this (and hopefully you see that this won't work).
Name[i] = "blablabla";
Group1Ime[i] = "someString";


So replace
EditBoxNames[i] = Group1->get("Ime" + "to_string(i)"); // error here becouse of "", even with Ime[i]
with
EditBoxNames[i] = Group1->get("Ime" + to_string(i));
to remove the error.

wmbuRn


EditBoxNames[i] = Group1->get("Ime" + to_string(i));

I get error: 'to_string' was not declared in this scope. [ i #include <string>  in main file ]

to_string is part of std::

EditBoxNames[i] = Group1->get("Ime" + std::to_string(i));

i get error: 'to_string' is not a member of 'std'. So i can conclude i dont have c++11 support. Will chack that with my compiler.

So i tried:

EditBoxNames[i] = Group1->get("Ime" + tgui::to_string(i)); // tgui:: instead of std::

I get error  no match for 'operator=' in 'Group1Names.std::vector<_Tp, _Alloc>::operator[] [with _Tp = tgui::SharedWidgetPtr<tgui::EditBox>, _Alloc = std::allocator<tgui::SharedWidgetPtr<tgui::EditBox> >, std::vector<_Tp, _Alloc>::reference = tgui::SharedWidgetPtr<tgui::EditBox>&, std::vector<_Tp, _Alloc>::size_type = unsigned int](i) = tgui::EditBox::getText() const()'|

My gcc is version: gcc version 4.6.3 (Ubuntu/Linaro 4.6.3-1ubuntu5)
To have support for c++11 i need either 4.7 gcc or 4.8.1. Should i update my gcc or there is solution with 4.6.3? :)

texus

You indeed needed tgui::to_string and not just to_string (I overlooked that).
The only reason that tgui::to_string exists is in case you don't have c++11 support, because when you do you could just use std::to_string (it doesn't make a difference).
Technically, gcc 4.6 already supports c++11 with the "-std=c++0x" flag, but I provided a to_string function in tgui so there isn't really a need to use it.

QuoteI get error  no match for 'operator=' in 'Group1Names.std::vector<_Tp, _Alloc>::operator[] [with _Tp = tgui::SharedWidgetPtr<tgui::EditBox>, _Alloc = std::allocator<tgui::SharedWidgetPtr<tgui::EditBox> >, std::vector<_Tp, _Alloc>::reference = tgui::SharedWidgetPtr<tgui::EditBox>&, std::vector<_Tp, _Alloc>::size_type = unsigned int](i) = tgui::EditBox::getText() const()'|
It seems to be an error in the line below.
Group1Names[i] = EditBoxNames[i]->getText();

This isn't correct. You're trying to assing a string to an edit box. I think this should solve the problem.
Group1Names[i]->setText(EditBoxNames[i]->getText());

wmbuRn

#4
So here is how code looks in the end:

std::vector<tgui::EditBox::Ptr> Group1Names;
std::vector<tgui::EditBox::Ptr> EditBoxNames;
for (unsigned int i = 1; i < 30; ++i)
{
    tgui::Panel::Ptr Group1 = gui.get("Group1");
    EditBoxNames[i] = Group1->get("Ime" + tgui::to_string(i));
    Group1Names[i]->setText(EditBoxNames[i]->getText());
}


After compiling and running i get: Segmentation fault (core dumped)
When i comment out [ with /*  */ that part of code program works]. So problem is with my program. I will seek to it. Thank you very much.

Edit:

std::vector<tgui::EditBox::Ptr> Group1Names;

Should not be EditBox it should be array variable [ 30 of them] that holds value from 30 editboxes.

edit2:
Here is how it should be:

std::vector<sf::String> Group1Names;
std::vector<tgui::EditBox::Ptr> EditBoxNames;
for (unsigned int i = 1; i <= 30; ++i)
{
    tgui::Panel::Ptr Group1 = gui.get("Group1");
    EditBoxNames[i] = Group1->get("Ime" + tgui::to_string(i));
    Group1Names[i] = EditBoxNames[i]->getText();
}

Group1Names is sf::String [also vector] that can hold values from EditBoxes. EditBoxNames holds values like Ime1, Ime2, ime3... Ime30. So at the end Group1Names take Text from EditBoxes. After compiling i get:  Segmentation fault (core dumped) which should not happend.

This is code for 1 EditBox:

tgui::Panel::Ptr Group1 = gui.get("Group1");
tgui::EditBox::Ptr Ime1 = Group1->get("Ime1");
sf::String Name = Ime1->getText();


This is for 30:


std::vector<sf::String> Group1Names;
std::vector<tgui::EditBox::Ptr> EditBoxNames;
for (unsigned int i = 1; i <= 30; ++i)
{
    tgui::Panel::Ptr Group1 = gui.get("Group1");
    EditBoxNames[i] = Group1->get("Ime" + tgui::to_string(i));
    Group1Names[i] = EditBoxNames[i]->getText();
}

Which is not working. :)

texus

#5
It looks to me like you are never actually creating the edit boxes.
The segfault makes me believe you are trying to access elements that you didn't insert in the vector.
You try to access 30 elements in the vector, but are there 30 elements in it?

There should be something like this somewhere in your code.
for (unsigned int i = 0; i < 30; ++i)
{
    tgui::EditBox::Ptr editBox(*Group1);
    editBox->load("TGUI/widgets/Black.conf", "Ime" + tgui::to_string(i+1));
    // ...

    EditBoxNames.push_back(editBox);
}


Edit:
You should start counting from 0 instead of from 1. If your names of your edit boxes start counting from 1 then you can still use to_string(i+1), but to access elements in a vector you should start with element nr 0.

wmbuRn

This is short version of Group1.hpp



// stuff like panel size, pictures bla bla bla

    // Begin editBox Ime
    for (unsigned int i = 1; i <= 30; ++i)
    {
        tgui::EditBox::Ptr Ime(*Group1, "Ime" + tgui::to_string(i));
        Ime->load("Data/Buttons/Black.conf");
        Ime->setMaximumCharacters(15);
        Ime->setSize(120, 15);
        Ime->setPosition(20, (i * 110) - 40);
        // i never used  EditBoxNames.push_back(editBox);
       }
    // End of editBox Ime;

// other EditBoxes Here, Labels, CheckBoxes
// all of them are shown when the program is compiled and they do what they are supossed to do :)
// then it comes this

std::vector<sf::String> Group1Names;
std::vector<tgui::EditBox::Ptr> EditBoxNames;
// Take Text from EditBoxes
for (unsigned int i = 1; i <= 30; ++i)
{
    tgui::Panel::Ptr Group1 = gui.get("Group1");
    EditBoxNames[i] = Group1->get("Ime" + tgui::to_string(i));
    Group1Names[i] = EditBoxNames[i]->getText();
}

So EditBoxes are created before "Take Text from EditBoxes".

texus

Quote// i never used  EditBoxNames.push_back(editBox);
Well thats your problem.
If you never insert the edit boxes then the EditBoxNames is empty.

And then
Group1Names[i] = EditBoxNames[i]->getText();
should also be
Group1Names.push_back(EditBoxNames[i]->getText());

wmbuRn

No core Dumped. Thanks. I will report back if its working when i start using

Group1Names.push_back(EditBoxNames[i]->getText());

for encrypting Values and then saving them to a file. And also for transfering values from one group to another [like from Group1 to Group1Notes]

Thank you