QThread blocking main application - c++

I have a simple form UI that has a slot for a button, starting a thread:
void MainWindow::LoadImage()
{
aThread->run();
}
And the run() method looks like this:
void CameraThread::run()
{
qDebug("Staring Thread");
while(1)
{
qDebug("ping");
QThread::sleep(1);
}
}
When I click the button that calls LoadImage(), the UI becomes unresponsive. I periodically see the "ping" message as the debug output but the UI hangs, does not respond to anything.
Why is my thread not running separately? CameraThread derived as public QThread
I am using gcc version 4.4.3 (Ubuntu 4.4.3-4ubuntu5) with QT libraries and QT Creator from Ubuntu 10.04(x86) repositories.

Short answer: Start your thread by calling aThread->start(); not run(), and make sure you thread's run() method is protected (not public).
Explanation
Calling start() is the correct way to start the thread, as it provides priority scheduling and actually executes the run() method in its own thread context.
It looks like you are going to be loading images in this thread, so I'm going to include some tips before you run into pitfalls many people fall into while using QThread
QThread itself is not a thread. It is just a wrapper around a thread, this brings us to..
signals/slots defined in the CameraThread class will not necessarily run in the thread's context, remember only the run() method and methods called from it are running in a separate thread.
IMHO, subclassing QThread in the majority of cases is not the way to go. You can do it much simpler with the following code, and it will save you many headaches.
class ImageLoader : public QObject {
Q_OBJECT
public slots:
void doWork()
{
// do work
}
};
void MainWindow::MainWindow(/*params*/)
{
ImageLoader loader;
QThread thread;
loader.moveToThread( &thread );
connect( this, SIGNAL( loadImage() ), &loader ,SLOT( doWork() ) );
thread.start();
// other initialization
}
void MainWindow::LoadImage()
{
emit loadImage();
}
Also read the Qt blog regarding this topic.

You have to call thread->start() not run... run is an entry point for thread. Thread is started with start. You call directly run, that's why you block your gui. Check documentation of QThread. virtual void QThread::run() is protected (not without a reason)

I think the problem could be that you are not calling QtCore.QThread._init__(self) in the constructor. I had the same issue. Also I think you should not override the start function, just override the run() function. This solved the same issue that I was having. Even without any sleep() delays, the window should be responsive.

Related

how to create a detached thread with QThread, like in std::thread

i've created a thread in QT using QThread but the parent of the thread is exiting before the thread finishes which itself is running infifnitely.
//mainwindow.cpp
void MainWindow::showEvent(QShowEvent *ev)
{
QMainWindow::showEvent(ev);
showEventHelper();
}
void MainWindow::showEventHelper()
{
//back-end thread
ServerStart *serverstart = new ServerStart();//initializing a pointer to my class
QThread thread;
serverstart->moveToThread(&thread);
QObject::connect(&thread, &QThread::started, serverstart, &ServerStart::run);
thread.start();
//in std::thread i used to detache it like so:
//std::thread worker(serverMain);
//worker.detach();
}
IMPORTANT: I'm making a GUI project. and my infinite thread is inside an onShow() method that needs to exit in order for the app to continue and make the UI. and I also want to send signals in the future from the thread to the main thread and the main thread should be able to respond and modify the UI according to the signal.
how can i do the same in QT?
You can't, however according to KDAB documentation of proper QThread usage you can emulate such behavior by connecting QThread::finished to QThead::deleteLater as shown from their document for QThread here https://www.kdab.com/wp-content/uploads/stories/multithreading-with-qt-1.pdf

Qt - does a QTimer::timeout() signal result in a QEvent?

