Getting error when saving file from QML to Sqlite. Error like this =>Property 'saveToSqlite' of object QObject(0x7ffcfa692910) is not a function
-
My Full code is =>
dbmanager.h file==>
#ifndef DBMANAGER_H
#define DBMANAGER_H
#include <QObject>
#include <QSqlDatabase>/**
-
\class DbManager
-
\brief SQL Database Manager class
-
DbManager sets up the connection with SQL database
-
and performs some basics queries. The class requires
-
existing SQL database. You can create it with sqlite:
-
- $ sqlite3 people.db
-
- sqilte> CREATE TABLE people(ids integer primary key, name text);
-
- sqlite> .quit
*/
class DbManager : public QObject
{
// Q_OBJECT
public:
explicit DbManager(QObject *parent = nullptr);
/**
- @brief Constructor
- Constructor sets up connection with db and opens it
- @param path - absolute path to db file
*/
DbManager(const QString& path);
/**
- @brief Destructor
- Close the db connection
*/
~DbManager();
bool isOpen() const;
/**
- @brief Creates a new 'people' table if it doesn't already exist
- @return true - 'people' table created successfully, false - table not created
*/
bool createTable();
/**
- @brief Add person data to db
- @param name - name of person to add
- @return true - person added successfully, false - person not added
*/
bool addRecord(const QString &name, const QString &fatherName,
const QString &motherName, const QString &mobileNumber,
const QString &selectedGender, const QString &qualification,
const QString &skills, const QString &state,
const QString &city, const QString &landmark,
const QString &pincode);/**
- @brief Remove person data from db
- @param name - name of person to remove.
- @return true - person removed successfully, false - person not removed
*/
bool removeRecord(const QString& name);
/**
- @brief Check if person of name "name" exists in db
- @param name - name of person to check.
- @return true - person exists, false - person does not exist
*/
bool recordExists(const QString& name) const;
/**
- @brief Print names of all persons in db
*/
void printAllRecords() const;
/**
- @brief Remove all persons from db
- @return true - all persons removed successfully, false - not removed
*/
bool removeAllRecords();
- sqlite> .quit
public slots:
//It will Save Data From QML UI to Sqlite Q_INVOKABLE bool saveToSqlite(const QString &data);
private:
QSqlDatabase m_db;
};#endif // DBMANAGER_H
filehandler.h file==>
#ifndef FILEHANDLER_H
#define FILEHANDLER_H#include <QObject>
#include <QSqlDatabase>class FileHandler : public QObject
{
Q_OBJECT
public:
explicit FileHandler(QObject *parent = nullptr);/*Constructor sets up connection with db and opens it path - absolute path to db file*/ FileHandler(const QString& path);
public slots:
//It will Save Data From QML UI to File
Q_INVOKABLE bool saveToFile(const QString &data);private:
QSqlDatabase m_db;
};#endif // FILEHANDLER_H
========================================
dbmanager.cpp file==>#include "dbmanager.h"
#include <QFile>
#include <QTextStream>
#include <QDateTime>
#include <QDebug>#include <QSqlQuery>
#include <QSqlError>
#include <QSqlRecord>DbManager::DbManager(const QString &path)
{
m_db = QSqlDatabase::addDatabase("QSQLITE");
m_db.setDatabaseName(path);if (!m_db.open()) { qDebug() << "Error: connection with database fail"; } else { qDebug() << "Database Connected Successfully !!!"; }
}
DbManager::~DbManager()
{
if (m_db.isOpen())
{
m_db.close();
}
}bool DbManager::isOpen() const
{
return m_db.isOpen();
}bool DbManager::createTable()
{
bool success = false;QSqlQuery query; query.prepare("CREATE TABLE student1 (id INTEGER PRIMARY KEY, name TEXT, fatherName TEXT, motherName TEXT, mobileNumber TEXT, gender TEXT, qualification TEXT, skills TEXT, state TEXT, city TEXT, landmark TEXT, pincode TEXT)"); if (!query.exec()) { qDebug() << "Couldn't create the table 'student1': one might already exist."; success = false; } return success;
}
bool DbManager::addRecord(const QString &name, const QString &fatherName,
const QString &motherName, const QString &mobileNumber,
const QString &selectedGender, const QString &qualification,
const QString &skills, const QString &state,
const QString &city, const QString &landmark,
const QString &pincode)
{
if (isOpen())
{
QSqlQuery queryAdd;
queryAdd.prepare("INSERT INTO student1 (name, fatherName, motherName, mobileNumber, gender, qualification, skills, state, city, landmark, pincode) "
"VALUES (:name, :fatherName, :motherName, :mobileNumber, :gender, :qualification, :skills, :state, :city, :landmark, :pincode)");
queryAdd.bindValue(":name", name);
queryAdd.bindValue(":fatherName", fatherName);
queryAdd.bindValue(":motherName", motherName);
queryAdd.bindValue(":mobileNumber", mobileNumber);
queryAdd.bindValue(":gender", selectedGender);
queryAdd.bindValue(":qualification", qualification);
queryAdd.bindValue(":skills", skills);
queryAdd.bindValue(":state", state);
queryAdd.bindValue(":city", city);
queryAdd.bindValue(":landmark", landmark);
queryAdd.bindValue(":pincode", pincode);if (queryAdd.exec()) { return true; } else { qDebug() << "Data insertion failed: " << queryAdd.lastError(); } } else { qDebug() << "Database is not open!"; } return false;
}
bool DbManager::removeRecord(const QString& name)
{
bool success = false;if (recordExists(name)) { QSqlQuery queryDelete; queryDelete.prepare("DELETE FROM people WHERE name = (:name)"); queryDelete.bindValue(":name", name); success = queryDelete.exec(); if(!success) { qDebug() << "remove person failed: " << queryDelete.lastError(); } } else { qDebug() << "remove person failed: person doesnt exist"; } return success;
}
void DbManager::printAllRecords() const
{
qDebug() << "Persons in Database:";
QSqlQuery query("SELECT * FROM student1");if (!query.exec()) { qDebug() << "Error executing query: " << query.lastError().text(); return; } while (query.next()) { QString name = query.value("name").toString(); QString fatherName = query.value("fatherName").toString(); QString motherName = query.value("motherName").toString(); QString mobileNumber = query.value("mobileNumber").toString(); QString selectedGender = query.value("gender").toString(); QString qualification = query.value("qualification").toString(); QString skills = query.value("skills").toString(); QString state = query.value("state").toString(); QString city = query.value("city").toString(); QString landmark = query.value("landmark").toString(); QString pincode = query.value("pincode").toString(); qDebug() << "Name: " << name; qDebug() << "Father's Name: " << fatherName; qDebug() << "Mother's Name: " << motherName; qDebug() << "Mobile Number: " << mobileNumber; qDebug() << "Gender: " << selectedGender; qDebug() << "Qualification: " << qualification; qDebug() << "Skills: " << skills; qDebug() << "State: " << state; qDebug() << "City: " << city; qDebug() << "Landmark: " << landmark; qDebug() << "Pincode: " << pincode; }
}
bool DbManager::recordExists(const QString& name) const
{
bool exists = false;QSqlQuery checkQuery; checkQuery.prepare("SELECT name FROM people WHERE name = (:name)"); /////////////////////////////////////// checkQuery.bindValue(":name", name); if (checkQuery.exec()) { if (checkQuery.next()) { exists = true; } } else { qDebug() << "person exists failed: " << checkQuery.lastError(); } return exists;
}
bool DbManager::removeAllRecords()
{
bool success = false;QSqlQuery removeQuery; removeQuery.prepare("DELETE FROM people"); if (removeQuery.exec()) { success = true; } else { qDebug() << "remove all persons failed: " << removeQuery.lastError(); } return success;
}
bool DbManager::saveToSqlite(const QString &data)
{
QStringList list =data.split(",");
qDebug()<<"Input Data" <<list;
printAllRecords();addRecord(list.at(0),list.at(1),list.at(2),list.at(3),list.at(4),list.at(5),list.at(6),list.at(7) ,list.at(8),list.at(9),list.at(10)); printAllRecords();
}
========================================
filehandler.cpp file==>#include "filehandler.h"
#include <QFile>
#include <QTextStream>
#include <QDateTime>
#include <QDebug>#include <QSqlQuery>
#include <QSqlError>
#include <QSqlRecord>FileHandler::FileHandler(const QString& path)
{
m_db= QSqlDatabase::addDatabase("QSQLITE");
m_db.setDatabaseName(path);if(!m_db.open()) { qDebug() << "Error: connection with database fail !!!"; } else { qDebug() << "Database Connected Successfully !!!"; }
}
FileHandler::FileHandler(QObject *parent) : QObject(parent){}
bool FileHandler::saveToFile(const QString &data)
{
QString fileName = QDateTime::currentDateTime().toString("dd-mm-yyyy-hh:mm:ss");
fileName +=".txt";QFile file("/root/Desktop/"+fileName); if(!file.open(QIODevice::WriteOnly | QIODevice::Text)) return false; QTextStream stream(&file); stream << data; file.close(); return true;
}
========================================
main.cpp file ==>
#include <QGuiApplication>
#include <QQmlApplicationEngine>
#include <QQmlContext>
#include <filehandler.h>
#include <dbmanager.h>
static const QString path = "example.db";int main(int argc, char *argv[])
{
QGuiApplication app(argc, argv);
QQmlApplicationEngine engine;
FileHandler fileHandler(path);DbManager dbManager(path); // engine.rootContext()->setContextProperty("file_Handler", &fileHandler); engine.rootContext()->setContextProperty("d_bmmanager", &dbManager); // engine.load(QUrl(QStringLiteral("qrc:/main.qml"))); if (engine.rootObjects().isEmpty()) return -1; return app.exec();
}
========================================
main.qml file==>import QtQuick 2.15
import QtQuick.Window 2.15
import QtQuick.Controls 2.12
import QtQuick.Layouts 1.3
import QtQuick.Dialogs 1.2Window {
id: window
width: 500
height: 700
visible: true
title: qsTr("Student Login Form")
flags: Qt.SplashScreen | Qt.FramelessWindowHintproperty string name: "" property string fatherName: "" property string motherName: "" property string mobileNumber: "" property string rajya: "" property string city: "" property string landMark: "" property string pinCode: "" property var selectedItems: [] property string selectedGender: "" //Top Heading Rectangle{ id:containerRect y: 0 height: 44 anchors.left: parent.left anchors.right: parent.right anchors.leftMargin: 0 anchors.rightMargin: 0 color: "dodgerblue" border.color: "#000000" border.width: 6 //Heading Name Text{ width: 245 height: 29 anchors.centerIn: parent text: "Student Login Form" font.family: "Times New Roman" anchors.verticalCenterOffset: -5 anchors.horizontalCenterOffset: 3 color: "#fefff6" font.pointSize: 20 } Button { id: button1 x: 389 y: 8 width: 98 height: 26 text: qsTr("Close") font.bold: true MouseArea{ anchors.fill: parent onClicked: { Qt.quit(); } Rectangle{ anchors.centerIn:parent width: 98 height: 26 radius: 2 color: "red" } } } } Rectangle{ id:containerRect1 color: "#f1ffffff" radius: 6 border.color: "#f797187f" border.width: 2 anchors.fill: parent anchors.rightMargin: 8 anchors.bottomMargin: 23 anchors.leftMargin: 9 anchors.topMargin: 53 GroupBox { id: groupBox height: 312 anchors.left: parent.left anchors.right: parent.right anchors.top: parent.top anchors.bottomMargin: -1 layer.textureSize.width: 4 anchors.rightMargin: 15 anchors.leftMargin: 11 anchors.topMargin: 2 title: qsTr("Personal Details") Label { id: label x: 50 y: 17 text: qsTr("Name") } Label { id: label1 x: 50 y: 47 text: qsTr("Father's Name") rotation: -1.907 } Label { id: label2 x: 50 y: 81 text: qsTr("Mother's Name") } Label { id: label3 x: 50 y: 123 text: qsTr("Mobile Number") } Label { id: label4 x: 50 y: 164 width: 49 height: 30 text: qsTr("Gender") } Label { id: label5 x: 50 y: 211 text: qsTr("Qualification") } TextField { id: nameTextField x: 175 y: 8 width: 238 height: 29 text: "Pappu" placeholderText: qsTr("Enter your name") onTextChanged: name=text } TextField { id: fatherNameTextField x: 175 y: 44 width: 238 height: 29 text: "Father Name" placeholderText: qsTr("Enter your Father's name ") onTextChanged: fatherName=text } TextField { id: motherNameTextField x: 175 y: 81 width: 238 height: 29 text: "Mother name" placeholderText: qsTr("Enter your Mother's name ") onTextChanged: motherName=text } TextField { id: mobileNumberTextField x: 175 y: 123 width: 238 height: 29 text: "85254" placeholderText: qsTr("Enter your mobile number") onTextChanged: mobileNumber=text } RowLayout{ x: 165 y: 160 scale: 0.9 RadioButton{ text: "Male" checked: selectedGender==="Male" onClicked: { if(checked) selectedGender="Male" } } RadioButton{ text: "Female" checked: selectedGender==="Female" onClicked: { if(checked) selectedGender="Female" } } } ComboBox { id: comboBox x: 178 y: 206 width: 140 height: 30 model: ["--Select--","10th","12th","Graduation","Post Graduation"] } Label { id: label10 x: 50 y: 244 text: qsTr("Skills") } Row{ spacing: 10 x: 170 y: 235 CheckBox { id: checkBoxC text: qsTr("C") checked: true } CheckBox { id: checkBoxCPlusPlus text: qsTr("C++") } CheckBox { id: checkBoxQt text: qsTr("Qt") } } } GroupBox { id: groupBox1 height: 254 anchors.left: parent.left anchors.right: parent.right anchors.top: parent.top anchors.rightMargin: 13 anchors.leftMargin: 13 anchors.topMargin: 314 title: qsTr("Address") Label { id: label6 x: 50 y: 27 width: 53 height: 20 text: qsTr("State") } Label { id: label7 x: 50 y: 72 width: 50 height: 20 text: qsTr("City") } Label { id: label8 x: 50 y: 125 width: 83 height: 20 text: qsTr("Land mark") } Label { id: label9 x: 50 y: 175 width: 61 height: 20 text: qsTr("Pincode") } TextField { id: stateTextField x: 178 y: 21 width: 238 height: 29 text: "Kar" placeholderText: qsTr("Enter your State") onTextChanged: rajya=text } TextField { id: cityTextField x: 178 y: 72 width: 238 height: 29 text: "Bang" placeholderText: qsTr("Enter your City ") onTextChanged:city=text } TextField { id: landmarkTextField x: 175 y: 126 width: 238 height: 29 text: "BEL" placeholderText: qsTr("Enter your Landmark ") onTextChanged: landMark=text } TextField { id: pincodeTextField x: 175 y: 176 width: 238 height: 29 text: "560013" placeholderText: qsTr("Enter your Pincode ") onTextChanged: pinCode=text } } Button { id: button x: 172 y: 568 width: 99 height: 37 text: qsTr("Submit") layer.format: ShaderEffectSource.RGB font.weight: Font.Bold font.underline: false font.strikeout: false font.bold: true font.family: "Verdana" onClicked: { //It will show Data From UI to Console // console.log("Name is :",name) // console.log("Father's Name is :",fatherName) // console.log("Mother's Name is :",motherName) // console.log("Mobile Number is :",mobileNumber) // console.log("Gender is :",selectedGender) var selectedItem=comboBox.currentText var selectedIndex=comboBox.currentIndex if(selectedIndex==0) { // console.log("Qualification is :",) } else { // console.log("Qualification is :",selectedItem) } selectedItems=[]; if(checkBoxC.checked) selectedItems.push(checkBoxC.text) if(checkBoxCPlusPlus.checked) selectedItems.push(checkBoxCPlusPlus.text) if(checkBoxQt.checked) selectedItems.push(checkBoxQt.text) // console.log("Skills :",selectedItems.toString()) // console.log("State is :",rajya) // console.log("City is :",city) // console.log("Land Mark is :",landMark) // console.log("Pincode is :",pinCode) //Save Data From UI to Text File var dataToSave = "Student's Name is : "+ nameTextField.text + "\n" + "Father's Name is : "+ fatherNameTextField.text +"\n"+ "Mother's Name is : "+ motherNameTextField.text +"\n"+ "Mobile Number is : "+ mobileNumberTextField.text +"\n"+ "Gender is : "+ selectedGender +"\n"+ "Qualification is : "+ selectedItem.toString() +"\n"+ "Skills : "+ selectedItems +"\n"+ "State is : "+ stateTextField.text +"\n"+ "City is : "+ cityTextField.text +"\n"+ "Landmark is : "+ landmarkTextField.text +"\n"+ "Pincode is : "+ pincodeTextField.text ; if (file_Handler.saveToFile(dataToSave)) { console.log("Data saved to file successfully."); } else { console.error("Error saving data to file."); } //Save Data From UI to Sqlite var skillsTxt = selectedItems.join(":").toString(); var csv_data = nameTextField.text + "," + fatherNameTextField.text +","+ motherNameTextField.text +","+ mobileNumberTextField.text +","+ selectedGender +","+ selectedItem+","+ skillsTxt +","+ stateTextField.text +","+ cityTextField.text +","+ landmarkTextField.text +","+ pincodeTextField.text ; if (d_bmmanager.saveToSqlite(csv_data)) { console.log("Data saved to Sqlite successfully."); } else { console.error("Error saving data to Sqlite."); } //It will Reset all field as blank nameTextField.text="" fatherNameTextField.text="" motherNameTextField.text="" mobileNumberTextField.text="" mobileNumberTextField.text="" stateTextField.text="" cityTextField.text="" landmarkTextField.text="" pincodeTextField.text="" //When Click on Save Button It will Display message "Data Saved Successfully !!!" and Main window will close var messageDialog = Qt.createQmlObject('import QtQuick.Dialogs 1.2; MessageDialog{}',parent); messageDialog.text = "Data Saved Successfully !!!"; messageDialog.standardButtons = StandardButton.Ok; messageDialog.accepted.connect(function(){ //Close the window when "OK" button is clicked window.close(); }); messageDialog.open(); } Rectangle{ anchors.centerIn: parent width: 99 height: 37 color: "green" anchors.verticalCenterOffset: 2 anchors.horizontalCenterOffset: 0 } } }
}
When above code is running then it is showing error like==>
TypeError: Property 'saveToSqlite' of object QObject(0x7ffe8aee8090) is not a function========================================
On consile it is showing like this==>
Database Connected Successfully !!!
QSqlDatabasePrivate::removeDatabase: connection 'qt_sql_default_connection' is still in use, all queries will cease to work.
QSqlDatabasePrivate::addDatabase: duplicate connection name 'qt_sql_default_connection', old connection removed.
Database Connected Successfully !!!
qml: Data saved to file successfully.
qrc:/main.qml:433: TypeError: Property 'saveToSqlite' of object QObject(0x7ffe8aee8090) is not a function -
-
Hi,
Please use coding tags when posting code. Otherwise it's unreadable.
Next, reduce your code to the bare minimum required to analyse your issue. Remove everything unrelated to your issue. Not many people will be interested in going through that much code with just an error message as entry point.
One thing that is an issue I can see is that you are declaring your invokable function in the slot section of your class. Although related, they are two different things.
-
S SGaist referenced this topic on