Solved QML/QSqlQueryModel program Crashed I don't understand why
-
Hi everyone
I'm new in Qt/C++ and QML. I was trying to Connect SQLite Database to QML with C++QSqlQueryModel
andQSqlDatabase
. I found this and Used this to wrote my Program and this is my code://database.h #include <QtSql/QSqlDatabase> #include <QSqlQuery> #include <QFileInfo> class Database { public: Database(); ~Database(); void open(); private: QSqlDatabase *db; };
//database.cpp #include "database.h" #include <QDebug> Database::Database() { } Database::~Database() { db->close(); } void Database::open() { QFileInfo file("database.db"); *db = QSqlDatabase::addDatabase("QSQLITE"); db->setDatabaseName("database.db"); db->setUserName("database"); db->setPassword("database"); if(file.exists()) { db->open(); return; } else { db->open(); QSqlQuery query; query.exec("CREATE TABLE person (" "id INT PRIMARY KEY," "name TEXT NOT NULL," "phone TEXT NOT NULL UNIQUE);"); query.exec("INSERT INTO person(id, name, phone) " "VALUES(1, 'Paul', '0123434' )"); query.exec("INSERT INTO person(id, name, phone) " "VALUES(2, 'Alex', '0765333' )"); query.exec("INSERT INTO person(id, name, phone) " "VALUES(3, 'Sara', '56753' )"); query.exec("INSERT INTO person(id, name, phone) " "VALUES(4, 'Mindcraft', '345755' )"); } }
//dataModel.h #include <QSqlQueryModel> class dataModel : public QSqlQueryModel { Q_OBJECT public: explicit dataModel(QObject *parent = 0); void setQuery(const QString &query, const QSqlDatabase &db = QSqlDatabase()); void setQuery(const QSqlQuery &query); QVariant data(const QModelIndex &index, int role) const; QHash<int, QByteArray> roleNames() const { return m_roleNames; } private: void generateRoleNames(); QHash<int, QByteArray> m_roleNames; };
//dataModel.cpp #include "datamodel.h" #include <QSqlRecord> #include <QSqlField> dataModel::dataModel(QObject *parent) : QSqlQueryModel(parent) { } void dataModel::setQuery(const QString &query, const QSqlDatabase &db) { QSqlQueryModel::setQuery(query, db); generateRoleNames(); } void dataModel::setQuery(const QSqlQuery &query) { QSqlQueryModel::setQuery(query); generateRoleNames(); } QVariant dataModel::data(const QModelIndex &index, int role) const { QVariant value; if(role < Qt::UserRole) { value = QSqlQueryModel::data(index, role); } else { int columnIdx = role - Qt::UserRole - 1; QModelIndex modelIndex = this->index(index.row(), columnIdx); value = QSqlQueryModel::data(modelIndex, Qt::DisplayRole); } return value; } void dataModel::generateRoleNames() { m_roleNames.clear(); for( int i = 0; i < record().count(); i ++) { m_roleNames.insert(Qt::UserRole + i + 1, record().fieldName(i).toUtf8()); } }
//main.cpp #include <QGuiApplication> #include <QQmlApplicationEngine> #include <QQmlContext> #include <QQmlComponent> #include "model/datamodel.h" #include "database/database.h" int main(int argc, char *argv[]) { Database dbase; dbase.open(); dataModel *model = new dataModel(); model->setQuery("select * from person"); QCoreApplication::setAttribute(Qt::AA_EnableHighDpiScaling); QGuiApplication app(argc, argv); QQmlApplicationEngine engine; QQmlContext *context = new QQmlContext(engine.rootContext()); context->setContextProperty("myModel", model); // QQmlComponent component(&engine); // component.setData("import QtQuick 2.0\nListView { model: myModel }", QUrl()); // QObject *window = component.create(context); engine.load(QUrl(QLatin1String("qrc:/main.qml"))); return app.exec(); }
//main.qml import QtQuick 2.7 import QtQuick.Controls 2.0 import QtQuick.Layouts 1.0 ApplicationWindow { id: root visible: true width: 640 height: 480 title: qsTr("Test QML Database Model") ListView { id: list_view anchors.centerIn: parent width: root/2 height: root/2 model: myModel delegate: Text { text: id + ": " + name + " " + phone } } }
It build fine but whenever I run the program I got this
The program has unexpectedly finished.
and Crashed.What is the problem?
-
Hi and welcome to devnet,
First thing to do: create your QApplication object before anything else. It initializes Qt's internals.
You are dereferencing a pointer that you didn't allocate in your Database class.
Also, please re-read the QSqlDatabase documentation on how to handle the your database connection object. -
thank you
I fix the database and model problem and they work fine but I still have problem to connect them to the QML
QQmlApplicationEngine engine; QQmlContext *context = new QQmlContext(engine.rootContext()); context->setContextProperty("myModel", model); engine.load(QUrl(QLatin1String("qrc:/main.qml")));
this part of my code doesn't work as I expect.
theQQmlApplicationEngine
work fine and show my qml file but theQQmlContext
doesn't work and I gotqrc:/main.qml:25: ReferenceError: myModel is not defined
error message.
I was trying to debug it but debugger not show any data of QML or what I want to show.
I think I should call engine source before thesetContextProperty
but I try different way and It hasn't worked yet.
Can you tell me what I missed or what I need to learn to fix it? -
Why are you creating a new QQmlContext ? Just use the one the engine gives you.
-
@SGaist Thanks man, everything work fine :)