Assign values to multiple edit boxes, given their names - c++

i am currently doing some programming in Borland C++ Builder 6.
I have 24 edit boxes(a visual component, with a text field) and i want to insert some values in the boxes, now i do it like this:
Edit1->Text=1;
Edit2->Text=2;
Edit3->Text=3;
...
Edit24->Text=24;
but i want to have something like this:
for(int i=1; i<25;i++){
Edit"i"->Text=i;
}
i think i have to make an array of objects or something.
Can any body help me with this? I don't have a lot of experience with objects and stuff like that.

There is a FindComponent function in VCL. It is used to find a component by it's name.
In your case it will look something like:
TEdit * tmp;
for( int i = 0; i < 24; i ++ )
{
tmp = (TEdit*)MyForm->FindComponent("Edit" + IntToStr(i) );
tmp->Text = i;
}

Related

Why do I still have strings in my ListBox even after using a loop to individually remove them?

Stumbled across what seems like an odd bug..... I have ListBox items added with addstring ... I have the listbox control return a count as a DWORD and convert it into an integer with the following code and only a portion of the strings listed are deleted ... I realise some of the type conversions arent necessary, but i have tried without the typecasting and the issue remains the same....the code :
int count = (int)myListBox->GetListBoxInfo();
for (int cnt = 0; cnt <= count; cnt++) {
UINT itemIndex = (UINT)cnt;
myListBox->DeleteString(itemIndex);
}
myListBox->UpdateData();
myListBox->UpdateWindow();
I’m sure there is probably another way to clear the list but im curious why this isn't working ....
Kind regards stackoverflow,
Imagine your listbox as
0 foo
1 bar
2 baz
Now, hit your loop. Delete index 0:
0 bar
1 baz
Now delete index 1
0 bar
See the problem? This would do what you want:
int count = (int)myListBox->GetListBoxInfo();
for (int i=0; i<count; ++i)
myListBox->DeleteString(0);
myListBox->UpdateData();
myListBox->UpdateWindow();
But in reality, belay all of that and just do this:
myListBox->ResetContent();
See ResetContent in the MSDN Library.

How to call properties of a struct instance with it's names [duplicate]

This question already has answers here:
Get attribute by name
(5 answers)
Closed 4 years ago.
I have a structure named informations,
struct informations {
char no[12];
char name[16];
int exam1, exam2;
float result;
char letter[3];
}
I'm storing informations of students in files. I can read/write files and other things. I want to sort all students (instances of informations structure) by all properties that structure has (in this case, ["no", "name", "exam1", "exam2", "result", "letter"]).
I have a sort function, it sorts for a property, like this:
for(int i = 0; i < 99; i++) {
for(int o = 0; o < 99; o++) {
if(students[i].result > students[i + 1].result) {
container = students[i];
students[i] = students[i + 1];
students[i + 1] = container;
}
}
}
The above code is, works fine for sorting all students by their result property, but I want to sort students by their all properties differently without duplicating the above code for all properties. I have ideas about to do this but I don't know how to apply these ideas into code,
Store all struct properties in an array,
string properties[6] = ["no", "name", "exam1", "exam2", "result", "letter"];
Iterate over the properties array,
In iteration loop, use the above sorting function by iterated property
Thanks for your helps!
Sorry, but without reflection (which C++ does not have) it's not trivial to do.
You can reduce duplication by switching from your quadratic implementation to std::sort, then write a bunch of comparators for each sort criterion. Those ought to be as simple as return student.result < student.result, where result is whatever member you wish to compare (though this is more complex for arrays and C-strings!).

I'm using qt to design a program and need help because my code is not DRY [duplicate]

I have a gui form, where multiple text boxes are present. I want to put their values inside an array. One way of doing it is by writing something like this
{array element } = ui->text_1->text();
and repeat it for text_2,text_3 upto n.
What I want is to run a loop and replace number portion of text box name in each cycle.
something like this {array element } = ui->text_{This number getting changed }->text();
How can it be done in qt?
There are two ways of doing this.
When you create the UI, instead of using text1, text2, etc. you create an array of QLineEdits (eg. std::vector<QLineEdit>) and then when you want to retrieve their values then simply iterate over this array
Iterate over the children of the container widget. You can get the list of the children using the following (documentation):
QList<QObject *> list = parentWidget->children();
Another option to those listed would be to create an array using an initializer list. Depending on how big the array is (and how often it changes), this might be workable.
QLineEdit* entries[] = { ui->text_0, ui->text_1, ui=>text_2 };
QStringList answers;
for ( int i = 0; i < 3; ++i )
{
answers += entries[i]->text();
}
here is an expanded version of Matyas' solution:
class MyClass : public QWidget
{
QStringList answers;
void FillAnswersList(QObject *base)
{
QLineEdit *lineEdit = qobject_cast<QLineEdit>(base);
if(lineEdit)answers.append(lineEdit->text());
else
{
foreach(QObject *child, base->children())
FillAnswersList(child);
}
}
};
If it is just the number changing, and always incrementing, there is another possible solution using QObject::findChild, which takes a name as a parameter.
QString name_template("text_%1");
QStringList answers;
for(int i = 0; i < MAX_TEXTS; ++i)
{
QLineEdit *edit = ui->findChild<QLineEdit *>(name_template.arg(i));
answers += edit->text();
}