Qt doc:
If no event loop is running, events won't be delivered to the object.
For example, if you create a QTimer object in a thread but never call
exec(), the QTimer will never emit its timeout() signal. Calling
deleteLater() won't work either. (These restrictions apply to the main
thread as well.)
Does this mean that signal void QTimer::timeout() will also issue a QEvent?
If so, where does the Qt doc state this?
where does the Qt doc state this?
Nowhere, because it shouldn't matter to the user of QTimer. The timer event is an implementation detail. It is delivered to the timer object itself, so you'd really have to go out of your way to intercept it. Here's how QTimer works:
class QTimer : public QObject {
Q_TIMER
QBasicTimer m_timer;
protected:
void timerEvent(QTimerEvent * ev) override {
if (ev->timerId() == m_timer.timerId())
emit timeout();
}
/*...*/
};
If you think about it, there's no way of emitting any signals without running the code that emits the signals, and the only way to safely run such code that emits things asynchronously is to code for run-to-completion chunks that cede control to the event loop at every opportunity. The event loop is notified by the platform that a timer has timed out, and emits a signal right then. You'd be in deep trouble if Qt issued signals such as timer timeouts from intrusive asynchronous callbacks like Unix signals: just read about how few things you can do while in a signal handler - it'd be no different than an interrupt handler.

Proper way to run managable background thread with QThread

I need to run few background threads which must be managable in a way that I can safely stop it anytime. Threads should do some repetable task.
I read documentation and the best way which I can find is to subclass QThread and reimplement run() method:
class BackgroundThread: public QThread
{
Q_OBJECT
virtual void run() Q_DECL_OVERRIDE
{
while (true)
{
// do some routine task
// sleep ...
}
}
};
I like this because I can run code in separate thread and I don't need to do unconvient Qt magic with moveToThread and connecting up to 10 signals/slots to properly manage thread resources.
The problem is that I can't find a way to safely stop the thread. I don't want to terminate it in a random place of execution, I would want it to stop when next iteration ends. The only way to achive it which I see now is to add some atomic flag to thread class and set it from main thread when I need to stop it, but I really don't like this solution.
What is the best way to implement managable background thread using Qt5?
You don't need any magic and "10 signals/slots". Just create your worker:
class Worker: public QObject
{
...
public slots:
void routineTask();
}
Somewhere in your code:
QThread bckgThread;
bckgThread.start();
Worker worker;
worker.moveToThread(&bckgThread);
Connect some signal to the routineTask slot to call it or use QMetaObject::invokeMethod.
And when you are done with the thread, just call:
bckgThread.quit();
bckgThread.wait();
That's pretty simple pattern. Why go the hard way and subclass QThread?

QT - force an object to process incoming signals

I am wondering how to tell a QObject to process all signals and call the slots associated with them. Here's the concrete problem I am having, for a better description of the question:
My program consists of three Qthreads : Main, Communication and Input.
The communication thread handles communication via the network, the Input thread handles user input, and both have several signal-slot connections to the main thread. Whenever a network event occurs, or whenever the user inputs a commandline command, a signal from the respective thread is called, which then activates the appropriate connected slot in the main thread. The main thread's role is to process these events. My code looks as follows:
QApplication a(argc, argv);
CommObj co; //inherits from QThread
co.start(); //Starts the thread
InputObj io; //inherits from QThread
io.start(); //Starts the thread
MainObj u(&co,&io);
return a.exec();
Now, what I want to achieve is for the main thread to not reach the last line.
My intentions are to call a method run() within the constructor of MainObj which is going to do something along the lines of this:
void run ()
{
forever
{
//process all signals..
}
}
However, I do not know how to implement the process all signals part. Any advice on how this could be done (including workarounds) would be very welcome.
This is completely unnecessary. a.exec() runs an event loop that will receive and process the events sent by other threads.
When a slot is invoked due to a signal being emitted in a different thread, Qt is posting a QMetaCallEvent to the receiver object. The QObject::event method is able to re-synthesize the slot call based on the data in the event.
Thus, you need to do nothing. a.exec() does what you want. Feel free to invoke it from MainObj's constructor, as qApp->exec() or as QEventLoop loop; loop.exec(), but that's rather bad design.
The real questions are:
Why do you need MainObj's constructor to spin an event loop?
What sort of "user input" are you processing in the io? You can't access any GUI objects from that thread.
Why are you deriving from QThread if you're using Qt's networking? You definitely don't want to do that - it won't work unless you spin an event loop, so you might as well just use a QThread without changes. Well, to be safe, you need just to make the thread destructible, so:
class Thread {
using QThread::run; // make it final
public:
Thread(QObject * parent = 0) : QThread(parent) {}
~Thread() { requestInterruption(); quit(); wait(); }
};
Anyway, by not using standard QThread that spins an event loop, the communication will be one way. Nothing in such threads will be able to react to signals from other threads.
You need to rearchitect as follows:
Use the Thread class as above. It's safe to be destructed at any time.
Have worker objects that run asynchronously using signals/slots/timers.
Move constructed workers to their threads.
What you need is the processEvents function. For example, if you don't want the user to be able to interact with widgets, but you want the graphics to update, use
processEvents(QEventLoop::ExcludeUserInputEvents);
See the documentation for details.

