Run a new thread Qt C++ - c++

i want to run code in a seperate thread of the main application, for that i hava created some file :
thread2.h
#ifndef THREAD2_H
#define THREAD2_H
#include <QThread>
class thread2 : public QThread
{
Q_OBJECT
public:
thread2();
protected:
void run();
};
#endif // THREAD2_H
thread2.cpp
#include "thread2.h"
thread2::thread2()
{
//qDebug("dfd");
}
void thread2::run()
{
int test = 0;
}
And the main file called main.cpp
#include <QApplication>
#include <QThread>
#include "thread1.cpp"
#include "thread2.h"
int main(int argc, char *argv[])
{
QApplication a(argc, argv);
thread2::run();
return a.exec();
}
But it dosen't work...
Qt Creator tell me : "cannot call member function 'virtual void thread2::run()' without object"
Thanks !

Invoking it like this: thread2::run() is how you would call a static function, which run() is not.
Also, to start a thread you don't call the run() method explicitly, you need to create a thread object and call start() on it which should invoke your run() method in the appropriate thread:
thread2 thread;
thread.start()
...

A simple Thread Class that allows you to pass a pointer to a function is as follows:
typedef struct TThread_tag{
int (*funct)(int, void*);
char* Name;
int Flags;
}TThread;
class Thread : public QThread {
public:
TThread ThreadInfoParm;
void setFunction(TThread* ThreadInfoIn)
{
ThreadInfoParm.funct = ThreadInfoIn->funct;
}
protected:
void run()
{
ThreadInfoParm.funct(0, 0);
}
};
TThread* ThreadInfo = (TThread*)Parameter;
//Create the thread objedt
Thread* thread = new Thread;
thread->setFunction(ThreadInfo);//Set the thread info
thread->start(); //start the thread

Related

QObject::~QObject: Timers cannot be stopped from another thread

I have this very simple Qt code:
void thread_func()
{
int a1 = 1;
const char* a2[] = { "dummy_param" };
QApplication app(a1, (char**)a2);
QMessageBox msg(QMessageBox::NoIcon, "MyTitle", "Foo bar Foo bar", QMessageBox::Ok);
msg.exec();
}
If I call the above function from my main in a std::thread, it brings up the dialog:
int main()
{
std::thread t(thread_func);
t.join();
}
...but when I close it, I get the warning message:
QObject::~QObject: Timers cannot be stopped from another thread
I've checked that the thread affinity of both QApplication instance and msg is the same. Calling the thread_func function directly from my main() (without creating a std::thread) removes that message.
I am using Qt 5.15.1 on Windows 10.
What am I missing here? Thanks
It's not allowed to operate Qt GUI directly outside the main thread(GUI thead). You can emit signals.
The warning message says it all. Use a signal/slot mechanism to accomplish the same thing.
#include <QApplication>
#include <QMessageBox>
#include <QObject>
#include <QThread>
#include <QWidget>
class Widget : public QWidget
{
Q_OBJECT
public:
Widget(){}
public slots:
void displayMessageBox()
{
QMessageBox msg(QMessageBox::NoIcon, "MyTitle", "Foo bar Foo bar", QMessageBox::Ok);
msg.exec();
this->close();
}
};
class Worker : public QObject
{
Q_OBJECT
public:
explicit Worker() {}
void start() { emit askForMessageBox(); }
signals:
void askForMessageBox();
};
int main(int argc, char *argv[])
{
QApplication a(argc, argv);
Widget *widget;
Worker *worker;
QThread *thread(nullptr);
widget = new Widget();
worker = new Worker();
thread = new QThread(nullptr);
QObject::connect(worker, &Worker::askForMessageBox, widget, &Widget::displayMessageBox);
QObject::connect(thread, &QThread::started, worker, &Worker::start);
widget->show();
worker->moveToThread(thread);
thread->start();
return a.exec();
}

Qt Script Multithreading

