Add transition without sender and receiver Qt 5.2 - c++

I implemented a three state machine and declared a function that change the current state of the machine:
void changeState(s1);
that contains the following command in order to change machine state:
s0->addTransition(s1)
When I compile it no error appears, but when I run the application the following message appears:
QObject::setParent: Cannot set parent, new parent is in a different thread
Shall I neccesarily connect the trnasition to a signal?
Thanks a lot for your help.
Luca

With what you explained, I would tell the issue is not from the connection itself. QT doesn't accept parent/child to be located in different thread. This means your whole state machine has to run in one single thread.
In order to run it in a thread different than the main thread you need to create your QStatemachine without parent, add all state and then move it to a different thread using QObject::moveToThread.
You may also fully create your state machine from an other thread altrough I never did that. Creating element in the main is most of the time a more straight forward implementation. You may then move them as you want.
And yes, you may add transition without signals. In this case the state just has to be activate by other means, by reimplementing QAbstractTransition.

Related

Cross thread call a.k.a run on main/UI thread from other thread without dependencies needed

I'm on some c++ mobile product, but I need my apps main thread is still running without any blocking when doing some heavy work on the background thread and run back on main thread. But I realized there is no runOnMainThread/runOnUIThread in c++ thread api. I trying to figure it out the issue and found that need to depend library, or create your own thread event queue. Although it is good, but i am thinking to have a behavior which can runOnUIThread.
How it does not work: the mentioned library creates a timer, installs a SIGALRM signal handler and dispatches queued tasks when signals are fired. This allows tasks being processed on the main thread even when it is busy. However POSIX permits only a small set of async-signal-safe functions to be invoked inside of signal handler. Running arbitrary с++ code inside of signal handler violates that restriction and leaves application in hopelessly doomed state.
After some research and development, I've created a library called NonBlockpp
it is a small c++ library to allow c++ mobile application able to process the heavy and time consuming task on background and back to Main thread again, It’s been tested and fired the main thread event.
It also allow to save the tasks and fire them later, all the task has no blocking each other and thread safety.
How it works:
If you found any query or suggestion, please don't hesitate to raise an issue and we can discuss it together.
The project has rectify from signal to pollEvent due to signal handler might not be safe to use.
Please take a look the new changed.
NonBlockpp
Usage

Qt c++ signal slots - necessary to clear signals?

