QBasicTimer::start: QBasicTimer can only be used with thread - qml

Description:
When the "QBasicTimer::start: QBasicTimer can only be used with thread " log appears, in my qml program, all rendering events are gone, that is, there is no more QEvent:updateResquest event.
The ui is no longer updated, and the interface is suspended. What causes this? What's even more strange is that my program does not show that the QBasicTimer type object is called

Related

Cannot update User Control Label Text from parent event until the event method reaches return statement

The main form of my application has an event that gets triggered upon completion of a certain task. The event completion launches a background thread and the called method in that thread runs a loop which takes a while to complete. This loop updates (or is supposed to update) the user on what's going on during its run by editing the label->Text property of the UserControl along with a percentage of completion in a different label in the same UserControl. There are some more labels in this UserControl that are updated, but are not of the concern for this question.
Here is how the methods and statements are called.
Event Completed -> Background Thread
Background Thread -> Process()
Process() -> for loop()
for loop() -> UserControl->SetMessage(System::String^ msg) and UserControl->SetPercentage(int Percentage)
(1) UserControl->SetMessage(System::String^ msg) -> stores msg in a private UserControl member and executes this->Invoke->SetMessage_sub()
(2) UserControl->SetPercentage(int prcnt) -> stores prcnt in a private UserControl member and executes this->Invoke->SetPercentage_sub()
(1) SetMessage_sub() -> label1->Text = _msg;
(2) SetPercentage() -> label1->Text = _prcnt;
However, I found that the labels were not getting updated for as long as the loop ran. The labels only updated once the loop finished its run inside Process().
I used the System::Console::WriteLine method to figure out where the problem occurs. I found out that all the methods were being called. But the execution would stop at where the program would reach label->Text property. Please help me out.
I have run into a similar problem recently and found that the GUI update calls must be made from either a thread running in the background or a background worker. Try calling the method that updates your GUI from a background thread or a background worker.
Edit 1 - it sounds like you've already tried a background thread. Try using a BackgroundWorker object to accomplish the task.
Edit 2 - upon re-reading your question, it occurred to me that the problem you are facing is the GUI not loading until the event method has returned. I encountered the same problem and asked my question here. To my surprise, all I got was downvotes and no answers. A comment tried to refer me to using BGWorker class to update GUI but none of them read my question carefully. I know background threads and background workers. I have tried both but the GUI does not update until return is called from the event method. In my case, after calling the BackgroundWorker to do the processing, I ran an empty while loop in the event method and called break when the BGWorker finished. But the GUI never updated until break was executed. So, my solution was to create a separate event for the processing and processing completion. The completion of the initial event calls the processing method and then processing method's completion calls the processionf completion event method.

global startup and shutdown events when application starts and exist

I need to write a log when the application starts and exits. Obviously when it starts it easy to write the log. But a user can close an application in multiple ways, even shut it down in task manager. is there sort of a global event when shutting an application down it will call a specific event from anywhere and I can add my logging code?
In visual Studio, go to the project properties window, Application tab. AT the bottom is a button labelled 'View Application Events' This takes you to a code view where you can add handlers for the application events including the shutdown event. However, this isn't always fired if your application crashes ^H^H^H^H^H closes in an 'unusual' way.
The startup event is useful too - you could put your startup logging code in there- we use it a lot to put in all the application setup code, with only a splash screen showing, then when the startup code completes the main window will pop up.
Finally, the Unhandled Exception event is a handy place to put a final catch-all backstop error handler

How to update a NSTextField Value during an action?