I need to run multiple (up to 50 or more) Qt Script Functions concurrently. Running two or three Threads with Script Functions works just fine, but as soon as I run around 50 Threads, I get an Error and my Program crashes.
ASSERTION FAILED: globalData().dynamicGlobalObject (..\3rdparty\javascriptcore\JavaScriptCore\runtime/JSGlobalObject.h:411 QTJSC::JSGlobalObject* QTJSC::ExecState::dynamicGlobalObject())
My main.cpp looks like this:
#include <QCoreApplication>
#include <QScriptEngine>
#include <threadworker.h>
int main(int argc, char *argv[])
{
QCoreApplication a(argc, argv);
QScriptEngine engine;
QScriptValue val = engine.evaluate("(function() {var r = Math.random(); while(1>0) print(r);})");
ThreadWorker *worker[50];
for(int i=0;i<50;i++) {
worker[i] = new ThreadWorker(val);
QObject::connect(worker[i], SIGNAL(needsStarting()), worker[i], SLOT(startScript()));
emit worker[i]->needsStarting();
}
return a.exec();
}
This is my threadworker.h:
#ifndef THREADWORKER_H
#define THREADWORKER_H
#include <QObject>
#include <QScriptValue>
#include <QThread>
class ThreadWorker : public QObject
{
Q_OBJECT
public:
explicit ThreadWorker(QObject *parent = 0);
explicit ThreadWorker(QScriptValue function);
signals:
needsStarting();
public slots:
void startScript();
private:
QScriptValue value;
QThread thread;
};
#endif // THREADWORKER_H
This is my threadworker.cpp:
#include "threadworker.h"
#include <QDebug>
ThreadWorker::ThreadWorker(QObject *parent) : QObject(parent)
{
}
ThreadWorker::ThreadWorker(QScriptValue function)
{
value = function;
this->moveToThread(&thread);
thread.start();
}
void ThreadWorker::startScript()
{
value.call();
}
I expected, that independently of the amount, the Qt Script Threads would run just fine and I can't understand what is causing this contrary behaviour.
Putting the QScriptEngine on worker class and let moveToThread move it to the the worker thread, seems to solve:
class Worker : public QObject
{
Q_OBJECT
public:
explicit Worker(QObject *parent = 0);
public slots:
void startScript(const QString &function);
private:
QScriptEngine engine;
QScriptValue value;
};
However, it will be a challenge create so many threads and release them properly on application exit. I suggest you to use pooled threads, for example, QtConcurrent. QtConcurrent allows you (for example but not limited to) multithread with just functions, not necessarly classes, and with QFutureSyncronyzer you can in one call wait for all the threads you want to finish. See QtConcurrent:
#include <QtScript>
#include <QtConcurrent>
#define THREADS 50
void worker_function(const QString &function)
{
QScriptEngine engine;
QScriptValue value;
value = engine.evaluate(function);
value.call();
}
...
QFutureSynchronizer<void> synchronizer;
//Set the max pooled threads
QThreadPool::globalInstance()->setMaxThreadCount(THREADS);
//Start all threads and add them to the future synchronizer
for (int i = 0; i < THREADS; i++)
synchronizer.addFuture(QtConcurrent::run(worker_function, QString("(function() {var r = Math.random(); while(1>0) print(r);})")));
//Wait for all threads to finish
synchronizer.waitForFinished();
...

Qt 5: emit signal from non-Qt thread