sorry, I can`t be mor speciic, because I am stuck in a jumble of classes, and several signal/slots.
In my project I use several signal-slots. Now I have the impression that depending on how often I start a routine that emits a signal my slot is run several times.
For the first rum my Slot is run once; In the second run it is run twice.... When I close my program I start again with running it once.
Is there a need to somehow finish/end/delete a signal after it is sent ?
Thank you
Take a look to the Qt::UniqueConnection flag.
You're connecting signals to slots in reaction to events. This causes duplicate connections as the events are repeated. In most cases, this is a bug. Usually you want to set up connections in class constructors, or otherwise when new objects are created and added to your system.
The unique connection will mask the problem, but not solve it - the solution is to move the connect statements to locations where they won't be re-executed.
A a signal stays connected, until either the disconnect() is used, or the sender or receiver is deleted.
So each signal/slot pair has to beconnected only once, and then every time the signal is emitted, the slot gets called.

How can I use multi thread in Qt/c++ to access my data base with an Api?

I have a problem, I'm connecting my program to the data base with an Api, to do this I use the network and webkit webkitwidgets funtions in Qt. I have been able to do this without any problem.
The think it's that I have to call some funtions in the api class from different threads.
Firts I try passing the api object to the Qthread class, but I'm getting this error:
#QObject: Cannot create children for a parent that is in a different thread.
(Parent is SerialPort(0x24a1738), parent's thread is QThread(0x24a1770), current thread is QThread(0x18a8b0)
So I try ussing signals ans slots, it work with the firts function I use, a funtion to create what a call in my data base a log, but when I try to close the log, so I can send the information needed. I get this error:
QEventLoop::exec: instance xxxxxx has already called exec()
What is the best way to work with Threads to avoid this problems ??
You haven't provided any code, only error messages. Since I have to guess, I'll say that you're creating a QObject-derived worker object and using the QObject::moveToThread method to change its thread affinity. The problem in this case is that you've already given the worker object a parent. You can't use moveToThread on an object that already has a parent. So, don't set the parent of your worker object when you create it and you should be good-to-go.
As others users have commented, you will need to use signals & slots to initiate queries, etc. in your worker object. Qt will handle synchronization issues via the thread's event loop, so you don't have to worry about mutex locking, etc (as long as you use only sig/slot to invoke methods and get output values from the worker object).
Don't forget to call QThread::start to get the thread's event loop started.
NOTE 1: I assume you're using a fairly recent version of Qt (>= 4.8).
NOTE 2: If you're using QSqlDatabase and friends to access your DB, make sure to create the DB connection in the worker object after it is moved to the new thread.

QThread doesn't start

Sorry for the length of this post. But I am stuck for two days now....
I am working on a Qt 4.6 Windows application that communicates with a hardware device through ActiveX.
When I send a command, the device does some stuff and when it's done (can take up to one minute) it emits a signal. I need to wait this signal to know if everything went okay (or not) and do some actions in consequence.
A command is sent to the device when a user clicks a button. And obviously, I don't want the HMI to freeze.
I am convinced I have to use threads. So I identified three threads:
the main thread corresponding to the HMI
the hardware controller (which locks after a command is sent and waits a signal)
a hardware notification listener that continuously gets signals from the hardware and unlock the thread 2
Here is the class diagram:
And a sequence diagram to show how I see things:
Explanations:
When the user launches my application, the HMI is created. The constructor of the HMI calls the constructor of the Worker. It constructs the hardware QAxObject. Then it constructs the HardwareListener giving in reference: the QAxObject, the QMutex and the QWaitCondition. Then the constructor of the Worker moves the HardwareListener object to another thread and starts it. Finally, the constructor of the HMI starts the thread of the Worker.
Then, when the user clicks a button, the HMI sends a signal to the Worker. The Worker sends a command to the hardware (that command may block the thread several seconds that's why I need the HardwareListener in another thread not to miss a signal). Then the Worker waits for a QWaitCondition (after having locked the QMutex).
After that, the hardware device sends a signal to the HardwareListener which wakes up the QWaitCondition. Therefore, the Worker thread stops waiting and finishes its actions. Finally, the Worker informs the HMI.
Problem:
The Worker and HardwareListener threads aren't created/started. Everything is done in the main thread so, obviously, it doesn't work. I don't exchange any special object between threads (so no need for qRegisterMetaType())
Question:
Is my design acceptable? There may be some other ways to do but it seems to me this is the most straightforward (taking into account the complexity).
EDIT:
I've changed my code to remove the QThread inheritance. I use the moveToThread() method instead.
Now the threads work fine. HOWEVER I have an ActiveX error: QAxBase: Error calling IDispatch member NewProject: Unknown error.
It seems the interfacing with the hardware is broken... Any idea?
Here is something interesting:
You cannot move a QAxObject to another thread once it has been created.
SOLUTION:
Here is what I have found.
Inheriting from QThread is not good design. If the work you are doing is computational heavy I would recommend using QThreadPool. I not than its better to use an asynchronous design. This means only calling function which never block and instead connect to signals notifying you that something happened.
So for example sending the command to the hardware and emitting a signal once the hardware is done. If the hardware API doesn't supply async functions than you are stuck with using threads.
QtConcurrentRun can help with that. Usually you should not need to touch threads yourself; and its a hell of a lot easier without.

QProcess: Destroyed while process is still running

I am using Qt for developing a custom control interface to xmgrace, a 2D plotting library.
I have 3 components in my project:
A GUI made in Qt
A QThread which runs some shared object code from C in a background thread.
An xmgrace window connected to both the above using a pipe. (Using the grace_np library)
Communication from (1) --> (2) is done by changing status of some global variables declared in the shared object code.
Communication from (1) --> (3) & (2) --> (3) is using built in functions provided by the grace_np library.
Now, communication from (2) --> (1) is what is causing problems. I tried 2 possible ways I could think of:
a) Declaring a shared object in Qt code which emits a Qt Signal and is called within the C code.
b) Returning from the thread and using the return value to perform some operation and then restart the thread.
Both these methodologies have given unreliable results. My GUI gets stuck/causes segmentation fault and I get the message:
QProcess: Destroyed while process is still running
I am not using the QProcess class anywhere in my code. So this has become a mystery.
Please provide some info on what could be the possible causes for this.
PS: The pipe to (3) is one way and is required that way only.
Edit 1:
FYI I'm using Qt 4.2, So I can't use the QObject approach and then use a movetothread()
I'm sorry for not putting the code, as I can't due to company policies and also because I don't know what to put (Its too huge). The shared c code is 400k+ lines
I believe I have found the culprit to my problem. It seems that using the class QMessageBox is causing this problem. I was initially using static function of QMessageBox. Now I have tried declaring it over both the stack and the heap, but the problem still persists.
But I have found that removing all calls to QMessageBox from my code solves the problem.
But then the problem now is, how do I show messages?
I am just speculating here, but is it possible that the modal nature of QMessageBox is blocking the pipe existing between my program and xmgrace and subsequently causing it to quit? Then creating a custom QMessageBox (non modal) might solve this issue.
Edit 2:
I'm not calling the QMessageBox from the worker thread. Plus the way I'm using the worker thread, it never returns unless I close the program. To give an idea my QThread::run function is of the form:
QThread_Object::run()
{
c_init();
c_main();
}
where c_init & c_run are functions linked from shared c code. So it is impossible to call a QMessageBox from within these directly.
For now I'm planning on doing away with the QMessageBox and using the QMainWindow status bar instead. But then it doesn't give the entire functionality. I suppose this could be a bug in Qt 4.2
Edit 3:
I mentioned earlier that communication from (2) --> (1) was what was causing problems. Now I have done away with this communication completely and have discovered more precisely that the problem is caused by invoking QMessageBox anytime after starting the worker thread. Earlier the communication mentioned above was causing Qt to emit a signal indirectly and invoke a QMessageBox which I believe was the culprit.
Edit 4:
Ok, I forgot to mention the biggest mystery surrounding this problem since the beginning. I basically work(Place A) via ssh on a workstation(Place B) on which I code and run this program.
B is connected on 2 physical networks. A is connected to B through Network 1. Now this problem has never occured while working from my terminal at A (ie on ssh via Network 1). But it consistently occurs when I access B directly or through ssh over Network 2. Please note that every time the code is executed on B only. Both these networks are used by hundereds.
Edit 5
Finally, I have solved my problem by sub-classing QDialog and making a custom MessageBox as I don't really require the extended functionality of QMessageBox. I still don't know what precisely within QMessageBox was causing the problem. I suppose some bug within Qt which will always remain a mystery.
Since there's no code I'm shooting in the dark a little here, but it sounds like your QProcess was created on the stack, intentionally or not, or your QThread is getting destroyed prematurely. I'd put money on your QThread objects being launched incorrectly. It's hard to blame you since the documentation is (or was until recently) screwy. Consider reading this thread and this thread and don't sub-class QThread at all.
Edit:
If QMessageBox is your culprit, then I'm guessing that you're displaying it from the child thread. From the documentation:
In GUI applications, the main thread is also called the GUI thread
because it's the only thread that is allowed to perform GUI-related
operations.
There are several ways to display messages from a child thread. Personally, I use qt's error reporting scheme and redirect qCritical, qDebug, etc to stderr. Another easier way to do it would be for you to emit a QString signal from your worker thread that's caught by your GUI thread, which then displays/collects the error. I like to have my MainWindow collect the errors and then display them all at once when the worker thread finishes.
Edit 2:
Since the problem seems to be QMessageBox being modal (i.e., blocking your main thread while the worker thread moves forward), you can easily solve this by using QMessageBox in its non-modal modes. Simply pass 0 as the parent widget in the QMessageBox constructor/static function. Processing will continue without waiting for the user to exit the window--this might also result in multiple message boxes being open at the same time. If that helps you avoid the error, go over your code carefully to make sure the windows are properly destroyed after closing.