QT QDialog not hiding properly when show/hide called quickly

I have a QDialog on my main thread and I have some logic that happens on a separate thread. When the logic begins, a signal is emitted connected to show() on the dialog. When the logic ends, a signal is emitted that is connected to hide() on the dialog. When the logic actually does work, the dialog is show/hide properly. If the logic does "nothing" and the signals are just emitted sequentially, the dialog doesn't always show/hide properly.
My connections are made similar to this:
class MainWindow : public QMainWindow
{
Q_OBJECT
public:
MainWindow(QWidget* parent = 0) :
Ui(new Ui::MainWindowUi),
Transferer(new DataTransferer()),
TransferProgress(this),
TransferThread()
{
Ui->setupUi();
connect(&Transferer, SIGNAL(Begin()), &TransferProgress, SLOT(show()));
connect(&Transferer, SIGNAL(End()), &TransferProgress, SLOT(hide()));
Transferer.moveToThread(&TransferThread);
TransferThread.start();
Transferer.DoStuff(true);
}
virtual ~MainWindow()
{
TransferThread.quit();
TransferThread.wait(1000);
delete Ui;
Ui = NULL;
}
private:
Ui::MainWindowUi* Ui;
DataTransferer Transferer;
TransferProgressDialog TransferProgress;
QThread TransferThread;
}
The logic looks similar to this:
class DataTransferer : public QObject
{
Q_OBJECT
public:
DataTransferer(QObject *parent) : QObject(parent) {}
virtual ~DataTransferer() {}
void DoStuff(bool dontDoStuff)
{
emit Start();
if (!dontDoStuff)
{
QThread::sleep(1);
}
emit End();
}
}
When the DataTransferer does stuff, everything works fine. When the dialog is shown and hidden in rapid succession, I get the ghost dialog approximately every other time I call DoStuff().
I used QThread::currentThreadId() and verified that the dialog and logic are running on separate threads.
Why would my dialog not hide properly in this case? Should I just force my logic to always run for at least a few hundred milliseconds (that solution is bad)? Is there a way I can have my dialog make sure it's fully loaded before trying to hide itself? Should I handle these signals/slots differently?
EDIT: I've currently resigned to just putting a QThread::sleep(1) after I emit the signal to show() the dialog. I don't like this solution, but nothing else has seemed to work. The sleep(1) allows the dialog to come all the way up before hiding it. I was also able to get this to work with QThread::msleep(10), but that still resulted in the ghost dialog about 1 in 6 tries.
I tried using a member QMutex in the dialog logic whenever I called either show() or hide(), but this didn't work.
I changed all cross-thread connections to use Qt::BlockingQueuedConnection and Qt::QueuedConnection and neither attempt was successful.
I tried moving the slot connections from the dialog to the object that sets up the connections and then calling the slots directly, but that didn't prove successful either.
I have the same issue, show dialog and when get some signals to close it, when time less than 20ms(which means quickly hide the dialog), it will left a ghost dialog.
So, i just use
QTimer::singleShot(50, this, [this](){
hide(); //hide dialog
});
in close handler function. It seems work well.
My guess is that the problem occurs because "show" and "hide" calls interlace. To verify this, use a semaphore - lock the object until show have finished, and wait on it in hide. Also look at the top-voted answer here for another possible (perhaps better) solution: connecting signal/slot across different threads between QObjects
Use Qt::BlockingQueuedConnection to connect signals to slots. Be sure that event loop of main thread is not blocked. Also, if your worker thread uses a lot of cpu time - you may call QThread::yeldCurrentThread() call.