How to initialize over a 100 QLabel in an efficient way

I want to have the ability to update over 100 labels, so I was going to put them in an array like this:
voltage_label_array[0] = this->ui->Voltage_0;
voltage_label_array[1] = this->ui->Voltage_1;
voltage_label_array[...] = this->ui->Voltage_2;
voltage_label_array[...n] = this->ui->Voltage_n;
and then have this method
void MainWindow::updateValue(int i, int voltage){
voltage_label_array[i]->setText(QString::number(voltage));
}
but having 100 lines to set this up seems like a bad idea. Is there a way I can initialize a QLabel array inside a for loop or something?
If you need to do this, something is horribly wrong with your design. But it is possible.
Assuming your labels are named Voltage_0 to Voltage_99:
for(int i = 0; i < 100; ++i) {
auto ptr = this->findChild<QLabel*>(QString("Voltage_%1").arg(i));
voltage_label_array[i] = ptr;
}
This "solution" uses Qt's runtime reflection and carries the expected performance penalties.
But if you need to display several similar values, look up QListWidget and similar classes.

How to use the QVector with multiple object

I'm trying to use the QVector class from Qt to work (for me :P). What I want to do is to put multiple instances of the object Question in a QVector.
I went on multiple forums, but they're all too complicated for me as I am a beginner.
This one post was perfect but I did not find a way to resolve my problem.
So I'm turning to you to help me!
Here's the function that I want to work :
The part that create the bundle/ the vector
/**
* #brief MenuQuestionnary::assembleQuiz
* Assemble the bundle of question that will be used in Quiz class
*/
void MenuQuestionnary::assembleQuiz(){
QVector<Question> vectorQuiz;
vectorQuiz.reserve(spinBoxNumberOfQuestion->value());
for(int i = 0; i <= spinBoxNumberOfQuestion->value(); i++){
vectorQuiz.append(Question((qrand()% maximumNumberOfQuestionAvailable)));
}
}
Here's my Question constructor :
Question::Question(int id)
{
this->questionId = id;
//TODO: Actually get it from DB
this->questionText = "2+2?";
this->explanation = "Addition mechanics";
this->creatorId = 1;
}
What i expect to do here is to put the selected number of the Question object in a vector. After that i can pass it to another class. From there i should be able to extract the text from them(questionText and questionExplanation).
You are trying to push objects of class type Question into a QVector<int>, which obviously is expecting an int instead. You should change it to QVector<Question> to begin with.
What I highly suggest, though, is that you read a good book on C++ before going any further, or your experience with it will just get more and more complicated.
Copy pasting code from forums on the internet is not programming and will get you in troubles soon.
I think what you want is this: QVector vectorQuiz; vectorQuiz.reserve(spinBoxNumberOfQuestion->value()); // reserve correct amount of space in vector for performance (not required). I don't know exactly how you are going to use vectorQuiz, but maybe you should use pointers to the questions i.e. QVector and insert questions using new Question()
/**
* #brief MenuQuestionnary::assembleQuiz
* Assemble the bundle of question that will be used in Quiz class
*/
void MenuQuestionnary::assembleQuiz(){
int iVectorSize = spinBoxNumberOfQuestion->value();
QVector<Question> vectorQuiz;
vectorQuiz.reserve(iVectorSize );
for(int i = 0; i <= iVectorSize ; ++i){
vectorQuiz.append(Question(i));
}
}
Your object (vectorQuiz) declared as vector of integers. If you want to add some integer value to it you should write something:
vectorQuiz.append( someIntegerValue );
or
vectorQuiz.push_back( someIntegerValue );
For vector of another type (i.e. Question), write code like this:
QVector<Question> vectorQuiz;
// ...
for(int i = 0; i <= spinBoxNumberOfQuestion->value(); ++i){
vectorQuiz.append(Question(i)); // without [i] after vector object
}
And possible your should use strict inequality < instead of <= in for-cycle (but I'm not sure).
I solved it by trying few things
Here's the explanation of what i did
I've split my function in two. The first one put the element in a QList and the second one shuffles it.
/**
* #brief MenuQuestionnary::assembleQuiz
* #param list
* Asseble a quiz in the Qlist and then ask shuffle to shuffle it...
*/
void MenuQuestionnary::assembleQuiz(QList<Question> &list){
for(int i = 0; i < spinBoxNumberOfQuestion->value(); ++i){
int rand = qrand() * maximumNumberOfQuestionAvailable;
Question newQuestion(rand);
list.append(newQuestion);
}
shuffleQuiz(list);
}
/**
* Method Shuffle
* equivalent to shuffling a deck of cards: we take a random one, move it to be the last one,
* then do it again enough times to have statistically touched every card.
*/
void MenuQuestionnary::shuffleQuiz(QList<Question> &list){
int iters = list.size() * list.size();
for (int i = 0; i < iters; ++i){
int rand = qrand() * list.size();
list.append(list[rand]);
list.removeAt(rand);
}
}
Thanks for the help though.