I am running a lengthly task in an Action and I would like to have a display of where I am at. For that I created a Text Field and I tried it with setStringValue:
[textField setStingValue: [NSSting stringWithFormat:#"%ld",currentValue]]
The code works but unfortunately it is not updating the NSTextField after every iteration but rather when the whole Action is done.
What am I doing wrong?
This is because applications with the Cocoa framework use an event loop to perform operations, and events occur in a completely serial fashion.
An event is basically any kind of action that the framework designer could not predict or found convenient to have run in a delayed manner. Since you can't predict when clicks will be performed, they need to be considered events; and for efficiency reasons (since you don't want to repaint a component multiple times if you don't need to), the repaint actions are events too.
Your action runs in response to a user event (for instance, a click on a button is an event) and therefore blocks all other events waiting in the queue until it's complete. However, components are repainted in response to a different, framework-triggered event, and as such the text field must wait until your action completes to repaint itself. This is why you cannot visually change the value of a text field from inside an action.
In order to notify your user of the progress of your task, you'll need to run it on a different thread. There's a lot to say about threads, so you should probably read some about them. I'm also sure that there are plenty of examples of how to run a long action in a background thread and update the UI accordingly for Cocoa all over the Internet.
When you click on a UI component, and it enters the Action block, the code is running on the main thread, the same thread that is painting the UI. If you run a long running operation in that block, it isn't going to paint until you are done because it is busy doing whatever you have it doing - you have hijacked the paint thread.
As said elsewhere, you need to spawn another thread, and then have the new thread perform the long running operation, and occasionally send messages to have the UI be updated by the main thread.
As a next step, go read the Apple documentation on NSThread, specifically:
+ (void)detachNewThreadSelector:(SEL)aSelector toTarget:(id)aTarget withObject:(id)anArgument
Be aware that threading is a non-trivial domain area, and be ready for some wierd behavior if you aren't careful.

Handle application exit

I want to run some cleanup code(like unregistering scheduled notifications) when a user quits the application by using the Alt-F4 or swipe down gesture. Is there any way to handle an application exit in WinJS? I've read the docs for the WinJS.Application object but don't see any methods to handle user exits.
There is no special event that indicates that an app is being closed:
There's no special event to indicate that the user has closed an app. After an app has been closed by the user, it's suspended and terminated, entering the NotRunning state within about 10 seconds. If an app has registered an event handler for the Suspending | suspending event, it is called when the app is suspended. You can use this event handler to save relevant application and user data to persistent storage.
So you'll want to handle a suspend/resume instead. The gory details for handling a suspend are here, but here's a summary:
Register for the checkpoint event that will tell your app that it's being suspended.
Save whatever data you need to save in the event handler for that event.
Release resources, suspend notifications, etc. in the event handler as well.
On resume, you can check if the app was closed by the user using the ApplicationExecutionState enum. That may or may not be relevant to you, since there doesn't seem to be a way to differentiate why checkpoint event was fired and your only option is to save your state in the event handler no matter why it happened.
There are additional suspend/resume guidelines here, and you may find this sample app helpful.

Unhandled exception in an even handler code block

I am coding a DLL in C++/CLI that is called in a C# based GUI application. I throw a custom exception (derived from Exception class), which, if not swallowed in my DLL, is handled in the final catch block in the GUI code. It works well for all throws, save one:
Im my DLL I have implemented a handler that will listen to SerialPort::DataReceived events. If I get an incorrect packet, I raise a custom exception, which is rethrown in the outermosst try-catch block. The GUI is supposed to display this custom exception. But for some reason an exception raised in this block is not re-thrown. Instead I get an "Unhandled exception" message in Debug mode. When I run the exe directly by double clicking the exe (in release folder) it simply crashes. Apparently, exceptions raised in this event handler method are not handled by the GUI. Or maybe they are not passed to the GUI from my DLL. It doesnt create a problem for other parts of my dll. The only reason I can think for this different behaviour is that the event handler doesn't have a caller. Is my guess correct? or is there some other reason. Any clues on how I can handle this problem? I dont want my application to crash. I just want to raise an exception so that the message can be displayed to the user in the GUI and the application can stop communicating with the serial port.
You need to switch to the UI thread before throwing from that event handler. This is typically accomplished with System::Threading::SynchronizationContext, but if you're using WinForms you can alternatively use System::Windows::Forms::Control::BeginInvoke or System::Windows::Forms::Control::Invoke.