I'm using Wt C++ framework and need to connect a push button with a class function. The below code works fine but it's needed to run the function doors_open_all on a thread to allow usage of other actions at the same time.
Wt::WPushButton *open_doors_button = new Wt::WPushButton("open all");
container_box->addWidget(open_doors_button);
open_doors_button->clicked().connect(boost::bind(&Servicemode::doors_open_all, this));
Something along the lines is needed:
open_doors_button->clicked().connect(boost::threaded_bind(&Servicemode::doors_open_all, this));
If I understand question corrently you need to run doors_open_all function in a new thread.
boost::thread constructor is internaly using boost::bind You don't need to be explicit.
So open_doors_button->clicked().connect(boost:: thread(&Servicemode::doors_open_all, this)); should do the job.
Version with boost::thread and boost::bind:
open_doors_button->clicked().connect(boost::thread(boost::bind(&Servicemode::doors_open_all, this)));
Edit:
You can also try using std::async for this purpouse too.
What does Servicemode::doors_open_all() do?
If I assume that what is taking a long time is just all backend stuff, so no widgets are being created, deleted or modified, then you can spawn a thread inside Servicemode::doors_open_all() to do all of that backend stuff. When it's done you have two possibilities:
Use WServer::post(), passing it the session id of your WApplication and a function, to notify the application that it should update its UI, and do all of your creating, deleting and modifying of widgets in that callback.
Grab the update lock of the WApplication:
// Assuming that app is a Wt::WApplication*
Wt::WApplication::UpdateLock lock(app); // lock is released when it goes out of scope
When you have the update lock, you can go ahead and modify the widget tree.
In any case, when doing this, you have to also do these two things:
Enable server push beforehand by calling app->enableUpdates(true). When the thread is done you can again disable server push with app->enableUpdates(false).
When you have modified the widget tree, notify Wt that it should push these changes to the client with app->triggerUpdate().
If what takes a long time is UI-related, then there's not much you can do, since Wt assumes that you only modify a WApplication and its widgets from a single thread at a time, i.e. when you have the update lock. The update lock is always grabbed automatically when handling an event coming from the client, like WPushButton::clicked().
Server push is demonstrated in the serverpush example. You can find that under examples/feature/serverpush in the Wt source tree.
Related
I am new to Qt. I have worker thread that is an std::thread. The worker thread function continuously fetches some some data in a loop. The size of the data is frequently updated on a Text element on a QML UI. I have a listener callback which is nothing but an std::function and it gets called from the thread's function. It sends me callbacks based on which I updated the Text element on QML. I update it using signal slot mechanism.
Following is the QML : Text element:
Text {
id: mytext
objectName: "mytextobject"
function slotUpdateData(someValue){
mytext = someValue
}
}
SignalUpdateData is connected with slotUpdateData which resides on QML side. Every time I get the data event callback from the std::thread, I emit SignalUpdateData which updates the QML Text element on UI.
void CallBackReceivedFromWorkerThread(float someValue) {
emit SignalUpdateData(someValue)
}
Following is how I have connected this C++ signal with the QML slot
QObject::connect(this, SIGNAL(SignalUpdateData(QVariant)), myTextItemQObject, SLOT(slotUpdateData(QVariant)));
And all of this works fine. No crashes, lock-ups, nothing.
As per my understanding, since the worker thread's function is triggering the callback, the execution control is on the worker thread when the callback is received. So when doing emit SignalUpdateData(someValue), we'er still on the worker thread. And as far as I know from my previous experience in android & java, we cannot update the UI from anywhere outside the main thread of the application.
So, How is this working ? Is emit SignalUpdateData(someValue) putting the call into the main UI thread's event loop ? Is Qt still making the UI change on main thread in spite of me calling for it from a worker thread ? If my approach is fine, then does it have performance implications ? What is the best recommendation to do this ?
I want to be very sure about this & not just lucky about making this to work. Should I use a Qt::Connection_enum as well for best approach ?
You're leveraging Qt the way it was meant to be! And you've run into it accidentally: that's a sign of a decent design - it "just works". Hooray for you, hooray for Qt :)
It's working because Qt has been designed specifically to make it work, and you're using the default automatic connection whose raison d'ĂȘtre is to help you out in this specific case. So you happen to be doing everything right: change nothing!
When you emit a signal, Qt acquires relevant source and destination object mutexes, and compares the receiving object's thread() to QThread::currentThread(). If they are identical, the slot/functor is called immediately: it happens in the body of the signal, so the slot is called before the signal returns. This is safe as the target object is used from its thread(), where it's safe.
If target->thread() != QThread::currentThread(), then a QMetaCallEvent is queued to the target object. The event contains the (equivalent of) slot method pointer and a copy of any parameters passed by the slot. The QObject::event implementation handles the event and executes the call. The target object thread's event loop is on the call stack, since its job is to deliver the queued events to the object.
The above is, in a nutshell the meaning of a Qt::AutoConnection. If you're using Qt::QueuedConnection, the 2nd case applies no matter what the threads are. If you're using Qt::DirectConnection, the 1st case applies no matter what.
My guess is that >95% of the uses of a non-automatic connection type in Qt-related questions on SO are unnecessary and stem from lack of understanding and resorting to what amounts to magic incantations.
I am writing a mathematical simulator in Qt5 and when I click a button, some heavy calculation needs to be done. During it, I want to display a Please, wait window, eventually with a progress bar. Preferably without using threads.
Problem is, during calculation the application hangs, events are not handled, and what should be a please, wait window is merely a window frame without any contents (looks transparent).
PC: AMD X2 L325, 2GB RAM, Radeon E4690
OS: Debian 6 (Squeeze, Old stable)
gcc 4.4.5, Qt 5.2.0
Any help would be appreciated!
While you could call QApplication::processEvents, it's not the best approach.
If you're avoiding threads because they're new to you, then I'm sure you'll find it much easier once you've done it once. Qt makes it easy.
All you need to do is create a class derived from QObject which will do the calculations. Next, create a thread and call the object's moveToThread function. The thread is then controlled with a few signals and slots. That's all there is to it.
Rather than repeat the content here, I suggest you read this article, which explains it in detail and provides clean and concise example code.
From the new object that processes your calculations, it can then emit a signal to a slot on the main thread, which will update the progress on your "Please Wait" window.
Note that Widgets and all rendering must be done on the main thread.
I prefer use Qt Concurrent. It is not well documented, but very handy, much better then using QThread directly.
I usually do such things like that I have separate QObject for logic, in there some slot which calls heavy calculation like that (see run documentation):
void MyCalculationClass::startCalculating() {
QtConcurent::run(this, &MyCalculationClass::doHeavyCalculation);
}
Where method doHeavyCalculation emits signals with progress and calculation results.
Usually this method operates on its own data not modified by other threads/methods, so if synchronization is needed, it is trivial. Signal-Slot mechanism is handling most of the multithreading issues (note that default connections detects that signals is emitted from other threads and queues slot calls in proper thread, it is done automatically by default).
i have such problem and i solve it like this, i make calculation in another thread( i use std::thread instad of QThread) before i start my calculation i just start timer
QTimer *timer = new QTimer(this);
connect(timer, SIGNAL(timeout()), this, SLOT(repaint()));
timer->start(1);
and then
std::thread t(&Widget::calcBackgound, this);
t.detach();
You can put the heavy and time consuming part of your code in run() member function of another class which inherits from QThread. After that create an instance of the new class and simply call its start() function.
Your new class can have a signal which emits the current progress value. you can then connect this signal to the slot of a progress bar.
I'm implementing threading in Metro mode, I got this example while Googling, but I don't understand CallbackContext . What's the use of this? This explains its use in MTA, but not clear to me. And I'm facing problem when I use CallbackContext as Any or Same. Something work with one but not with other! So first thing first I want to know what's the use of this?! PS: I'm new to WindowsRT programming and C++ too! Thanks!
auto workItemHandler = ref new WorkItemHandler([=](IAsyncAction^)
{
// Run the user callback.
try
{
func(data);
}
catch (...)
{
}
// Signal that the thread has completed.
SetEvent(completionEvent);
//CloseHandle(completionEvent);
}, CallbackContext::Same);
CallbackContext determines whether your delegate (in this case, a WorkItemHandler) aggregates the free-threaded marshaller. This will determine whether your delegate can be smuggled to another apartment (CallbackContext::Any), or if it must be called back to the originating apartment (CallbackContext::Same). Basically, it tells the person invoking your delegate whether it can be called directly regardless of apartment, or if they need to marshal back to the apartment it was created in.
For example, in a Windows Store Application, anything that modifies the UI needs to run on the UI thread (STA). Let's presume the method you're in is one that runs on the UI thread (such as an event callback, like a button click handler). Certain async calls like ThreadPool::RunAsync will run the passed-in delegate on a thread other than the UI thread (as the default for delegates is CallbackContext::Any). This is useful if you do not need to do anything on the UI thread, as it frees that thread up to continue pumping messages (and your app continues to feel performant).
However, if you do need to modify the UI or make a call back into the UI, and you attempt to do so from a non-UI thread, you will get an incorrect thread exception. By adding the parameter CallbackContext::Same you can force your delegate to run in the originating apartment (in this scenario, the STA) and thereby avoid the issue.
(You can also make a call back to the UI thread by using Dispatcher->RunAsync to invoke a further delegate to run on the STA. Whether it's better for your entire delegate to run on the STA or not depends on your scenario.)
I've checked a satisfying explanation but could not find. Usually docs mention that in order to use signals/slots between threads, we need to use event loops and start them by calling exec.
However I can see that w/o using exec(), I can still send signals and handle them across threads.
What's the exact use of it?
Use QThread::exec() when you want to run the event loop Qt provides for you in the QThread class. If you don't call exec(), you need to create your own event loop that processes Qt events (that is, if you want signals / slots to work). This is almost certainly more work than it's worth, unless you have very specific needs.
You say you can still send signals / slots? My guess is that you're not actually running anything on a different thread. This is a very common issue when using QThread. Put a breakpoint inside the code you think is running on a different thread and have a look at the stack trace - you may be in for a shock!
A rough example.
Suppose you have a text box. On each letter user types on the text box you want to perform some background task. You can setup a QThread for that. Emit something whenever the contents of text box changes. Assign a slot from your QThread that handles the background task. Emit something from QThread when the task finished. Handle this signal from main thread. Connect them. Start the thread when the text box is created (or any appropriate time). If you call exec() from your QThread::run() then you don't need to start() the thread multiple times.
If you don't use this mechanism, you may need to create (and/or start()) a QThread each time the content of text box changes, perform the background task and get result. This time you can still use signal/slot between main thread and this thread, but you need to start() the thread multiple times.
My application is a multi threaded app (using wxThreads). At the moment, the main thread along with it's child worker threads are outputting various messages to Stdout (using cout).
I have a new frame/window with a wxTextCtrl, and would like to redirect all the StdOut messages in to it.
GuiLogFrame *logframe;
logframe = new GuiLogFrame(NULL, wxID_ANY, wxEmptyString);
logframe->Show();
logredirector = new wxStreamToTextRedirector(logframe->get_log_textctrl());
This doesn't work. But if I replace the last line
wxStreamToTextRedirector redir(logframe->get_log_textctrl());
The standard out will be redirected to the logframe wxTextCtrl as long as redir is in scope... I want it to stay even when it goes out of scope.
What I want is the wxStreamToTextRedirector to stay intact the entire time the application is running... so even the new thread's cout will also redirect in to the same wxTextCtrl.
Any thoughts?
One thing that is very important to know is that GUI operations should only be done on the main thread; if you don't, it will crash or lock up when you have more than one GUI operation happening at the same time. This is definitely true under windows, but I believe it applies to all platforms. What you will need to do is post an event to the control using GetEventHandler()->AddPendingEvent. Then wx will add the event to the object's queue and when the main thread runs, it can do the GUI operation.
This might not be the exact answer to your question, but it is relevant information.
I found one way of doing it but I didn't try it out in a multi-threaded app.
You can create a pointer to the wxStreamToTextRedirector on a constructor() using new.
And then, don't forget to delete the pointer in the destructor.
wxStreamToTextRedirector is a RAII class associating the stream with the text control in its ctor and breaking the association in its dtor. You can, of course, create it on the heap instead of using it as a local variable or even just manually do what its ctor/dtor do, i.e. call ostr.rdbuf(text) and restore the original value of rdbuf() at some later time.
However, as arolson101 wrote, you'd still could have a problem in your code if you allow multiple threads use the same wxTextCtrl and simple redirection won't help you with this. You would need to write your own custom streambuf-derived class which would avoid outputting the text immediately but post a message to the main GUI thread asking it to do it, which is not completely trivial.