Project

General

Profile

Changed signal from List of Wt::WLineEdit fields

Added by Mike Ackley over 4 years ago

Hello,

In Wt 3, previously I used a signal mapper to enable a list of Wt::WLineEdit fields to be entered. It was working well.

I am now trying (similar to this:)

std::vector <Wt::WLineEdit *> amount;

amount.push_back (Wt::cpp::make_uniqueWt::WLineEdit(Wt::WString("")).get());

and

amount.back()->changed().connect( std:::bind( [=]() { amountChanged(0,amount.back() ); } ))

Later...

amount.push_back (Wt::cpp::make_uniqueWt::WLineEdit(Wt::WString("")).get());

row;

amount.back()->changed().connect( std:::bind( [=]() { amountChanged(row,amount.back() ); } ))

myClass::amountChanged (row, Wt::WLineEdit *)

{

std::cout << "This row was entered:" << row << \" \" << Wt::LineEdit.text() << std::endl;

}

This code generates sigsegv (faults) on the 'changed' line, and I have tried various combinations.

Even instead of { amountChanged...}, if I try {} or { std::cout "Row=" << row << std::endl } this is not working so I assume the issue may be in the lambda.

My c is not exceptional, so maybe a C issue, not a WT issue, but I would appreciate some help.

Thanks!

Mike


Replies (3)

RE: Changed signal from List of Wt::WLineEdit fields - Added by lm at over 4 years ago

amount.push_back (Wt::cpp::make_unique<Wt::WLineEdit>(Wt::WString("")).get());

This creates a std::unique_ptr<A>, gets the pointer from it, passes that pointer to amount. What happens to the std::unique_ptr<A>?

std::unique_ptr<A> "owns" the pointer to your Wt::WLineEdit. When the std::unique_ptr<A> gets destroyed (which will be just before the next line in this case!), the pointer gets destroyed, too, automatically. The pointer you just passed to std::vector<A*> amount is destroyed immediately. When you dereference this pointer, you get segmentation fault.

It looks like you create another pointer "Later". Are you wanting more Wt::WLineEdits at that point? I assume so, but the same problem will plague them.

RE: Changed signal from List of Wt::WLineEdit fields - Added by Mike Ackley over 4 years ago

Hi,

Thanks for your reply!! Yes, the same problem plagues my additionally added Wt::WLineEdit's as well as the [0] one.

I had assumed the vector holds the .get() of the std::unique_ptrWt::WLineEdit, and did not think the was destroyed.

Elsewhere in the code, I (used to) add the Vector of Wt::WLineEdit's into a Wt::WTable, and used these as a list of fields to perform data entry into.

What I used to do, prior to WT.4 was create a vector of Wt::WLineEdits, and then a bit later in the code, I do a loop of adding these saved pointers to an AddWidget in a table. This way, I create a table of input fields, dependent on how many I decide to add.

Based on what you say, is the reason for the destruction of the std::unique_ptrWt::WLineEdit because only the get() is stored in the vector and the non-raw-pointer is insufficient to hold the std::unique_ptr??

I wonder if I change the Vector to become amount<std::unique_ptr Wt::WLineEdit > but then if I go on to ADD this WLineEdit to the Table, the Vector would lose ownership of the pointer..

Another solution, I wonder, is to add the WLineEdit to the table first, then AFTER it's added, save the get() into the vector. This is a bit messy in my current code...

The only issue with this, is that I have a [0] dummy element which never will be added to the table.

Are there any other tricks?

RE: Changed signal from List of Wt::WLineEdit fields - Added by lm at over 4 years ago

I wonder if I change the Vector to become amount<std::unique_ptr Wt::WLineEdit >

This is the correct next question. Unfortunately, the answer is "no". std::vector<std::unique_ptr<A> > won't work because std::unique_ptr<A> is not copyable. (It may be possible, but it's not pleasant.)

What you should do is add the std::unique_ptr<Wt::WLineEdit> s to your Wt::WTable, then store pointers in a std::vector<Wt::WLineEdit*>. Something like this:

std::vector<Wt::WLineEdit*> amount;
for (auto const & a : source_data)
{
    auto new_pointer {my_table->addNew<Wt::WLineEdit>(a)};
    amount.push_back(new_pointer);
}
    (1-3/3)