qt How to put my function into a thread - multithreading

I'm a QT newbie. I have a class extend from widget like:
class myclass: public Qwidget
{
Q_OBJECT
public:
void myfunction(int);
slots:
void myslot(int)
{
//Here I want to put myfunction into a thread
}
...
}
I don't know how to do it. Please help me.

Add a QThread member then in myslot move your object to the thread and run the function.
class myclass: public Qwidget
{
QThread thread;
public:
slots:
void myfunction(int); //changed to slot
void myslot(int)
{
//Here I want to put myfunction into a thread
moveToThread(&thread);
connect(&thread, SIGNAL(started()), this, SLOT(myfunction())); //cant have parameter sorry, when using connect
thread.start();
}
...
}
My answer is basically the same as from this post: Is it possible to implement polling with QThread without subclassing it?

Your question is very broad . Please find some alternatives that could be beneficial to you :
If you want to use signal/slot mechanism and execute your slot within a thread context you can use moveToThread method to move your object into a thread (or create it directly within the run method of QThread) and execute your slot within that thread's context. But Qt Docs says that
The object cannot be moved if it has a
parent.
Since your object is a widget, I assume that it will have a parent.
So it is unlikely that this method will be useful for you.
Another alternative is using QtConcurrent::run() This allows a method to be executed by another thread. However this way you can not use signal/slot mechanism. Since you declared your method as a slot. I assumed that you want to use this mechanism. If you don't care then this method will be useful for you.
Finally you can create a QThread subclass within your slot and execute whatever your like there.
This is all I could think of.
I hope this helps.

Related

Monotouch PerformSelector on specific thread with multiple arguments and callbacks

I've been having some issues with threading in monotouch. My app makes use of an external library which I've linked with and it works fine. Because of the nature of the app and the library I have to make all the calls to it on a single separate thread.These calls will generally be :
Random non deterministic caused by user
Every t miliseconds(around 20ms). Like an update function
After reading for a bit I decided to try out NSThread. I've managed to call the Update function by attaching an NSTimer to the thread's RunLoop and it's all working fine. The problem that I'm having now is calling other methods on the same thread. I read somewhere that using PerformSelector on the RunLoop adds the selector invocation to the RunLoop's queue and invokes it when available, which is basically exactly what I need. However the methods that I need to call :
Can have multiple paramteres
Have callbacks, which I need to invoke on the main thread, again with multiple parameters
For the multiple parameters problem I saw that NSInvocation can be a solution, but the life of me I can't figure out how to do it with monotouch and haven't found any relevant examples.
For the actuals calls that I need to make to the library, I tried doing a generic way in which I can call any function I choose via delegates on a particular thread, which sort of works until I'm hit with the multiple parameters and/or callbacks to the main thread again with multiple parameters. Should I maybe just register separate selectors for each (wrapped)function that I need to call from the library?
I'm not hellbent on using this approach, if there is a better way I'm open to it, it's just that after searching for other options I saw that they don't fit my case:
GCD(not even sure I have it in monotouch) spawns threads on it's own whenever necessary. I need a single specific thread to schedule my work on
NSInvocationQueue(which uses GCD internally from what I read) does the same thing.
pThreads, seem overkill and managing them will be a pain(not even sure I can use them in monotouch)
I'm not an iOS developer, the app works fine with monodroid where I had Runnables and Handlers which make life easier :) . Maybe I'm not looking at this the right way and there is a simple solution to this. Any input would be appreciated.
Thanks
UPDATE
I was thinking of doing something along these lines :
Have a simple wrapper :
class SelectorHandler : NSObject
{
public static Selector Selector = new Selector("apply");
private Action execute;
public SelectorHandler(Action ex)
{
this.execute = ex;
}
[Register("apply")]
private void Execute()
{
execute();
}
}
Extend NSThread
public class Daemon : NSThread
{
public void Schedule(Action action)
{
SelectorHandler handler = new SelectorHandler(action);
handler.PerformSelector(SelectorHandler.Selector, this, null, true);
}
}
Then, when I want to call something I can do it like this :
private Daemon daemon;
public void Call_Library_With_Callback(float param, Action<int> callback)
{
daemon.Schedule(() =>
{
int callbackResult = 0;
//Native library calls
//{
// Assign callback result
//}
daemon.InvokeOnMainThread(() =>
{
callback(callbackResult);
});
});
}

