c++qtqt5qmetaobjectqproperty

I am getting an error on Qt, and can't figure out where I went wrong


So, I am learning my way around Q_PROPERTY, QMetaObject and QMetaProperty.

I have built a working GUI, but whenever I run the script, I get an error

Can anyone tell me what I did wrong/am doing wrong? The QDout() function, as mentioned, is only there to display something if I successfully connected the 'Print' Button with the QDout() function.

Below I have my files that associate with the Qt Project I am working on. This is nothing serious, only for me to learn how to do it.

qt.core.qobject.connect: QObject::connect: No such slot FileInput::writeToFile()

My Header Files:

fileinput.h

#ifndef FILEINPUT_H
#define FILEINPUT_H

#include <QWidget>
#include <QPushButton>
#include "person.h"

class FileInput : public QWidget
{
    Q_OBJECT

public:
    FileInput(QWidget *parent = nullptr);
    void set_GUI();
public slots:
    void writeToFile(QObject *obj);
    void QDout(); //just a test function to test my 'connect' part
private:
    QPushButton *xx;
    QPushButton *pp;
};
#endif // FILEINPUT_H

person.h

#ifndef PERSON_H
#define PERSON_H

#include <QObject>
#include <QDate>

class Person : public QObject
{
    Q_OBJECT
    Q_PROPERTY(QString name READ getName WRITE setName)
    Q_PROPERTY(QDate birth READ getBirth WRITE setBirth)
public:
    Person();
    Person(QString n, QDate d);

    QString getName() const;
    QDate getBirth() const;

    void setName(QString n);
    void setBirth(QDate d);

private:
    QString name;
    QDate birthDate;
};

class Product : public QObject
{
    Q_OBJECT
    Q_PROPERTY(QString name READ getName WRITE setName)
    Q_PROPERTY(double price READ getPrice WRITE setPrice)
public:
    Product();
    Product(QString n, double d);

    QString getName() const;
    double getPrice() const;

    void setName(QString n);
    void setPrice(double d);

private:
    QString name;
    double price;
};

#endif // PERSON_H

And then i have 3 .cpp files

filminput.cpp

#include "fileinput.h"

#include <QPushButton>
#include <QVBoxLayout>

#include <QMetaObject>
#include <QMetaProperty>
#include <QFile>
#include <QTextStream>

FileInput::FileInput(QWidget *parent)
    : QWidget(parent)
{
}

void FileInput::set_GUI()
{
    QWidget *w = new QWidget;
    w->resize(250,250);
    w->setWindowTitle("Q Meta Nonsence");

    Product lem = Product();
    lem.setName("PHIL");
    lem.setPrice(16.45);

    xx = new QPushButton("Exit");
    pp = new QPushButton("Print");

    QVBoxLayout *ll = new QVBoxLayout;

    ll->addWidget(xx);
    ll->addWidget(pp);
    ll->setSpacing(25);

    w->setLayout(ll);
    w->show();

    connect(xx,SIGNAL(clicked()),w,SLOT(close()));

    connect(pp,SIGNAL(clicked()),this,SLOT(writeToFile(lem)));
}

void FileInput::QDout() //just prints 'success' when pressing the 'print' button
{
    qDebug() << "success";
}

//this next function is supposed to write to the data.txt file
void FileInput::writeToFile(QObject *obj)
{
    QFile file("C:/Users/marti/Documents/Qt/QM/data.txt");
    if(!file.open(QFile::WriteOnly|QFile::Text|QFile::Append))
    {
        qDebug() << "Already open or there is another issue";
        file.close();
    }
    QTextStream toFile(&file);

    const QMetaObject *mo = obj->metaObject();
    for(int i=mo->propertyOffset(); i<mo->propertyCount(); i++)
    {
        const QMetaProperty prop = mo->property(i);
        QString name = prop.name();
        QVariant value = prop.read(obj);
        QString valStr = value.toString();
        toFile << name << ": " << valStr << "\n";
    }
    file.close();
}

person.cpp

#include "person.h"

Person::Person()
{
    name = QString();
    birthDate = QDate();
}

Person::Person(QString n, QDate d)
{
    name = n;
    birthDate = d;
}

QString Person::getName() const
{
    return name;
}

QDate Person::getBirth() const
{
    return birthDate;
}

void Person::setName(QString n)
{
    name = n;
}

void Person::setBirth(QDate d)
{
    birthDate = d;
}

Product::Product()
{
    name = QString();
    price = 0.0;
}

Product::Product(QString n, double d)
{
    name = n;
    price = d;
}

QString Product::getName() const
{
    return name;
}

double Product::getPrice() const
{
    return price;
}

void Product::setName(QString n)
{
    name = n;
}

void Product::setPrice(double d)
{
    price = d;
}

main.cpp

#include "fileinput.h"

#include <QApplication>

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

    return a.exec();
}

Solution

  • You're using the older connect syntax which masks the problem that you're connecting a signal with no parameters to a slot that wants a parameter. To fix it use the new syntax and use a lambda to provide the extra parameter.

    connect(pp, &QPushButton::clicked, this, [=](){ writeToFile(lem); });