I want to return a QString value from a function that exists in class called DB in my MainWindow class, but it always crashes the application.
db.h
#ifndef DB_H
#define DB_H
#include <QMainWindow>
#include <QtSQl>
#include <QSqlQuery>
#include <QSqlError>
#include <QObject>
#include <QDialog>
class DB : public QMainWindow
{
Q_OBJECT
public:
explicit DB(QWidget *parent = 0);
QString getDriver() const;
void setDriver(const QString &value);
private:
QString Driver="test";
signals:
public slots:
};
#endif // DB_H
and this is db.cpp
#include "db.h"
DB::DB(QWidget *parent) : QMainWindow(parent)
{
}
QString DB::getDriver() const
{
return Driver;
}
void DB::setDriver(const QString &value)
{
Driver = value;
}
mainwindow.h
#ifndef MAINWINDOW_H
#define MAINWINDOW_H
#include <QMainWindow>
#include <QDebug>
#include <QFileInfo>
#include <QDialog>
#include <QObject>
#include "Db.h"
namespace Ui {
class MainWindow;
}
class MainWindow : public QMainWindow
{
Q_OBJECT
public:
explicit MainWindow(QWidget *parent = 0);
~MainWindow();
DB *conn;
private slots:
void on_pushButton_clicked();
private:
Ui::MainWindow *ui;
};
#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);
}
MainWindow::~MainWindow()
{
delete ui;
}
void MainWindow::on_pushButton_clicked()
{
QString driverfromdb = conn->getDriver();
qDebug() << driverfromdb;
}
And this what happen when I click the pushbutton: image
You are declaring a pointer to DB class inside your MainWindow class
DB *conn;
but you never initialize it. At the moment it does not point to anything, so if you try to access it:
QString driverfromdb = conn->getDriver(); // boom, conn is somewhere in the void
The solution is simple, you need to create a DB object before using it, e.g.:
void MainWindow::on_pushButton_clicked()
{
conn = new DB();
QString driverfromdb = conn->getDriver();
qDebug() << driverfromdb;
}
or just let conn be a typical variable, not an pointer:
class MainWindow : public QMainWindow
{
Q_OBJECT
public:
explicit MainWindow(QWidget *parent = 0);
~MainWindow();
DB conn; // conn is created after creating MainWindow object
This way you have not to initialize anything and you will avoid crashes.
or:
MainWindow::MainWindow(QWidget *parent) :
QMainWindow(parent), conn(new DB),
ui(new Ui::MainWindow)
{
ui->setupUi(this);
}
MainWindow::~MainWindow()
{
delete conn;
delete ui;
}
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 want to get ListItem in ListWidget that I clicked. But I can't find the way. All the things say get from text but I want the clicked one. Also I'm new in qt and c++.
stackoverflow says add more detail but I don't know how to add more detail so I write this line to get enough "detail".
Here is my .h file:
#ifndef MAINWINDOW_H
#define MAINWINDOW_H
#include <QMainWindow>
#include <string.h>
#include <QListWidgetItem>
QT_BEGIN_NAMESPACE
namespace Ui { class MainWindow; }
QT_END_NAMESPACE
class MainWindow : public QMainWindow
{
Q_OBJECT
public:
MainWindow(QWidget *parent = nullptr);
~MainWindow();
class rsu
{
public:
std::string id;
std::string name;
double coorx;
double coory;
std::string ip;
int port;
};
std::vector<rsu> r;
QListWidgetItem *rsuitem;
private:
Ui::MainWindow *ui;
private slots:
void addRSU();
void deleteRSU();
};
#endif // MAINWINDOW_H
And my .cpp file:
#include "mainwindow.h"
#include "ui_mainwindow.h"
#include "string"
#include "string.h"
#include "QCheckBox"
#include "QString"
MainWindow::MainWindow(QWidget *parent)
: QMainWindow(parent)
, ui(new Ui::MainWindow)
{
ui->setupUi(this);
ui->rsuWidget->hide();
connect(ui->addRSU, SIGNAL(clicked()), ui->rsuWidget, SLOT(show()));
connect(ui->cancelRSU, SIGNAL(clicked()), ui->rsuWidget, SLOT(hide()));
connect(ui->saveRSU, SIGNAL(clicked()), this, SLOT(addRSU()));
}
MainWindow::~MainWindow()
{
delete ui;
delete rsuitem;
}
void MainWindow::addRSU()
{
rsu *baz = new rsu;
baz->id = ui->ID->text().toStdString();
baz->name = ui->Name->text().toStdString();
baz->coorx = ui->CoorX->text().toFloat();
baz->coorx = ui->CoorX->text().toFloat();
baz->ip = ui->IP->text().toStdString();
baz->port = ui->Port->text().toInt();
r.push_back(*baz);
rsuitem = new QListWidgetItem(QString::fromUtf8(baz->name.c_str()),ui->listRSU);
rsuitem->setFlags(rsuitem->flags() | Qt::ItemIsUserCheckable);
rsuitem->setCheckState(Qt::Unchecked);
}
void MainWindow::deleteRSU()
{
}
And my ui:
QScriptEngine eng;
QScriptEngineDebugger debugger;
debugger.attachTo(&eng);
QScriptValue consoleObj = eng.newQObject(this);
eng.globalObject().setProperty("asd", consoleObj);
QScriptValue handler= eng.evaluate("(function(text) { asd.log('text was changed to '+text); })");
QLineEdit *edit = new QLineEdit(this);
qScriptConnect(edit, SIGNAL(textChanged(QString)), QScriptValue(), handler);
edit->show();
qScriptConnect(edit, SIGNAL(textChanged(QString)), QScriptValue(), handler) is not working, but when i am using handler.call(QScriptValue(),args) it works well;
QScriptValueList args;
args << 3;
handler.call(QScriptValue(),args);
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);
Q_INVOKABLE void log(QString msg);
~MainWindow();
private slots:
private:
Ui::MainWindow *ui;
};
#endif // MAINWINDOW_H
mainwindow.cpp
#include "mainwindow.h"
#include "ui_mainwindow.h"
#include<qscriptengine.h>
#include<qscriptenginedebugger.h>
#include<qlineedit.h>
#include<qdebug.h>
MainWindow::MainWindow(QWidget *parent) :
QMainWindow(parent),
ui(new Ui::MainWindow)
{
ui->setupUi(this);
QScriptEngine eng;
QScriptEngineDebugger debugger;
debugger.attachTo(&eng);
QScriptValue consoleObj = eng.newQObject(this);
eng.globalObject().setProperty("asd", consoleObj);
QScriptValue handler= eng.evaluate("(function(text) { asd.log('text was changed to '+text); })");
QLineEdit *edit = new QLineEdit(this);
qDebug()<<qScriptConnect(edit, SIGNAL(textChanged(QString)), QScriptValue(), handler);
edit->show();
}
MainWindow::~MainWindow()
{
delete ui;
}
void MainWindow::log(QString msg)
{
qDebug() << "jsConsole: "<< msg;
}
A variable created in a method that is not created in the heap is deleted when it finishes executing the method, in your case the QScriptEngine is created in the constructor reason why it is eliminated, and all the script depends on it. The solution is simple, make the QScriptEngine member of the class:
mainwindow.h
#ifndef MAINWINDOW_H
#define MAINWINDOW_H
#include <QMainWindow>
#include <QScriptEngine>
namespace Ui {
class MainWindow;
}
class MainWindow : public QMainWindow
{
Q_OBJECT
public:
explicit MainWindow(QWidget *parent = 0);
~MainWindow();
Q_INVOKABLE void log(const QString & text);
private:
Ui::MainWindow *ui;
QScriptEngine eng; // member
};
#endif // MAINWINDOW_H
mainwindow.cpp
#include "mainwindow.h"
#include "ui_mainwindow.h"
#include <QLineEdit>
#include <QScriptEngine>
#include <QScriptEngineDebugger>
#include <QDebug>
MainWindow::MainWindow(QWidget *parent) :
QMainWindow(parent),
ui(new Ui::MainWindow)
{
ui->setupUi(this);
QScriptEngineDebugger debugger;
debugger.attachTo(&eng);
QScriptValue consoleObj = eng.newQObject(this);
eng.globalObject().setProperty("asd", consoleObj);
QScriptValue handler= eng.evaluate("(function(text) { asd.log('text was changed to '+text); })");
QLineEdit *edit = new QLineEdit(this);
qScriptConnect(edit, SIGNAL(textChanged(QString)), QScriptValue(), handler);
edit->show();
}
MainWindow::~MainWindow()
{
delete ui;
}
void MainWindow::log(const QString &text)
{
qDebug()<< text;
}
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 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?