Update Scene from Thread?

I need to update a QGraphicsView with a QGraphicsScene from a thread.
Below is some pseudo'ish code example of what I am doing which is causing me issues (runtime errors).
What am I doing wrong, and how should I be doing it?
Main App:
void Main::startThread()
{
view = new QGraphicsView(...);
thread = new MyThread(...);
connect(thread, SIGNAL(doSceneUpdate(QGraphicsScene*)), this, SLOT(updateScene(QGraphicsScene*)));
thread->start();
}
void Main::updateScene(QGraphicsScene *scene)
{
view->SetScene(scene);
view->show();
repaint();
}
The Thread:
void MyThread::run()
{
QGraphicsScene *scene = new QGraphicsScene(...);
while(1)
{
//draw stuff on the scene
emit doSceneUpdate(scene);
//some delay
}
Thanks in advance!!!
[edit]
The error is:
ASSERT failure in QCoreApplication::sendEvent: "Cannot send events to objects owned by a different thread. Current thread
3e53c0. Receiver '' (of type 'QGraphicsScene') was created in thread 1476cd18", file c:\Qt\qt-everywhere-opensource-src-4.8.2\src\corelib\kernel\qcoreapplication.cpp, line 501
What am I doing wrong, and how should I be doing it?
I think the canonical answer is here -- in a nutshell, the article states that you shouldn't be subclassing QThread, but rather you should use a "bare" (i.e. not-subclassed) QThread object and connect its started() signal to a slot that will then be run in the context of that thread, after the thread starts. That way the object-thread-ownership issues are handled automatically for you.
Note also that threads other than the main Qt thread are generally not allowed to create or interact directly with GUI objects like QGraphicsScene, since doing that would introduce race conditions due to the operations going on simultaneously behind the scenes in Qt's GUI event loop. If you want to use a separate thread, you'll need to keep it away from your GUI objects, and instead just have it emit asynchronous signals and/or send Events to the main/GUI thread to get the main/GUI thread to do the GUI-object updates on its behalf.
The problem is with your connection line. You are connecting a slot to a signal which does not make sense. You should connect the signal from the thread to the slot :
connect(thread, SIGNAL(doSceneUpdate(QGraphicsScene*)),this, SLOT(updateScene(QGraphicsScene*)));
in
void MyThread::run()
{
QGraphicsScene *scene = new QGraphicsScene(...);
...
}
do you pass this to the constructor of QGraphicsScene()?
That could be one cause of error, since now you are passing a child of MyThread to Main
Try creating a QGraphicsScene object on the stack or with the parent as NULL ( new QGraphicsScene(0) )

How to make a Thread pause in Spring mvc project?

I am using a Thread in Spring mvc project to do some background working.
What I have done is
I write a class which extends Thread. and I added init() method to start this class.
Whole ThreadTest.java is Below.
package org.owls.thread.vo;
public class ThreadTest extends Thread {
public void init(){
this.start();
}
public void pause(){
this.interrupt();
}
#Override
public void run() {
for(int i = 0; i < 100; i++){
try{
Thread.sleep(3000);
System.out.println("Thread is running : " + i);
} catch(Exception e){e.printStackTrace();}
}
}
};
edit root-context.xml intent to start this Thread as soon as possible when the server started.
<bean id="threadTest" class="org.owls.thread.vo.ThreadTest" init-method="init"/>
Now is the problem. I want to make a toggle button(pause/resume) in my home.jsp and When I click the button it works. But I do not know how can I access to the Thread, which already registered and run.
please, show me the way~>0<
P.S
additional question about java Thread.
What method exactly means pause and resume. I thought stop is the one similar to pause, but it is deprecated.
And start() is somehow feels like 'new()' not resume.
Thanks
I figured out how to control a thread.
if I want to pause(not stop), code should be like below.
thread.suspend();
And want to resume this from where it paused, like below.
thread.resume();
even though those methods are both deprecated.
(if somebody knows some replacement of these, reply please)
If you do not want to yellow warning in your spring project,
you can remove warning by simply add an annotation on that method.
annotation is #SuppressWarnings("deprecated").
=========================================================
From here, additional solutions based on my experience.
To make automatic executing Spring mvc Thread,
I did following steps.
make a simple Class which extends Thread class.
inside that class, make a method. this will be calles by
config files. in this method. I wrote code like "this.start();".
Let Spring knows we have a Thread class that should run independently
with Web activities. To do this, we have to edit root-context.xml.
Add a bean like this.
<bean id="threadTest" class="org.owls.thread.vo.ThreadTest" init-method="init"/>
init is the method name which generated by user in step 2.
Now we run this project Automatically Thread runs.
Controlling Thread is not relavent with Spring, I guess.
It is basically belongs to java rules.
I hope this TIP(?) will be helpful to people who just entered world of programming :-)

