Unsolved QThread
-
Hi everyone!
Could I run a single thread to run two different slots?
Here is the example:
connect(thread, SIGNAL(started()), seq, SLOT(startOn()));
connect(thread, SIGNAL(started()), seq, SLOT(startOn1()));Will both "startOn" slots will run at the same time?
If not, then what should I do to run these both at the same time? -
-
@jsulm thanks for the reply.
Can I associate two threads of the two different classes in toggle function of single push-button so that these two threads can run simultaneously once the button is toggled?
-
@Mar_60
Yes, you can have separate threads running at the same time started from the same signal.Don't forget that your threads are not allowed to update widgets etc. in the UI thread.
-
@JonB Thank u very much for the reply.
I have main table widget which I need to update by running my threads. So can I do it? If not, then how it can be done?
One more question, If I start my both threads in toggle function of pushbutton then, Will they both run simultaneously or one by one?
For example:
void MainWindow::on_startON_toggled(bool checked)
{
thread_1->start();
thread_2->start();
}Thanks in Advance.
-
I have main table widget which I need to update by running my threads. So can I do it? If not, then how it can be done?
Not directly. You must emit a signal from the thread where they want to update something, and your main GUI thread can have a slot for that to do whatever is needed for the update. Which will happen the next time the GUI thread is scheduled and reads from the event queue (
Qt::QueuedConnection
, because you are cross-thread).Your two separate threads will run "simultaneously", "in parallel" with main GUI thread, as scheduled by the OS. They would only run in serial, "one by one" if you put it e.g.
thread_1->wait(); thread_2->start();
. -
If you want to update a table widget in separate threads this will get quite involved. As mentioned before only the GUI thread is allowed to change widgets. Step 1 for you would be to replace the
QTableWidget
with aQTableView
. TheQTableView
connects to a model which you'll have to implement yourself (by deriving from the right Qt model class). This approach will separate the data from the representation (i.e. the GUI). Now, you can manipulate the data in a separate thread.Even if you just have a single thread (different from the GUI thread) you need to think about synchronization. This will be the hard part to do right because you do not want any synchronization mechanisms in your model when updating the GUI. Here is my first hunch how you might not run into trouble: 1. Have a pointer to the actual data in your model class. You can make a copy of the data and modify the copy and finally by just swapping a pointer update the data. Even for large data the final swap will be fast. 2. Update the data of the model by calling a slot in the GUI thread. Make sure that the slot is executed inside the GUI thread and not the thread you are calling from. The event loop of the GUI thread will work as synchronization between updating the data and redrawing the
QTableView
. In this way theQTableView
will never have a spliced view of mixed old and new data. 3. Finally update theQTableView
by callingupdate()
to refresh the widget.For making sure that the slot is executed in the GUI thread there are two approaches. The first is to connect a signal of the other thread with a slot of the model living in the GUI thread. Just emit the signal and everything will be fine. The other approach is to invoke a function explicitly in the context of the GUI thread:
QMetaObject::invokeMethod(qGuiApp, [...](){ model->updateData(newDataPointer); tableView->update(); });
qGuiApp
is the context object when invoking the function. If called from a different thread it will queue an event into the event loop of the GUI thread.Finally, if you want to update the data from two different threads at once, you might need more involved synchronization between these two threads. I would do this only after the approach I mentioned above works with only 1 additional thread.