PDA

View Full Version : Help with VoidRealms "Threading done correctly"



Akiva
31st December 2013, 07:38
http://www.youtube.com/watch?v=yazMHbIew0Q


So my issue is pretty obvious:

I created a new QT GUI Application
It is templated as such, that the main thread's constructor creates the UI
Thus, when I try to thread as Void Realms does, it creates a duplicate instance of the ui.


This is what I am trying to accomplish in a larger program:

A properly threaded program; I understand that the Qt documentation has been troublesome in this area. I am unsure if this is still the case.
A thread that communicates with a database, which can make changes to the main UI


The reason why I am using threads

To learn. Threading seems like it is a crucial skill to understand.
To make my program more efficient.
To avoid having my UI hang while it is trying to communicate with the database [which is over a network].


I went ahead and created a new application in QTCreator, File>New File or Project>Applications>QTGui Application
The lines I added from following Void Realms will have a comment beside them, "// Inserted"


#ifndef MAINWINDOW_H
#define MAINWINDOW_H

#include <QMainWindow>
#include <QThread> // Inserted
#include <QDebug> // Inserted

namespace Ui {
class MainWindow;
}

class MainWindow : public QMainWindow
{
Q_OBJECT

public:
explicit MainWindow(QWidget *parent = 0);
~MainWindow();
void THREAD_example(QThread &cThread); // Inserted

public slots:
void METHOD_example(); // Inserted

private:
Ui::MainWindow *ui;
};

#endif // MAINWINDOW_H



#include "mainwindow.h"
#include "ui_mainwindow.h"

MainWindow::MainWindow(QWidget *parent) :
QMainWindow(parent),
ui(new Ui::MainWindow)
{
ui->setupUi(this);
}

MainWindow::~MainWindow()
{
delete ui;
}

// Inserted
void MainWindow::THREAD_example(QThread &cThread)
{
connect(&cThread,SIGNAL(started()),this,SLOT(METHOD_example ()));
}

// Inserted
void MainWindow::METHOD_example()
{
qDebug() << "Snakes";
}



#include "mainwindow.h"
#include <QApplication>

int main(int argc, char *argv[])
{
QApplication a(argc, argv);
MainWindow w;
w.show();

// Inserted
QThread cThread;
MainWindow cObject;
cObject.THREAD_example(cThread);
cObject.moveToThread(&cThread);
cThread.start();

return a.exec();
}



So how should I change this code, that while still threading "correctly", that I am not creating a duplicate instance of the UI?

wysota
31st December 2013, 07:50
You cannot access the user interface from a worker thread.

Akiva
31st December 2013, 07:56
Right, I remember that; Give me a half an hour, and I'll try to restructure the application above that the main is setup to receive a signal from the worker.

wysota
31st December 2013, 08:06
Just remember that using threads "just because you can" is usually a bad idea. Think if you really benefit from having threads in your program in any way.

Akiva
31st December 2013, 10:02
I believe I figured out what I needed to do.

I made a new class, and just added a parameter to my connections which takes the ui object created in main.cpp

Without going too much into it, here is a snippet from my worker class source

void example::THREAD_example(QThread &cThread, MainWindow &w)
{
connect(&cThread,SIGNAL(started()),&w,SLOT(METHOD_example()));
}


METHOD_example() is a public slot in the main thread, which takes signals from my worker class, blah blah blah

anyways, thanks :P

anda_skoa
31st December 2013, 10:35
Your original code was almost correct. You can make it work properly by just removing this line


cObject.moveToThread(&cThread);


But since the thread is not doing anything it is not very useful :)

Cheers,
_