How to run one function in another thread

I'm standing in front of a small (maybe not) problem. I have one function which parses XML file (very big xml ~1Gb) so it takes many time (5-6 mins to finish the func). I don't want to use it in GUI-thread because of known issues (mainwindow freezes and nothing happened, so user thinks everything goes wrong). I've tried to solve this problem by using
QtConcurrent::run
But one more problem appeared: if user press X (close button in top right corner) main GUI-thread goes down, but child-thread which was generated my QtConcurrent::run continue his work and I can kill him only by task manager.
I've decided to use QThread instead of QtConcurrent::run6 but I don't understand how can I run MainWindow class function:
void MainWindow::parseXML()
I've tried to create smth like this:
class pThread : public QThread
{
Q_OBJECT
private:
void run();
};
void pThread::run(){
MainWindow::parseXML();
}
But when I'm trying to compile it error appears:
cannot call member function 'void MainWindow::parseXML()' without object
Moreover, I don't know if it possible to update GUI-thread through this method (parseXML function changes statusBar)
What should I do?
The recommended ways to work with threads in Qt is not to inherit from QThread class, see the documentation here and you should be able to do it after that.
And yes it is possible to update the mainwindow from the thread, just code the signals and slots for that functionality, into mainwindow class code a slot that updates the progress and into the class that does the work (the xml parsing you need - there is no reason that functionality should be into the mainwindow class anyway) you code the signal that emit the progress and connect it with mainwindow's slot with Qt::QueuedConnection (note that the default auto-connection will become queued if the objects are in separate threads).
Another option is to use start a QRunnable with QThreadPool. you may want to check documentation. Be ware to wait the spawned threads with QThreadPool::waitForDone().

Qt threading stopped UI from responding

I think I might misunderstood several concepts in Qt's threading,
In my window class, which is derived from QWidget:
class Widget
{
Q_OBJECT
public:
Widget::Widget (QObject *parent = 0) : QObject(parent)
{
moveToThread(&th); // still stuck
connect (&th, SIGNAL(started()), SLOT(doWork()));
th.start();
}
private:
QThread th;
private slots:
void doWork ()
{
// hmm, this stuck the UI
while (1)
{
qDebug() << "Sleeping";
}
};
};
The forever loop stuck the UI, it shouldn't be, since that was called by the QThread.
Can anyone point out what's wrong about this code?
Widget::dowork() is executed on the main thread (on which the GUI runs), that's why it blocks. It doesn't matter that it was called by a QThread.
The correct way to execute code on another thread is to first move a QObject instance to a QThread using QObject::moveToThread(), and then connect the started() signal of the QThread to the slot of the QObject instance that you want executed.
If you want to know more: https://www.qt.io/blog/2010/06/17/youre-doing-it-wrong
Another issue with your code is that you're trying to move a QWidget-derived object to another thread. This is not allowed. QWidget instances must remain on the main thread. Instead, you should subclass from QObject.
Yet another issue with the code is that you're doing this in the constructor. Moving the object to another thread while it's not fully constructed yet is just asking for trouble.

Resources