I have wrote a simple signal - slot. where i member objects signal is connected to slot of the class. I gets error
I have given the code below... If I keep the connect in the constructor then also i get error.
#ifndef COUNTER_H
#define COUNTER_H
#include <QObject>
#include <QTextEdit>
class Counter : public QObject
{
Q_OBJECT
public:
Counter()
{
m_value = 0;
}
int value() const
{
return m_value;
}
public slots:
void setValue(int value);
void callSetValue();
signals:
void valueChanged(int newValue);
private:
int m_value;
QTextEdit m_text;
};
#endif // COUNTER_H
//counter.cpp
#include "counter.h"
void Counter::setValue(int value)
{
QObject::connect (&m_text, SIGNAL(textChanged()), this, SLOT(callSetValue()));
qDebug("setValue invoked");
if (value != m_value)
{
m_value = value;
m_text.setText("hai");
emit valueChanged(value);
qDebug("emited signal");
}
}
void callSetValue()
{
qDebug("callSetValue() invoked");
}
gives me error "undefined reference to 'Counter::callSetValue()'
At the bottom of counter.cpp change
void callSetValue()
to
void Counter::callSetValue()
Did you try re-running qmake? The code for signals may not have been generated if you modified signals or slots without running qmake again.
Related
The program I have written has a function that takes a QList and returns the information in said QList as a QString. This works as intended
I however want to run this function in a thread in order to serialize the process, so I created a new class that runs a QThread.
//header file
#include "item.h"
#include <QThread>
#include <QObject>
#include <QList>
#include <QString>
class String_Writer_Thread : public QThread
{
Q_OBJECT
public:
explicit String_Writer_Thread(QObject *parent = nullptr);
void run();
void setList(QList<ITEM*> IList);
signals:
void EMIT_STRING(QString);
private:
QList<ITEM*> ITEM_LIST;
};
//implementation file
#include "string_writer_thread.h"
#include <QMutex>
String_Writer_Thread::String_Writer_Thread(QObject *parent)
: QThread{parent}
{
}
void String_Writer_Thread::run()
{
QString XString;
foreach(auto *I, ITEM_LIST)
{
XString.append(I->getString());
}
/*getString() is a void function that returns the data from an ITEM item as follows:
Name: ITEM_NAME //QString
Size: ITEM_SIZE //three int values (height, breadth, length)
Color: ITEM_COLOR //QString
*/
emit EMIT_STRING(XString); //should emit the resulting QString
terminate();
wait();
}
//this function is called before the QThread is started in the main class to insert the QList
//into the threaded class
void String_Writer_Thread::setList(QList<ITEM*> IList)
{
ITEM_LIST.clear();
foreach(auto I, IList)
{
ITEM_LIST.append(I);
}
}
Then in my main class, I initialize an item as such:
//main class header
public slots:
void update_Output(QString String_from_Thread); //handles the emitted string
private:
String_Writer_Thread *TString;
QString getThreadString; //this will hold the output from the String_Writer_Thread class
QList<ITEM*> Item_List;
and in the main class' implementation I connect the Signals and Slots as
//main class implementations
//initializing TString
TString = new String_Writer_Thread();
//connecting the signals and slots
connect(TString, &String_Writer_Thread::EMIT_STRING, this, &MainWindow::update_Output);
...
void MainWindow::update_Output(QString String_from_Thread)
{
getThreadString = String_from_Thread;
Text_Output.append(getThreadString); //Text_Output is a QTextEdit in the ui.
//I use it instead of QDebug because QDebug is a pain to
//work with sometimes
}
void MainWindow::add_Item_to_List(ITEM newI)
{
Item_List.append(newI);
TString->setList(Item_List);
TString->start();
}
To compare, the original function is simply
QString MainWindow::List_to_String(QList<ITEM*> ITL)
{
QString XString;
foreach(auto *I, ITL)
{
XString.append(I->getString());
}
/*getString() is a void function that returns the data from an ITEM item as follows:
Name: ITEM_NAME //QString
Size: ITEM_SIZE //three int values (height, breadth, length)
Color: ITEM_COLOR //QString
*/
return XString;
}
Despite the Program building without giving me red or yellow flags, it still crashes.
I am a beginner of qt.I adopted the way recommended by QThread Class in qt documentation.
The method used in documentation is as follows.
class Worker : public QObject
{
Q_OBJECT
public slots:
void doWork(const QString ¶meter) {
QString result;
/* ... here is the expensive or blocking operation ... */
emit resultReady(result);
}
signals:
void resultReady(const QString &result);
};
class Controller : public QObject
{
Q_OBJECT
QThread workerThread;
public:
Controller() {
Worker *worker = new Worker;
worker->moveToThread(&workerThread);
connect(&workerThread, &QThread::finished, worker, &QObject::deleteLater);
connect(this, &Controller::operate, worker, &Worker::doWork);
connect(worker, &Worker::resultReady, this, &Controller::handleResults);
workerThread.start();
}
~Controller() {
workerThread.quit();
workerThread.wait();
}
public slots:
void handleResults(const QString &);
signals:
void operate(const QString &);
};
So I have Class SocketThreadCtrler and Class SocketWorker respectively.
Concrete code is as follows.
socketthreadctrler.h is as follows.
#ifndef SOCKETTHREADCTRLER_H
#define SOCKETTHREADCTRLER_H
#include <QObject>
#include <QThread>
#include "socketworker.h"
class SocketThreadCtrler : public QObject
{
Q_OBJECT
private:
QThread workThread;
public:
explicit SocketThreadCtrler(QObject *parent = 0);
~SocketThreadCtrler();
private:
void connSigAngSlots();
public slots:
void login(QString acnt, QString passwd);
void EmitSigCheckLogin(bool loginStatus);
signals:
void SIG_CONECTSERVER();
void SIG_WRITEMSG(QByteArray&);
void SIG_CHECKLOGIN(bool);
private:
SocketWorker* worker;
// MainUI* mainUI;
};
#endif // SOCKETTHREADCTRLER_H
socketThreadCtrler.cpp
#include "header/backend/communication/socketthreadctrler.h"
#include "header/backend/communication/smessage1.h"
SocketThreadCtrler::SocketThreadCtrler(QObject *parent) : QObject(parent)//, worker(NULL)
{
// SocketWorker* worker = new SocketWorker();
worker=new SocketWorker;
worker->moveToThread(&workThread);
connSigAngSlots();
workThread.start();
emit SIG_CONECTSERVER();
}
SocketThreadCtrler::~SocketThreadCtrler()
{
workThread.quit();
workThread.wait();
}
void SocketThreadCtrler::connSigAngSlots()
{
connect(&workThread,SIGNAL(finished()),worker,SLOT(deleteLater()));
connect(this,SIGNAL(SIG_CONECTSERVER()),worker,SLOT(connectServer()),Qt::QueuedConnection);
connect(this,SIGNAL(SIG_WRITEMSG(QByteArray&)),worker,SLOT(writeMsg(QByteArray&)));
connect(worker,SIGNAL(Sig_LoginStatus(bool)),this,SLOT(EmitSigCheckLogin(bool)));
}
void SocketThreadCtrler::login(QString acnt, QString passwd)
{
//如何给login专门开一个线程
SMessage1 msg1(acnt, passwd);
emit SIG_WRITEMSG(msg1.getMsg());
}
void SocketThreadCtrler::EmitSigCheckLogin(bool loginStatus)
{
emit SIG_CHECKLOGIN(loginStatus);
}
socketWorker.h
#ifndef SOCKETWORKER_H
#define SOCKETWORKER_H
#include <QObject>
#include <QTcpSocket>
#include "messagefactory.h"
#include "rmessage.h"
#include "message.h"
#include "auxfuncset.h"
#include "smessage.h"
class SocketWorker : public QObject
{
Q_OBJECT
private:
static const quint16 serverPort=12345;
static const QString serverAddr;
QTcpSocket sock;
public:
explicit SocketWorker(QObject *parent = 0);
void WorkerEmitSigLogin(bool loginStatus);
private:
bool isServerMsg();
quint32 getMsgLen();
void getMsg(quint32 msgLen, QByteArray& msgBytes);
signals:
void Sig_LoginStatus(bool loginStatus);
public slots:
void connectServer();
void writeMsg(QByteArray&Msg);
void procMsg();
//private:
};
#endif // SOCKETWORKER_H
socketWorker.cpp
#include "header/backend/communication/socketworker.h"
const QString SocketWorker::serverAddr("127.0.0.1");
SocketWorker::SocketWorker(QObject *parent) : QObject(parent)
{
}
void SocketWorker::connectServer()
{
QString tmp=serverAddr;
sock.connectToHost(tmp,serverPort);
connect(&sock,SIGNAL(readyRead()) ,this, SLOT(procMsg()));
}
void SocketWorker::writeMsg(QByteArray& Msg)
{
sock.write(Msg);
// QAbstractSocket will start sending data automatically
// once control goes back to the event loop
sock.flush();
}
void SocketWorker::procMsg()
{
if(!isServerMsg()) return;
quint32 msgLen=0;
msgLen=getMsgLen();
if(0 == msgLen) return;
QByteArray msgBytes;
getMsg(msgLen,msgBytes);
RMessage* msg = MessageFactory::createMessage(msgBytes);
msg->process(this);
delete msg;
}
bool SocketWorker::isServerMsg()
{
//MSGHEADER
quint32 msgHead=0;
while(AuxFuncSet::readQuint32(&sock, msgHead))
{
if(msgHead == Message::MSGHEADER)
{
return true;
}
}
return false;
}
quint32 SocketWorker::getMsgLen()
{
while(sock.bytesAvailable()<sizeof(quint32));
quint32 msgLen=0;
AuxFuncSet::readQuint32(&sock,msgLen);
return msgLen;
}
void SocketWorker::getMsg(quint32 msgLen, QByteArray& msgBytes)
{
while(sock.bytesAvailable()<msgLen);
msgBytes = sock.read(msgLen);
}
void SocketWorker::WorkerEmitSigLogin(bool loginStatus)
{
emit Sig_LoginStatus(loginStatus);
}
The error message provided by compiler is
QObject: Cannot create children for a parent that is in a different thread.
(Parent is QTcpSocket(0xb988c8), parent's thread is QThread(0xb93528), current thread is QThread(0x8dfe2c)
From my debugging, I find the key section is signal-slot connect part that causes this problem.
Specifically,there are four connection statements.
i.e.,
connect(&workThread,SIGNAL(finished()),worker,SLOT(deleteLater()));
connect(this,SIGNAL(SIG_CONECTSERVER()),worker,SLOT(connectServer()),Qt::QueuedConnection);
connect(this,SIGNAL(SIG_WRITEMSG(QByteArray&)),worker,SLOT(writeMsg(QByteArray&)));
connect(worker,SIGNAL(Sig_LoginStatus(bool)),this,SLOT(EmitSigCheckLogin(bool)));
But only the middle two statements causes this error.Concretely,if I delete the middle two statements,i.e.,
connect(this,SIGNAL(SIG_CONECTSERVER()),worker,SLOT(connectServer()),Qt::QueuedConnection);
connect(this,SIGNAL(SIG_WRITEMSG(QByteArray&)),worker,SLOT(writeMsg(QByteArray&)));
then there are no errors.
So I am confused.After one and a half hour,I still don't find a effective solution and a reasonable explanation.So I think I need help.Thanks in advance.
The core of my project is independent of GUI framework that's why I prefer std::thread. But Qt gives me an error when thread is using.
The inferior stopped because it received a signal from the operating system.
Signal name: SIGSEGV
Signal meaning: Segmentation fault
//MainWindow.h
#ifndef MAINWINDOW_H
#define MAINWINDOW_H
#include <thread>
#include <mutex>
#include <QMainWindow>
namespace Ui { class MainWindow; }
struct Observer
{
virtual void notify() = 0;
};
class Core
{
public:
std::thread *run()
{
std::thread thread(&Core::runP, this);
thread.detach();
return &thread;
}
void setObserver(Observer *observer) { _observer = observer; }
int ii() const { return _ii; }
void nextIi() { _ii++; }
void lock() { _mutex.lock(); }
bool tryLock() { return _mutex.try_lock(); }
void unlock() { _mutex.unlock(); }
private:
void runP()
{
for (int i = 1; i <= 1000; i++) {
if (i % 10 == 0) {
lock();
nextIi();
unlock();
notify();
}
}
}
void notify() { _observer->notify(); } //!!!
Observer *_observer;
int _ii;
std::mutex _mutex;
};
struct MwObserver : public Observer
{
explicit MwObserver(struct MainWindow *mainWindow) { _mainWindow = mainWindow; }
virtual void notify();
MainWindow *_mainWindow;
};
class MainWindow : public QMainWindow
{
Q_OBJECT
public:
explicit MainWindow(QWidget *parent = 0);
~MainWindow() { delete _ui; }
void upd();
public slots:
void run() { _core.run(); }
private:
Ui::MainWindow *_ui;
MwObserver _observer;
Core _core;
};
inline void MwObserver::notify() { _mainWindow->upd(); }
#endif
-
//MainWindow.cpp
#include "mainwindow.h"
#include "ui_mainwindow.h"
MainWindow::MainWindow(QWidget *parent) :
QMainWindow(parent),
_ui(new Ui::MainWindow),
_observer(this)
{
_ui->setupUi(this);
connect(_ui->pushButtonRun, SIGNAL(clicked(bool)), this, SLOT(run()));
}
void MainWindow::upd()
{
_core.lock();
setWindowTitle(QString::number(_core.ii()));
_core.unlock();
}
There are multiple problems here, first and most obvious was already noted by perencia. You are returning a pointer to stack variable. In c++ terms it's unacceptable.
Secondly. The crash comes from not using std::thread, but from race condition. The Qt event loop does not know about you mutex, so your setWindowTitle call is introducing a race, that leads to crash.
You need to use QMetaObject::invokeMethod to post function to the Qts event loop.
Example:
change
inline void MwObserver::notify() { _mainWindow->upd(); }
to
inline void MwObserver::notify() {
if(!QMetaObject::invokeMethod(_mainWindow, "upd", Qt::QueuedConnection))
std::cerr << " Failed to invoke method" << std::endl;
}
additional includes may apply
This updates the GUI from a thread different then the GUI thread! Which is not allowed.
Why not to use QThread and a signal/slot mechanism to update your window title. The Qt framework does the thread switching automatically.
class Core : public QObject
{
Q_OBJECT
public:
explicit Core(QObject * parent = 0) : QObject(parent) {}
signals:
void notify();
public slots:
void nextIi() { _ii++; }
void runP()
{
for (int i = 1; i <= 1000; i++) {
if (i % 10 == 0) {
nextIi();
notify();
}
}
}
private:
Q_DISABLE_COPY(Core);
int _ii;
};
class MainWindow : public QMainWindow
{
Q_OBJECT
public:
explicit MainWindow(QWidget *parent = 0);
~MainWindow();
public slots:
void run() {_th.start();}
void upd(int ii) {setWindowTitle(QString::number(ii));}
private:
Ui::MainWindow *_ui;
Core _core;
QThread _th;
};
//MainWindow.cpp
#include "mainwindow.h"
#include "ui_mainwindow.h"
MainWindow::MainWindow(QWidget *parent) :
QMainWindow(parent),
_ui(new Ui::MainWindow),
_observer(this)
{
_ui->setupUi(this);
connect(_ui->pushButtonRun, SIGNAL(clicked(bool)), this, SLOT(run()));
connect(&_core, SIGNAL(notify(int)), this, SLOT(upd(int)));
_core.moveToThread(&_th);
}
MainWindow::~MainWindow()
{
delete _ui;
_th.quit();
_th.wait(1000);
}
You are creating thread on the stack and returning a pointer to that. After run() that pointer is no longer valid.
Aside from returning pointer to stack variable and updating GUI from thread object that is not known for QT. I don't see from your code, where you set up _observer member of Core class. There is no setObserver call for _core member of MainWindow class.
So consructor of MainWindow class calls consructor of _core member, but after that _core._observer contains garbage. I think this is the cause of your Segmentaion Fault in call of notify method of Core class.
The answers to all the problems have already been given, let me summarize.
The program crash has nothing to do with the threading, The problem is that the _observer in the _core member of MainWindowis not set. A call to setObserver must be added.
explicit MainWindow( QWidget *parent = nullptr ) :
QMainWindow( parent ),
_observer( this )
{
_core.setObserver( &_observer );
}
This will lead to the next problem, that the observer actually calls the udp message from another thread, causing a UI update in a different thread context. To solve this, it is easiest to use Qt's Qt::QueuedConnection. To enable this we must make upt() a slot.
public slots:
void run();
void upd();
Then we can either call it using QMetaObject::invokeMethod in
inline void MwObserver::notify()
{
QMetaObject::invokeMethod( _mainWindow, "upd", Qt::QueuedConnection );
}
or use a signal / slot connection by deriving MwObserver from QObject, giving it a signal, and connect that signal to the upd slot and raising the signal in notify.
struct MwObserver
: public QObject
, public Observer
{
Q_OBJECT;
signals:
void sigUpd();
public:
explicit MwObserver( MainWindow *mainWindow );
virtual void notify()
MainWindow *_mainWindow;
};
void MwObserver::notify()
{
sigUpd();
}
MwObserver::MwObserver( MainWindow *mainWindow )
{
_mainWindow = mainWindow;
connect( this, SIGNAL(sigUpd()), _mainWindow, SLOT(upd()) )
}
Disclaimer: I haven't used Qt in some time but with X/XMotif on Linux/UNIX the GUI MUST run in the 'main-thread', not spawned threads. Maybe this applies to your situation. Just a thought, have your GUI code run in the main-thread.
The best approach is to wrap pure C++ code with QObejct instance and fire signals when this objects receive some notification from pure C++ code.
SO in your case:
class MwObserver : public QObject, public Observer
{
Q_OBJECT
public:
explicit MwObserver(QObject *parent)
: QObject(parent)
{}
signals:
void SomeEvent();
protected:
// Observer
void notify() {
emit SomeEvent();
}
};
Now MainWindow should connect some slot to signal provided this way and everything should work out of the box (Qt will do thread jumping behind the scenes).
In your code form comment the crash is caused by invalid use of temporary object. This is INVALID C++ code no mater what kind of object is returned:
std::thread *run()
{
std::thread thread(&Core::runP, this);
thread.detach();
return &thread;
}
You cant return a pointer to local object of the function method, since this object becomes invalid immediately when you return a function. This is basic C++ knowledge.
I am trying to create QQuickWidget based application.
What i am trying to do:
Class A(game.h) and Class B(gamestate.h) are forward declared. Class A is main QQuickWidget class with methods. Class B QObject derived class contains signals, slots, variables and methods.
Class B Variable values can set from class A -- Working
When variable value changes signal should be emitted -- working
when signal was emitted slot method should be called in class B -- working
Class B should invoke a method in class A -- working
Class A should create another qquickwidget -- NOT WORKING
(No compiling error. Application crashes on load)
I tried to call from class A and showIntro() function working fine. But when tried to call from class B its not working.
Game.h
#ifndef GAME_H
#define GAME_H
#include <QQuickWidget>
class GameState;
class Game: public QQuickWidget
{
Q_OBJECT
public:
Game();
GameState *gameState;
void showIntro();
public slots:
void onStatusChanged(QQuickWidget::Status);
};
#endif // GAME_H
Game.cpp
#include "game.h"
#include <QQuickWidget>
#include <QDebug>
#include "gamestate.h"
Game::Game(): QQuickWidget()
{
gameState = new GameState(this);
mainScreen = new QQuickWidget();
connect(this, SIGNAL(statusChanged(QQuickWidget::Status)), this, SLOT(onStatusChanged(QQuickWidget::Status)));
setFixedSize(450, 710);
setSource(QUrl("qrc:/EmptyScreen.qml"));
}
void Game::onStatusChanged(QQuickWidget::Status status)
{
switch(status)
{
case QQuickWidget::Ready:
qDebug() << "hi";
gameState->setValue(1);
//showIntro();
break;
case QQuickWidget::Error:
qDebug() << "Error";
break;
}
}
void Game::showIntro()
{
mainScreen->setSource(QUrl("qrc:/MainScreen.qml"));
mainScreen->setAttribute(Qt::WA_TranslucentBackground);
mainScreen->setParent(this);
}
Here is my Gamestate.h
#ifndef GAMESTATE_H
#define GAMESTATE_H
#include <QObject>
class Game;
class GameState : public QObject
{
Q_OBJECT
public:
explicit GameState(QObject *parent = 0);
int value() const {return m_value; }
Game *game;
signals:
void valueChanged(int newValue);
public slots:
void setValue(int value);
void stateChanged(int value);
private:
int m_value;
};
#endif // GAMESTATE_H
GameState.cpp
#include "gamestate.h"
#include "game.h"
GameState::GameState(QObject *parent) : QObject(parent)
{
m_value = 0;
connect(this,SIGNAL(valueChanged(int)), this, SLOT(stateChanged(int)));
}
void GameState::setValue(int value)
{
if(value != m_value)
{
m_value = value;
emit valueChanged(value);
}
}
void GameState::stateChanged(int value)
{
if(value == 1)
{
game->showIntro();
}
}
and my final main.cpp
#include <QApplication>
#include <QQmlApplicationEngine>
#include "game.h"
Game *game;
int main(int argc, char *argv[])
{
QApplication app(argc, argv);
game = new Game();
game->show();
return app.exec();
}
Pls suggest me what could be the issue.
Member variable Game* game of class GameState is not initialized and therefore the program crashes when trying to dereference the pointer within GameState::stateChanged().
Change the constructor of GameState to the following:
// in gamestate.h
explicit GameState(Game *parent = 0);
// in gamestate.cpp
GameState::GameState(Game *parent) : QObject(parent), game(parent)
{
m_value = 0;
connect(this,SIGNAL(valueChanged(int)), this, SLOT(stateChanged(int)));
}
I am trying to implement Signal and Slot system between the main gui and another object moved to another thread...the following is how the class design looks like...unfortunately cannot implement it...
MainWindow.h
signals:
void StopDisplayWidget();
void StartDisplayWidget();
void signalFromGUI();
private slots:
void on_pushButton_start_display_clicked();
void on_pushButton_stop_display_clicked();
void on_pushButton_check_clicked();
private:
Ui::MainWindow *ui;
displaythread *threadforDisplay;
display *displayWidget;
QThread *WorkerDisplay;
MainWindow.cpp
{
threadforDisplay = new displaythread;
threadforDisplay->setptr2display(displayWidget);
WorkerDisplay = new QThread;
QObject::connect(WorkerDisplay,SIGNAL(started()),threadforDisplay,SLOT(Process()));
QObject::connect(this,SIGNAL(StartDisplayWidget()),threadforDisplay,SLOT(StartDisplay()));
QObject::connect(this,SIGNAL(StopDisplayWidget()),threadforDisplay,SLOT(StopDisplay()));
QObject::connect(this,SIGNAL(signalFromGUI()),threadforDisplay,SLOT(Check()));
threadforDisplay->moveToThread(WorkerDisplay);
}
void MainWindow::on_pushButton_start_display_clicked()
{
if(!threadforDisplay->IsDisplayActive())
emit this->StartDisplayWidget();
if(!WorkerDisplay->isRunning())
WorkerDisplay->start();
}
void MainWindow::on_pushButton_stop_display_clicked()
{
if(threadforDisplay->IsDisplayActive())
{
emit this->StopDisplayWidget();
}
}
void MainWindow::on_pushButton_check_clicked()
{
std::cout<<"CHECKING SIGNAL SLOT"<<std::endl;
emit this->signalFromGUI();
}
threadforDisplay is a pointer to displaythread class which looks like
displaythread.h
#include <QObject>
#include <QWaitCondition>
#include <QMutex>
#include "display.h"
class displaythread : public QObject
{
Q_OBJECT
public:
explicit displaythread(QObject *parent = 0);
bool IsDisplayActive() const;
void setptr2display(display *);
signals:
public slots:
void Process();
void StartDisplay();
void StopDisplay();
void Check();
private:
void SleepThread();
volatile bool stopped,running;
QMutex mutex;
QWaitCondition waitcondition;
display *displayinGUI;
displaythread.cpp
void displaythread::setptr2display(display *ptr)
{
displayinGUI = ptr;
}
void displaythread::Process()
{
std::cout<<"RECEIVED START PROCESS SIGNAL"<<std::endl;
running = true;
while(true)
{
if(!stopped)
{
displayinGUI->update();
this->SleepThread();
}
}
}
void displaythread::SleepThread()
{
mutex.lock();
waitcondition.wait(&mutex,20);
mutex.unlock();
}
void displaythread::StartDisplay()
{
std::cout<<"RECEIVED START SIGNAL"<<std::endl;
stopped = false;
running = true;
}
void displaythread::StopDisplay()
{
std::cout<<"RECEIVED STOP SIGNAL"<<std::endl;
stopped = true;
running = false;
}
bool displaythread::IsDisplayActive() const
{
return running;
}
void displaythread::Check()
{
std::cout<<"SIGNAL FROM GUI RECEIVED"<<std::endl;
}
display.h
class display : public QWidget
{
Q_OBJECT
public:
explicit display(QWidget *parent = 0);
~display();
signals:
public slots:
private:
void paintEvent(QPaintEvent *);
IplImage *image_opencvBGR,*image_opencvRGB;
QImage image;
CvCapture *webcam;
display.cpp
display::display(QWidget *parent) :
QWidget(parent)
{
image_opencvRGB = cvCreateImage(cvSize(640,480),8,3);
webcam = cvCaptureFromCAM(-1);
}
display::~display()
{
cvReleaseCapture(&webcam);
}
void display::paintEvent(QPaintEvent *)
{
//std::cout<<"IN PAINT LOOP"<<std::endl;
image_opencvBGR = cvQueryFrame(webcam);
cvCvtColor(image_opencvBGR,image_opencvRGB,CV_BGR2RGB);
image = QImage((const unsigned char*)image_opencvRGB->imageData,image_opencvRGB->width,image_opencvRGB->height,QImage::Format_RGB888);
QRectF target(0.0,0.0,image.width(),image.height());
QRectF source(0.0,0.0,image.width(),image.height());
QPainter painter(this);
painter.drawImage(target,image,source);
}
OUTPUT :
RECEIVED START PROCESS SIGNAL
However except the Process slot no other slot is working when signals are emitted from the main gui i.e. MainWindow..is it due to movetoThread command? Donno where i am going wrong..
The answer is simple : Qwidgets don't work outside the main thread. So you cannot execute GUI code using displaythread.
Furthermore your while loop may cause issues (I know the variable is volatile but I dont have the time to analyze properly if it is correct)
See the documentation for more information.
ps: It seems you are overdoing things. Rework your whole design. GUI operations are in the main thread. Use threads for computations only. If the communication between thread and access to their variables use signal and slots only, you dont need locking mechanisms.