Slots

Added by Mike Ackley 5 months ago

Hi,

I'm new to C++ and WT but an 'ol developer of 20+ years ;-)

However, I am having difficulty fully understanding the signal/slot process.

I have a pushbutton like this copied from the Web Page example

WPushButton *Button = new WPushButton("Start");
Button->clicked().connect(Button, &Wt::WPushButton::disable);

This works.

But

Button->clicked().connect(this,&Home::startCreateMaster);

and

Button->clicked().connect(boost::bind(&Home::startCreateMaster, this)); (found in the forums)

both fail to trigger "startCreateMaster" to start. I have tried a few other combinations without success,
and despite my reading, I must be missing something. I think the issue is that the startCreateMaster is a function
in the same class as the button, on the same thread. However, I don't know why the pushbutton disable would work (so that
event must be getting through) but the event is not getting through to the function.

My goal is to implement the 'home' page, with a button, that invokes a function on the Homepage Class
(startCreateMaster) which will kick off a thread to create a master database.

I'd like the thread to set a finished signal when it's done, and send a signal back to the Home class.

I haven't worked out the best approach yet, but intuition is telling me that I want the work done in the threads, and the GUI done in the main class. I looked at the server push example, but thought that I don't really want the thread updating the GUI directly, though I might compromise in the case of a progress bar. My thoughts are push button->disable button->start thread;
Background thread does DB work (may be 1 min).. Another "progress" widget maybe sits on the web page, and listens (is a connect-> slot back from the thread to it maybe) and the thread does a signal every now and then to update the progress widget. At the end, the thread would signal finished.

At the moment, the startCreateMaster is just like this. Just trying to see it invoked.

void Home::startCreateMaster() {
std::cout << "in start createmaster" << std::endl;
this->log("notice") << "In startCreateMaster";
return;
}

Does somebody have a simple example of how this two-way handshaking is implemented?

This would help very much, as I've been stuck on this for a few days...

Thanks
Mike
p.s. really enjoying learning wt, it's great.


Replies

RE: Slots - Added by Wim Dumon 5 months ago

Mike Ackley wrote:

Button->clicked().connect(this,&Home::startCreateMaster);

and

Button->clicked().connect(boost::bind(&Home::startCreateMaster, this)); (found in the forums)

both fail to trigger "startCreateMaster" to start. I have tried a few other combinations without success, and despite my reading, I must be missing something. I think the issue is that the startCreateMaster is a function in the same class as the button, on the same thread. However, I don't know why the pushbutton disable would work (so that event must be getting through) but the event is not getting through to the function.

Both should work. A slot remains connected until its target is deleted (insofar that target is a boost::trackable, which is the case if it inherits from WObject).

My goal is to implement the 'home' page, with a button, that invokes a function on the Homepage Class (startCreateMaster) which will kick off a thread to create a master database.

I'd like the thread to set a finished signal when it's done, and send a signal back to the Home class.

Pay attention: if you manipulate a widget tree from within a thread, you MUST grab the UpdateLock (See WApplication documentation). Also, those modifications will not be sent to the client unless you trigger an update yourself. Look at the feature/serverpush example for more info. Also, consider using WServer::post() instead of the UpdateLock mechanism; it is usually much simpler.

Can you post a full test-case of what you're trying to acomplish? It's hard to point out the possible mistake in this way...

Best regards,
Wim.

RE: Slots - Added by Mike Ackley 4 months ago

Hi Wim,

Sorry to take a while to reply, thanks for your answer.

My lack of C++ knowledge and reading the documentation was at the core. I fixed it now.
What I originally did, was to use leverage (copy) the homepage example, with push button triggers to try and start a background thread.

I didn't realize that some of the homepage elements are wrappered as const, which don't respond
to triggers - at least when attaching functions to respond. So I moved some of the constants to be instantiated and this worked.

I studied both the server push, and the broadcast example, as well as some determined reading to understand more how virtualization works, as well as info on boost::bind, which I didn't understand before.
One further point was that I originally has a separate object with a (thread) function defined, which i instantiated from a function which was triggered. However, the object got into all sorts of scope issues.
Then I learned that you can simply run a method off the current object (homepage for example) as a separate thread, and then I simply used server.post back to update the main event loop to manipulate the widgets (progress bar). Unfortunately, because of a couple of shortfalls in my C++ knowledge, I originally made things more complex than I needed. I studied the serverpush and simplechat examples. Both seem to deal with cross-session communications, but I just needed same-session widget-tree updates from a thread.

So I was originally looking for the simplest post-back case. I just start a thread from the main event loop (i.e. push button) in the same session, and then update the progress bar. I achieved that simply by having a progress bar in the main widget tree, and have a thread which POSTS back a "% complete" message to the main tree, which then updates the bar. Works perfectly. I prefer server.post because the 'main widget tree' looks after the GUI rather than another thread getting control. I think this separates concerns better. However, that's just an opinion, and there may be more complex cases I didn't think of yet.

Thanks for your kind offer to help - I am sure I will have more questions, but now I an knee deep in trying the suggestion popups after solving the event problem I had.

Best wishes,
Mike
p.s. WT a very excellent library. I'm enjoying learning it. Thanks