What I am trying to achieve is a cross-platform TCP socket library built on top of Qt QTcpServer/Socket. I faced an issue that signals, emitted from a non-Qt thread without Qt event loop, are not received by objects in QThread with the event loop.
I have found that emitting from a non-Qt thread worked before with Qt::QueuedConnection connection type set explicitly, according to this and this questions. Those questions are rather old and relate to Qt 4. So I wonder if this functionality is still supported in Qt 5.
I have explored the Qt 5 source code and found:
Emitting a signal is just a call to QMetaObject::activate
QMetaObject::activate, in turn, calls queued_activate, if connection type is set to Qt::QueuedConnection or the current thread (emitter thread) is different from the thread receiver lives in (in my case, Qt::QueuedConnection is set explicitly).
queued_activate creates an event object and calls QCoreApplication::postEvent
QCoreApplication::postEvent does proper locking and puts the event into the receiver event queue. Despite postEvent is a static QCoreApplication function that uses self - a pointer to current static QCoreApplication singleton, it should work properly even if there is no global QCoreApplication object (i.e. self == 0).
Given this, I suppose that for signal&slot mechanism to work properly, only the receiver thread has to have the Qt event loop that will dispatch the event from the queue, correct me if I am wrong.
Despite that, emitting a signal from a non-Qt thread does not work for me. I have created as simple demo app as possible that demonstrates the malfunctioning of the signal&slot.
MyThread component just inherits QThread and moves inside itself (moveToThread) QObject-derived ThreadWorker.
MyThread.h:
#ifndef MYTHREAD_H
#define MYTHREAD_H
#include <QThread>
#include "ThreadWorker.h"
class MyThread : public QThread
{
Q_OBJECT
public:
MyThread();
signals:
void mySignal();
private:
ThreadWorker m_worker;
};
#endif // MYTHREAD_H
MyThread.cpp:
#include "MyThread.h"
#include "ThreadWorker.h"
MyThread::MyThread()
: m_worker(*this)
{
m_worker.moveToThread(this);
}
Thread worker is needed to live in MyThread thread and to connect to MyThread`s mySignal() signal.
ThreadWorker.h:
#ifndef THREADWORKER_H
#define THREADWORKER_H
#include <QObject>
class MyThread;
class ThreadWorker : public QObject
{
Q_OBJECT
public:
explicit ThreadWorker(const MyThread& thread);
public slots:
void mySlot();
};
#endif // THREADWORKER_H
ThreadWorker.cpp:
#include "ThreadWorker.h"
#include <QDebug>
#include "MyThread.h"
ThreadWorker::ThreadWorker(const MyThread& thread)
: QObject(0)
{
connect(&thread, SIGNAL(mySignal()),
this, SLOT(mySlot()),
Qt::QueuedConnection);
}
void ThreadWorker::mySlot()
{
qDebug() << "mySlot called! It works!";
}
Finally, the main.cpp:
#include <QCoreApplication>
#include <QDebug>
#include "MyThread.h"
int main(int argc, char *argv[])
{
// QCoreApplication a(argc, argv);
MyThread my_thread;
my_thread.start();
emit my_thread.mySignal();
qDebug() << "mySignal emitted";
my_thread.wait();
// return a.exec();
}
Note, that if I uncomment QCoreApplication creation, I get the correct output:
mySignal emitted
mySlot called! It works!
but if I leave it as is, I get only
mySignal emitted
QEventLoop: Cannot be used without QApplication
So, what is the reason signal&slot mechanism does not work in this case? How to make it working?
The error message tells you exactly what you need to know: you can't use the event loop system without QCoreApplication existing. That's all. All of your exploration into the innards of Qt was educational, but a red herring. None if it matters at all.
only the receiver thread has to have the Qt event loop that will dispatch the event from the queue
That's correct.
Does it mean that if I create QCoreApplication inside QThread, this system should work?
You might create it on any thread (in contrast to QGuiApplication that can only live on the main thread). But make sure that you link statically with Qt. Otherwise, if you're linking with system Qt, you'll become binary incompatible with any process using the same Qt if you create a second instance of the application. Thus, if you use system Qt you can work around by inspecting whether an application instance exists, and only create one if it doesn't exist yet.
Furthermore, you shouldn't really need to create the application instance in a custom thread. Your library should accept an initialization call that should be performed in the main thread of the calling process. This initialization can create an application object if one doesn't exist.
// https://github.com/KubaO/stackoverflown/tree/master/questions/twothreads-41044526
#include <QtCore>
// see http://stackoverflow.com/questions/40382820
template <typename Fun> void safe(QObject * obj, Fun && fun) {
Q_ASSERT(obj->thread() || qApp && qApp->thread() == QThread::currentThread());
if (Q_LIKELY(obj->thread() == QThread::currentThread()))
return fun();
struct Event : public QEvent {
using F = typename std::decay<Fun>::type;
F fun;
Event(F && fun) : QEvent(QEvent::None), fun(std::move(fun)) {}
Event(const F & fun) : QEvent(QEvent::None), fun(fun) {}
~Event() { fun(); }
};
QCoreApplication::postEvent(
obj->thread() ? obj : qApp, new Event(std::forward<Fun>(fun)));
}
class Worker : public QObject {
Q_OBJECT
QBasicTimer m_timer;
int n = 0;
void timerEvent(QTimerEvent *event) override {
if (event->timerId() == m_timer.timerId())
emit hasData(n++);
}
public:
Q_SIGNAL void hasData(int);
Q_SLOT void onData(int d) { qDebug() << QThread::currentThread() << "got data" << d; }
void start() {
safe(this, [this]{ m_timer.start(50,this); });
}
void quit() {
safe(this, [this]{ m_timer.stop(); thread()->quit(); });
}
};
class Library {
QByteArray dummy{"dummy"};
int argc = 1;
char *argv[2] = {dummy.data(), nullptr};
QScopedPointer<QCoreApplication> app;
static Library *m_self;
struct {
Worker worker;
QThread thread;
} m_jobs[3];
public:
Library() {
Q_ASSERT(!instance());
m_self = this;
if (!qApp) app.reset(new QCoreApplication(argc, argv));
for (auto & job : m_jobs) {
job.worker.moveToThread(&job.thread);
job.thread.start();
job.worker.start();
QObject::connect(&job.worker, &Worker::hasData, &m_jobs[0].worker, &Worker::onData);
}
}
~Library() {
for (auto &job : m_jobs) {
job.worker.quit();
job.thread.wait();
}
}
static Library *instance() { return m_self; }
};
Library *Library::m_self;
// API
void initLib() {
new Library;
}
void finishLib() {
delete Library::instance();
}
int main()
{
initLib();
QThread::sleep(3);
finishLib();
}
#include "main.moc"

My QThread finished but I cannot get the signal

The run method of my QThread is finishing, but I cannot get the signal.
Here is the entire code:
My thread header:
#ifndef MYTHREAD_H
#define MYTHREAD_H
#include <QThread>
#include <QDebug>
#include "mydataobject.h"
class MyThread: public QThread
{
Q_OBJECT
public:
MyThread(MyDataObject data,
bool useData);
private:
void run();
signals:
void resultsReady(MyDataObject data);
private:
MyDataObject data;
bool useData;
};
#endif // MYTHREAD_H
My thread code:
#include "mythread.h"
MyThread::MyThread(MyDataObject data, bool useData)
{
this->data = data;
this->useData = useData;
}
void MyThread::run()
{
if( useData )
{
data.calculate(); // Do something
}
emit resultsReady(data);
qDebug() << "Thread finished";
}
My test header:
#ifndef THREADTESTER_H
#define THREADTESTER_H
#include <QDebug>
#include "mythread.h"
class ThreadTester: public QObject
{
Q_OBJECT
public:
ThreadTester();
void runTests();
public slots:
void threadFinished(MyDataObject data);
private:
MyDataObject data;
};
#endif // THREADTESTER_H
My test code:
#include "threadtester.h"
ThreadTester::ThreadTester(){}
void ThreadTester::runTests()
{
qRegisterMetaType<MyDataObject>("MyDataObject");
MyDataObject data;
MyThread* thread = new MyThread(data, true);
connect(thread, SIGNAL(resultsReady(MyDataObject)),
this, SLOT(threadFinished(MyDataObject)));
thread->start();
thread->wait();
}
void ThreadTester::threadFinished(MyDataObject data)
{
qDebug() << "TEST";
this->data = data;
}
Main function:
#include <QApplication>
#include "threadtester.h"
int main(int argc, char *argv[])
{
QApplication a(argc, argv);
ThreadTester threadTester;
threadTester.runTests();
return a.exec();
}
Why the public slot threadFinished is never called?
Note: the "Thread finished" message is appearing, but the "TEST" message not.
What happens in your code:
create QApplication
create ThreadTester
run method ThreadTester::runTests which does following:
creates tread object
connect to result
start thread
wait for thread…
now thread does it job and emits the signal
since you connect used default connection method, slot invocation is scheduled to be run in event loop which didn't start yet.
thread completes
…wait for thread completes (probably here you expecting final result, but look what happens later)
event loop is started
event loop executes queued invocation of slot ThreadTester::threadFinished
event loop waits for next events

QT and C++: can't call function outside main() function

I would like to know how to call the function Do_Download() from the SocketTest class outisde the main() function.
The first cTest.Do_Download() does work, but when I call the test() function, the csTest.Do_Download() does not work.
So it looks like I can only acces SocketTest from inside the main() function, and not from any other function.
Does somebody know how this can be solved?
Thanks!
main.cpp:
int main(int argc, char *argv[])
{
QApplication a(argc, argv);
MainWindow w;
w.show();
SocketTest cTest;
cTest.Do_Download();
return a.exec();
}
void test()
{
qDebug() << "test main functie";
SocketTest csTest;
csTest.Do_Download();
}
SocketTest.h:
#ifndef SOCKETTEST_H
#define SOCKETTEST_H
#include <QObject>
#include <QTcpSocket>
#include <QDebug>
#include <QHttp>
#include <QFile>
#include <QString>
class SocketTest : public QObject
{
Q_OBJECT
public:
explicit SocketTest(QObject *parent = 0);
void Do_Download();
signals:
public slots:
void stateChanged ( int state );
void responseHeaderReceived ( const QHttpResponseHeader & resp );
void requestFinished ( int id, bool error );
private:
QTcpSocket *socket;
QHttp *http;
QHttp *http2;
};
#endif // SOCKETTEST_H
If your DoDownload function is doing anything asynchronously (likely, when dealing with the Qt networking classes), the SocketTest you are creating in test() is being destroyed before it can act on any return value.
It works in main() because the event loop starts and the SocketTest instance hangs around.