I'm using the Qt application. When I'm trying to call the subclass from the connect, subclass (doWork) function it's not getting called. please refer to my sample code and help me to solve the issue.
I'm using the Qt application. When I'm trying to call the subclass from the connect, subclass (doWork) function it's not getting called. please refer to my sample code and help me to solve the issue.
MainWindow.h
#ifndef MAINWINDOW_H
#define MAINWINDOW_H
#include "QMainWindow"
#include <QThread>
#include "Worker.h"
namespace Ui { class MainWindow; }
class MainWindow: public QMainWindow {
Q_OBJECT
public:
explicit MainWindow(QWidget *parent = 0);
~MainWindow(); private:
Ui::MainWindow *ui;
QThread *thread;
Worker *worker;
signals:
void requestUpdate(int initial);
};
#endif // MAINWINDOW_H
Mainwindow.cpp
#include "mainwindow.h"
#include "ui_mainwindow.h"
#include <QDebug>
MainWindow::MainWindow(QWidget *parent) :
QMainWindow(parent),
ui(new Ui::MainWindow)
{
ui->setupUi(this);
thread = new QThread();
worker = new Worker();
worker->moveToThread(thread);
connect(this, SIGNAL(requestUpdate(int)), worker, SLOT(doWork(int)));
int enc = 10;
emit requestUpdate(enc);
}
MainWindow::~MainWindow()
{
delete thread;
delete worker;
delete UI;
}
Worker.h
#ifndef WORKER_H
#define WORKER_H
#include<QObject>
class Worker: public QObject
{
Q_OBJECT
signals:
void workRequested();
public slots:
void doWork(int initial);
};
#endif // WORKER_H
Worker.cpp
#include "Worker.h"
#include <QTimer>
#include <QEventLoop>
#include <QThread>
#include <QDebug>
Worker::Worker(QObject *parent) :
QObject(parent)
{
_working =false;
_abort = false;
}
void Worker::doWork(int initial)
{
qDebug() << "initial" << endl;
}
Thanks & Regards,
Haji
Related
doit is a Qthread subclass with a signal kif() but the signal emitting is not working I want to show the resualt of gav() on one of my editLines at the same time as its changes inside gav() pls help :((((((( I wasted so much time to find out how I can do it :((((((
main.cpp
#include "mainwindow.h"
#include <QApplication>
int main(int argc, char *argv[])
{
QApplication a(argc, argv);
MainWindow w;
w.show();
return a.exec();
}
doit.h
#ifndef DOIT_H
#define DOIT_H
#include <QThread>
class doit : public QThread
{
Q_OBJECT
public:
doit();
int i;
QString z;
void run() ;
void gav(int &i);
signals:
void kif(const QString &text);
};
#endif // DOIT_H
#include "doit.h"
doit::doit()
{
}
void doit::run()
{
gav(i);
}
void doit::gav(int &i)
{
int k=i;
for (int b=0;b<k;b++){
i=b;
z= QString::number(i);
emit kif(z);
}
}
mainwindow.h
#ifndef MAINWINDOW_H
#define MAINWINDOW_H
#include <QMainWindow>
#include "doit.h"
QT_BEGIN_NAMESPACE
namespace Ui { class MainWindow; }
QT_END_NAMESPACE
class MainWindow : public QMainWindow
{
Q_OBJECT
public:
MainWindow(QWidget *parent = nullptr);
~MainWindow();
doit *dovit=new doit;
private slots:
void checkInput(const QString &text);
private:
Ui::MainWindow *ui;
};
#endif // MAINWINDOW_H
mainwindow.cpp
#include "mainwindow.h"
#include "ui_mainwindow.h"
MainWindow::MainWindow(QWidget *parent)
: QMainWindow(parent)
, ui(new Ui::MainWindow)
{
ui->setupUi(this);
//QObject::connect(dovit,doit::kif(&QString),this , MainWindow::checkInput(QString)))
connect(dovit,SIGNAL(kif(QString)),this,SLOT(checkInput(QString)));
dovit->start();
}
MainWindow::~MainWindow()
{
delete ui;
}
void MainWindow::checkInput(const QString &text)
{
ui->lineEdit_3->setText(text);
}
and Im new in this , so pls tell me exactlly where should I change or add and what tanx alot
Well it finally worked after wasting a lot of my time. For anyone wondering vtables was the problem (as I read its a bug (not sure)) and I should just
right click on the project folder and rebuild and run qmake the project ,
I added Qobject.h too and it worked.
working code:
(it is also a simple and good example of meta signaling in qt if you need it)
doit.h
#define DOIT_H
#include <QThread>
#include <QObject>
class doit : public QThread
{
Q_OBJECT
public:
doit();
void gav();
void run() ;
signals:
void kif(QString text);
};
#endif // DOIT_H
doit.cpp
#include "doit.h"
#include <QDebug>
doit::doit()
{
}
void doit::run()
{
gav();
}
void doit::gav()
{
QString z;
for (int i=0;i<11;i++){
z="mamad";
z = z + QString::number(i);
QThread::sleep(1);
qDebug()<<z;
emit kif(z);
}
}
mainwindow.h
#ifndef MAINWINDOW_H
#define MAINWINDOW_H
#include <QMainWindow>
#include "doit.h"
QT_BEGIN_NAMESPACE
namespace Ui { class MainWindow; }
QT_END_NAMESPACE
class MainWindow : public QMainWindow
{
Q_OBJECT
public:
MainWindow(QWidget *parent = nullptr);
~MainWindow();
doit *dovit=new doit;
//doit dovit;
private slots:
void on_pushButton_clicked();
private:
Ui::MainWindow *ui;
};
#endif // MAINWINDOW_H
mainwindow.cpp
#include "mainwindow.h"
#include "ui_mainwindow.h"
MainWindow::MainWindow(QWidget *parent)
: QMainWindow(parent)
, ui(new Ui::MainWindow)
{
ui->setupUi(this);
connect(dovit,SIGNAL(kif(QString)),this->ui->lineEdit_3,SLOT(setText(QString)));
}
MainWindow::~MainWindow()
{
delete ui;
}
void MainWindow::on_pushButton_clicked()
{
dovit->start();
}
I created a timer in a thread and in this timer char value counts from 0 to 10.
I want to display this char value on the GUI. I do not get any error but the GUI freeze when I started.
Can you help me on where I am doing wrong please?
main.cpp
#include "mainwindow.h"
#include <QApplication>
int main(int argc, char *argv[])
{
QApplication a(argc, argv);
MainWindow w;
w.show();
return a.exec();
}
mainwindow.h
#ifndef MAINWINDOW_H
#define MAINWINDOW_H
#include "mythread.h"
#include <QMainWindow>
QT_BEGIN_NAMESPACE
namespace Ui { class MainWindow; }
QT_END_NAMESPACE
class MainWindow : public QMainWindow
{
Q_OBJECT
public:
explicit MainWindow(QWidget *parent = nullptr);
~MainWindow();
MyThread *mThread;
private:
Ui::MainWindow *ui;
public slots:
void onNumberChanged(char);
};
#endif // MAINWINDOW_H
mainwindow.cpp
#include "mainwindow.h"
#include "ui_mainwindow.h"
MainWindow::MainWindow(QWidget *parent)
: QMainWindow(parent)
, ui(new Ui::MainWindow)
{
ui->setupUi(this);
mThread = new MyThread(this);
connect(mThread,SIGNAL(NumberChanged(char)), this, SLOT(onNumberChanged(char)));
mThread->start();
}
MainWindow::~MainWindow()
{
delete ui;
}
void MainWindow::onNumberChanged(char Number)
{
ui->label->setText(QString::number(Number));
}
mythread.h
#include <QThread>
#include <QTimer>
#include <QObject>
class MyThread : public QThread
{
Q_OBJECT
public:
explicit MyThread(QObject *parent = 0);
void run();
signals:
void NumberChanged(char);
public slots:
void update();
private:
QTimer *timer;
};
mythread.cpp
#include "mythread.h"
#include <QtCore>
char i=45;
QString mystr = "mytext";
MyThread::MyThread(QObject *parent) :
QThread(parent)
{
timer= new QTimer();
connect(timer,SIGNAL(timeout()),this,SLOT(update()));
timer->start(10);
}
void MyThread::update()
{
for( i = 0; i<10; i++){
emit NumberChanged(i);
this->msleep(500);
}
if (i>0)
i=0;
}
void MyThread::run()
{
}
you need to create your timer in the run() function, not in the constructor.
because the constructor is called in GUI thread and each object that is created in this function is in GUI thread. or you can call moveToThread for your timer to move to your thread.
My app, consists in 2 different object (QObject and QMainWIndow), and I am wondering how to communicate between them with SLOT/SIGNAL. Moreover, does existing better approach ?
Can someone make an simple example ? Thank :)
sample
mainwindow.h
#ifndef MAINWINDOW_H
#define MAINWINDOW_H
#include <QMainWindow>
#include "ui_mainwindow.h"
#include "object.h"
namespace Ui {
class MainWindow;
}
class MainWindow : public QMainWindow
{
Q_OBJECT
public:
explicit MainWindow(QWidget *parent = 0);
~MainWindow();
private:
Ui::MainWindow *ui;
private slots:
};
#endif // MAINWINDOW_H
mainwindow.cpp
#include "mainwindow.h"
#include "object.h"
MainWindow::MainWindow(QWidget *parent) :
QMainWindow(parent),
ui(new Ui::MainWindow)
{
ui->setupUi(this);
connect(ui->chkState, SIGNAL(clicked()), this, SLOT(object->chkState();));
}
MainWindow::~MainWindow()
{
delete ui;
}
object.h
#ifndef OBJET_H
#define OBJET_H
#include "mainwindow.h"
#include <QMainWindow>
#include <QObject>
class Object : public QObject
{
Q_OBJECT
public:
explicit Object(QObject *parent = 0);
bool state;
signals:
private slots:
void chkState(Ui::MainWindow *ui);
};
#endif // OBJET_H
objet.cpp
#include "object.h"
#include "mainwindow.h"
Object::Object(QObject *parent) : QObject(parent)
{
}
void Object::chkState(Ui::MainWindow *ui)
{
if (ui->chkState->isChecked())
{
ui->state->setText("true");
state = true;
}
else
{
ui->state->setText("false");
state = false;
}
}
Here is a simple example of how to emit signals and slots.
#ifndef MAINWINDOW_H
#define MAINWINDOW_H
#include <QMainWindow>
#include "object.h"
namespace Ui {
class MainWindow;
}
class MainWindow : public QMainWindow
{
Q_OBJECT
public:
explicit MainWindow(QWidget *parent = 0);
~MainWindow();
signals:
void transmit_to_object(bool value);
private slots:
void receive_from_object(bool value);
void on_checkBox_clicked();
private:
Ui::MainWindow *ui;
object m_object;
};
#endif // MAINWINDOW_H
#ifndef OBJECT_H
#define OBJECT_H
#include <QObject>
class object : public QObject
{
Q_OBJECT
public:
explicit object(QObject * parent = 0);
signals:
void transmit_to_gui(bool value);
private slots:
void receive_from_gui(bool value);
private:
bool state;
};
#endif // OBJECT_H
#include "mainwindow.h"
#include <QApplication>
int main(int argc, char *argv[])
{
QApplication a(argc, argv);
MainWindow w;
w.show();
return a.exec();
}
#include "mainwindow.h"
#include "ui_mainwindow.h"
MainWindow::MainWindow(QWidget *parent) :
QMainWindow(parent),
ui(new Ui::MainWindow)
{
ui->setupUi(this);
connect(&m_object,SIGNAL(transmit_to_gui(bool)),this,SLOT(receive_from_object(bool)));
connect(this,SIGNAL(transmit_to_object(bool)),&m_object,SLOT(receive_from_gui(bool)));
}
MainWindow::~MainWindow()
{
delete ui;
}
void MainWindow::receive_from_object(bool value)
{
if(value)
{
ui->lineEdit->setText("true");
}
else
{
ui->lineEdit->setText("false");
}
}
void MainWindow::on_checkBox_clicked()
{
if(ui->checkBox->isChecked())
{
emit transmit_to_object(true);
}
else
{
emit transmit_to_object(false);
}
}
#include "object.h"
#include "mainwindow.h"
object::object(QObject *parent)
{
}
void object::receive_from_gui(bool value)
{
state = value;
emit transmit_to_gui(state);
}
There are several errors in your code.
First:
connect(ui->chkState, SIGNAL(clicked()), this, SLOT(object->chkState();));
Here you say:
"when we click on the ui->chkState, I want you call a function in this, which is the object->chkState slot". That's definitly not what you want.
What is object ? this object hasn't been created. What you want is :
connect(ui->chkState, SIGNAL(clicked()), myobject, SLOT(chkState()));
with myobject an object of type Object so you need to add in your mainwindow.h a
Object *myobject;
and in your mainwindow.cpp before the connect:
myobject = new Object(this);
Moreover, your function void chkState(Ui::MainWindow *ui); won't work because you cannot get the mainwindow ui in parameter like that.
What I advise you to do, if it's only for tests so you know that parent is the type of MainWindow, you can do:
void Object::chkState()
{
MainWindow* parent = static_cast<MainWindow*>(parent());
if (parent->ui->chkState->isChecked())
{
parent->ui->state->setText("true");
state = true;
}
else
{
parent->ui->state->setText("false");
state = false;
}
}
So the parameter in your slot is removed.
I know this question asked many times but still confused and cannot find a solution.
I have a MainWindow and a class.
In my class I have a signal which I emit in the method call.
Problem: Slot method is not firing.
Here is my code.
BWorker.h
#pragma once
#include <QObject>
class BWorker : public QObject
{
Q_OBJECT
public:
BWorker(QObject *parent);
~BWorker();
void doSomething();
signals:
void signalSomething();
};
BWorker.cpp
#include "BWorker.h"
BWorker::BWorker(QObject *parent)
: QObject(parent)
{
}
BWorker::~BWorker()
{
}
void BWorker::doSomething()
{
emit signalSomething();
}
QtGuiApplication1.h
#pragma once
#include <QtWidgets/QMainWindow>
#include "ui_QtGuiApplication1.h"
class QtGuiApplication1 : public QMainWindow
{
Q_OBJECT
public:
QtGuiApplication1(QWidget *parent = Q_NULLPTR);
public slots:
void workDone();
private:
Ui::QtGuiApplication1Class ui;
};
QtGuiApplication1.cpp
#include "QtGuiApplication1.h"
#include "BWorker.h"
QtGuiApplication1::QtGuiApplication1(QWidget *parent)
: QMainWindow(parent)
{
ui.setupUi(this);
BWorker bworker(this);
connect(&bworker, SIGNAL(bworker.signalSomething), this, SLOT(workDone()));
bworker.doSomething();
}
void QtGuiApplication1::workDone() {
}
Your problem is here:
SIGNAL(bworker.signalSomething)
This is not valid and you should see a message in terminal saying that there is no such signal. The correct syntax for your case would be:
SIGNAL(signalSomething())
Please post your code by copy-pasting it. Do not edit the code: The problem could be emerged from where you edited.
The code of mine worked fine.
mainwindow.h:
#ifndef MAINWINDOW_H
#define MAINWINDOW_H
#include <QMainWindow>
namespace Ui {
class MainWindow;
}
class MainWindow : public QMainWindow
{
Q_OBJECT
public:
explicit MainWindow(QWidget *parent = 0);
~MainWindow();
public slots:
void workDone();
private:
Ui::MainWindow *ui;
};
#endif // MAINWINDOW_H
mainwindow.cpp:
#include "mainwindow.h"
#include "ui_mainwindow.h"
#include <QDebug>
#include "worker.h"
MainWindow::MainWindow(QWidget *parent) :
QMainWindow(parent),
ui(new Ui::MainWindow)
{
ui->setupUi(this);
Worker worker(this);
connect(&worker, SIGNAL(signalSomething()), this, SLOT(workDone()));
//connect(&worker, &Worker::signalSomething, this, &MainWindow::workDone);
worker.doSomething();
}
MainWindow::~MainWindow()
{
delete ui;
}
void MainWindow::workDone()
{
qDebug() << "Done.";
}
worker.h:
#ifndef WORKER_H
#define WORKER_H
#include <QObject>
class Worker : public QObject
{
Q_OBJECT
public:
explicit Worker(QObject *parent = 0);
void doSomething();
signals:
void signalSomething();
public slots:
};
#endif // WORKER_H
worker.cpp:
#include "worker.h"
Worker::Worker(QObject *parent) : QObject(parent)
{
}
void Worker::doSomething()
{
emit signalSomething();
}
Application Output:
Debugging starts
Done.
Debugging has finished
Printed out "Done." means the codes are working.
I don't get it.
loginview.h
#ifndef LOGINVIEW_H
#define LOGINVIEW_H
#include <QMainWindow>
#include <QDebug>
#include <QPushButton>
class LoginView : public QWidget
{
public:
QWidget *LoginViewSetup(QWidget * wdgMain);
public slots:
virtual void LogInUser();
virtual void CreateUser();
public:
QPushButton *logInBtn;
QPushButton *createBtn;
};
#endif // LOGINVIEW_H
loginview.cpp
#include "loginview.h"
QWidget *LoginView::LoginViewSetup(QWidget * wdgMain)
{
//some code
return wdgCenter;
}
void LoginView::LogInUser()
{
//some code
}
void LoginView::CreateUser()
{
//some code
}
mainwindow.h
#ifndef MAINWINDOW_H
#define MAINWINDOW_H
#include <QMainWindow>
#include <QDebug>
#include <loginview.h>
namespace Ui {
class MainWindow;
}
class MainWindow : public QMainWindow
{
Q_OBJECT
public:
explicit MainWindow(QWidget *parent = 0);
~MainWindow();
private:
Ui::MainWindow *ui;
QWidget * wdgMain;
};
#endif // MAINWINDOW_H
mainwindow.cpp
#include "mainwindow.h"
#include "ui_mainwindow.h"
MainWindow::MainWindow(QWidget *parent) :
QMainWindow(parent),
ui(new Ui::MainWindow)
{
ui->setupUi(this);
wdgMain = new QWidget(this);
LoginView LoginViewObj;
QWidget *wdgCenter = LoginViewObj.LoginViewSetup(wdgMain);
setCentralWidget( wdgMain );
connect(LoginViewObj.createBtn, SIGNAL (released()), &LoginViewObj, SLOT (CreateUser()));
}
MainWindow::~MainWindow()
{
delete ui;
}
Problem:
QObject::connect: No such slot QWidget::CreateUser() in
../proj/mainwindow.cpp:16
I tried to add Q_OBJECT to the loginview.h and then rebuild project with QMAKE. After that there is no warning about slot, but buttons still not active. Program don't jump to handle of the button in debug mode.
Please, help me to understand what's wrong? I have an object of another class LoginView and I pass this object as a reciever for a slot. Why it passes through my class and searches slot in QWidget?