Privacy policyContactsAbout siteOpinionsGitHubDonate
© EVILEG 2015-2018
Recommend hosting
TIMEWEB

QML - Lesson 016. SQLite database and the working with it in QML Qt

База данных, SQLite, Qt, QML, Android, DataBase, Model, View, MVC

A small example to work with the database in QML Qt. This lesson brings together information on the use of signals and slots in the Qt QML , access to C++ classes from QML layer implementation of the application interface on QML, as well as the implementation of the model/view for the database tables.

The database contains a table with a list of people, which has four columns:

  • id (INTEGER) - a unique record number;
  • FirstName (VARCHAR (255)) - First Name;
  • SurName (VARCHAR (255)) - Last Name;
  • Nik (VARCHAR (255)) - Nik name.

The application must implement removing and adding records to the database through the application interface. To add records to the database three fields for data entry will be used and a button that initiates the addition of data to an SQL database. Adding entries to the table through a wrapper class designed for this application is present in metodom.Takzhe ListModel class that implements the model of data representation for the information display in the TableView in QML layer.

Project structure

  • QmlDataBase.pro - the profile of the project;
  • database.h - wrapper class header file to work with the database;
  • database.cpp - file source wrapper class codes for the work with the database;
  • listmodel.h - header data model file;
  • listmodel.cpp - file source data model;
  • main.cpp - the main file of the application source code;
  • main.qml - basic qml file.

QmlDataBase.pro

To work with the database you need to connect sql module, as well as widgets module for native application appearance.

TEMPLATE = app

QT += qml quick widgets sql

SOURCES += main.cpp \
    database.cpp \
    listmodel.cpp

RESOURCES += qml.qrc

# Additional import path used to resolve QML modules in Qt Creator's code model
QML_IMPORT_PATH =

# Default rules for deployment.
include(deployment.pri)

HEADERS += \
    database.h \
    listmodel.h

main.cpp

Basically, source files are included wrapper classes to work with the database and data model class. Objects of these classes must be declared and initialized in the file, and configure access to these objects and their properties of QML layer.

Once access to the objects set of QML layer become available following object properties and functions are declared in its class as:

  1. Signals
  2. Slots
  3. As well as the functions that appear in the macro Q_PROPERTY
#include <QApplication>
#include <QQmlApplicationEngine>
#include <QQmlContext>

#include "database.h"
#include "listmodel.h"

int main(int argc, char *argv[])
{
    QApplication app(argc, argv);
    QQmlApplicationEngine engine;

    DataBase database;
    database.connectToDataBase();

    ListModel *model = new ListModel();

    engine.rootContext()->setContextProperty("myModel", model);
    engine.rootContext()->setContextProperty("database", &database);

    engine.load(QUrl(QStringLiteral("qrc:/main.qml")));

    return app.exec();
}

database.h

In this class, declared methods for working with the database:

  • methods to connect to the database, restore it;
  • methods for adding records to the database;
  • methods for deleting entries in the data table.

Connecting to a database is necessary for the proper operation of the data model that inherit from QSqlQueryModel . And, accordingly, it uses SQL queries to open in the database application.

This class implements the Facade design pattern, although not completely, because as I said, that one of QSqlQueryModel entities used in the data model in this lesson.

ATTENTION!!! - The database file is created in the folder C:/example , so the correct method or DataBase::connectToDataBase() example or create a folder on drive C.

#ifndef DATABASE_H
#define DATABASE_H

#include <QObject>
#include <QSql>
#include <QSqlQuery>
#include <QSqlError>
#include <QSqlDatabase>
#include <QFile>
#include <QDate>
#include <QDebug>

#define DATABASE_HOSTNAME   "NameDataBase"
#define DATABASE_NAME       "Name.db"

#define TABLE                   "NameTable"         
#define TABLE_FNAME             "FisrtName"         
#define TABLE_SNAME             "SurName"          
#define TABLE_NIK               "Nik"              

class DataBase : public QObject
{
    Q_OBJECT
public:
    explicit DataBase(QObject *parent = 0);
    ~DataBase();
    void connectToDataBase();

private:
    QSqlDatabase    db;

private:
    bool openDataBase();        
    bool restoreDataBase();     
    void closeDataBase();       
    bool createTable();         

public slots:
    bool inserIntoTable(const QVariantList &data);      // Adding entries to the table
    bool inserIntoTable(const QString &fname, const QString &sname, const QString &nik);
    bool removeRecord(const int id); // Removing records from the table on its id
};

#endif // DATABASE_H

database.cpp

Initialize the database connection is made by connectToDataBase() . The name of the table, database, file, and columns in the table specified in the directives define in the header file.

#include "database.h"

DataBase::DataBase(QObject *parent) : QObject(parent)
{

}

DataBase::~DataBase()
{

}

void DataBase::connectToDataBase()
{
    if(!QFile("C:/example/" DATABASE_NAME).exists()){
        this->restoreDataBase();
    } else {
        this->openDataBase();
    }
}

bool DataBase::restoreDataBase()
{
    if(this->openDataBase()){
        return (this->createTable()) ? true : false;
    } else {
        qDebug() << "Failed to restore the database";
        return false;
    }
    return false;
}

bool DataBase::openDataBase()
{
    db = QSqlDatabase::addDatabase("QSQLITE");
    db.setHostName(DATABASE_HOSTNAME);
    db.setDatabaseName("C:/example/" DATABASE_NAME);
    if(db.open()){
        return true;
    } else {
        return false;
    }
}

void DataBase::closeDataBase()
{
    db.close();
}

bool DataBase::createTable()
{
    QSqlQuery query;
    if(!query.exec( "CREATE TABLE " TABLE " ("
                            "id INTEGER PRIMARY KEY AUTOINCREMENT, "
                            TABLE_FNAME     " VARCHAR(255)    NOT NULL,"
                            TABLE_SNAME     " VARCHAR(255)    NOT NULL,"
                            TABLE_NIK       " VARCHAR(255)    NOT NULL"
                        " )"
                    )){
        qDebug() << "DataBase: error of create " << TABLE;
        qDebug() << query.lastError().text();
        return false;
    } else {
        return true;
    }
    return false;
}

bool DataBase::inserIntoTable(const QVariantList &data)
{
    QSqlQuery query;
    query.prepare("INSERT INTO " TABLE " ( " TABLE_FNAME ", "
                                             TABLE_SNAME ", "
                                             TABLE_NIK " ) "
                  "VALUES (:FName, :SName, :Nik)");
    query.bindValue(":FName",       data[0].toString());
    query.bindValue(":SName",       data[1].toString());
    query.bindValue(":Nik",         data[2].toString());

    if(!query.exec()){
        qDebug() << "error insert into " << TABLE;
        qDebug() << query.lastError().text();
        return false;
    } else {
        return true;
    }
    return false;
}

bool DataBase::inserIntoTable(const QString &fname, const QString &sname, const QString &nik)
{
    QVariantList data;
    data.append(fname);
    data.append(sname);
    data.append(nik);

    if(inserIntoTable(data))
        return true;
    else
        return false;
}

bool DataBase::removeRecord(const int id)
{
    QSqlQuery query;

    query.prepare("DELETE FROM " TABLE " WHERE id= :ID ;");
    query.bindValue(":ID", id);

    if(!query.exec()){
        qDebug() << "error delete row " << TABLE;
        qDebug() << query.lastError().text();
        return false;
    } else {
        return true;
    }
    return false;
}

listmodel.h

The data model is a class inherited from QSqlQueryModel , which override the data() and roleNames() . Also listed in the class of the role in which information is transmitted in the representation in the interface. To delete data, you must obtain a unique record ID, which extends from the model by the method of getID() on the role and line number that was passed from view. To retrieve data from databases used updateModel() method, which established SQL-query the database.

#ifndef LISTMODEL_H
#define LISTMODEL_H

#include <QObject>
#include <QSqlQueryModel>

class ListModel : public QSqlQueryModel
{
    Q_OBJECT
public:
    /* We list all the roles that will be used in the TableView. 
     * As you can see, they have to be in the memory above the parameter Qt::UserRole. 
     * Due to the fact that the information below this address is not for customizations
     * */
    enum Roles {
        IdRole = Qt::UserRole + 1,      // id
        FNameRole,                      // Firt name
        SNameRole,                      // Last name
        NikRole                         // Nik name
    };

    explicit ListModel(QObject *parent = 0);

    // Override the method that will return the data
    QVariant data(const QModelIndex & index, int role = Qt::DisplayRole) const;

protected:
    /* hashed table of roles for speakers. 
     * The method used in the wilds of the base class QAbstractItemModel, 
     * from which inherits the class QSqlQueryModel
     * */
    QHash<int, QByteArray> roleNames() const;

signals:

public slots:
    void updateModel();
    int getId(int row);
};

#endif // LISTMODEL_H

listmodel.cpp

For the implementation of the model in a file source connect the header file database.h , which features define directive for the names of tables and columns. Return data is performed on predefined roles, which must be identical in the TableView , which will be used to display data.

#include "listmodel.h"
#include "database.h"

ListModel::ListModel(QObject *parent) :
    QSqlQueryModel(parent)
{
    this->updateModel();
}

// The method for obtaining data from the model
QVariant ListModel::data(const QModelIndex & index, int role) const {

    // Define the column number, on the role of number
    int columnId = role - Qt::UserRole - 1;
    // Create the index using a column ID
    QModelIndex modelIndex = this->index(index.row(), columnId);

    return QSqlQueryModel::data(modelIndex, Qt::DisplayRole);
}

QHash<int, QByteArray> ListModel::roleNames() const {

    QHash<int, QByteArray> roles;
    roles[IdRole] = "id";
    roles[FNameRole] = "fname";
    roles[SNameRole] = "sname";
    roles[NikRole] = "nik";
    return roles;
}

// The method updates the tables in the data model representation
void ListModel::updateModel()
{
    // The update is performed SQL-queries to the database
    this->setQuery("SELECT id, " TABLE_FNAME ", " TABLE_SNAME ", " TABLE_NIK " FROM " TABLE);
}

// Getting the id of the row in the data view model
int ListModel::getId(int row)
{
    return this->data(this->index(row, 0), IdRole).toInt();
}

main.qml

In Qt Model / View / Controller paradigm change in the model / view . Presentation combines a controller and a view. Thus, main.qml processes the information that the user enters and passes it to the backend in a digestible form, but when you consider that the object class is given database access layer of QML, and the addition of data is made through the function slot, it can be roughly assumed that the the controller is implemented in the view.

import QtQuick 2.5
import QtQuick.Controls 1.4
import QtQuick.Layouts 1.1
import QtQuick.Dialogs 1.2

ApplicationWindow {
    visible: true
    width: 640
    height: 480
    title: qsTr("Hello World")

    RowLayout {
        id: rowLayout
        anchors.top: parent.top
        anchors.left: parent.left
        anchors.right: parent.right
        anchors.margins: 5

        spacing: 10

        Text {text: qsTr("Имя")}
        TextField {id: fnameField}
        Text {text: qsTr("Фамилия")}
        TextField { id: snameField}
        Text {text: qsTr("НИК")}
        TextField {id: nikField}

        Button {
            text: qsTr("Add")

            // Make a new entry in the database
            onClicked: {
                database.inserIntoTable(fnameField.text , snameField.text, nikField.text)
                myModel.updateModel() // And updates the data model with a new record
            }
        }
    }

    TableView {
        id: tableView
        anchors.top: rowLayout.bottom
        anchors.left: parent.left
        anchors.right: parent.right
        anchors.bottom: parent.bottom
        anchors.margins: 5

        TableViewColumn {
            role: "fname"
            title: "First Name"
        }
        TableViewColumn {
            role: "sname"
            title: "Last name"
        }
        TableViewColumn {
            role: "nik"
            title: "Nik name"
        }

        model: myModel

        // Setting lines in TableView to intercept mouse left click
        rowDelegate: Rectangle {
            anchors.fill: parent
            color: styleData.selected ? 'skyblue' : (styleData.alternate ? 'whitesmoke' : 'white');
            MouseArea {
                anchors.fill: parent
                acceptedButtons: Qt.RightButton | Qt.LeftButton
                onClicked: {
                    tableView.selection.clear()
                    tableView.selection.select(styleData.row)
                    tableView.currentRow = styleData.row
                    tableView.focus = true

                    switch(mouse.button) {
                    case Qt.RightButton:
                        contextMenu.popup() // Call the context menu
                        break
                    default:
                        break
                    }
                }
            }
        }
    }

    // The context menu offers deleting a row from the database
    Menu {
        id: contextMenu

        MenuItem {
            text: qsTr("Remove")
            onTriggered: {
                /* Call the dialog box that will clarify the intention to remove the row from the database
                 * */
                dialogDelete.open()
            }
        }
    }

    // Dialog of confirmation the removal line from the database
    MessageDialog {
        id: dialogDelete
        title: qsTr("Remove record")
        text: qsTr("Confirm the deletion of log entries")
        icon: StandardIcon.Warning
        standardButtons: StandardButton.Ok | StandardButton.Cancel

        // If the answer ...
        onAccepted: {
            /* ... remove the line by id, which is taken from the data model 
             * on the line number in the presentation
             * */
            database.removeRecord(myModel.getId(tableView.currentRow))
            myModel.updateModel(); 
        }
    }
}

Conclusion

As a result, you get an application that will appear as shown in the following figure.

In addition, I recommend reading more about Facade design pattern and see a more complete embodiment of this pattern in the following article: "Design pattern "Facade"

Video

We recommend hosting TIMEWEB
We recommend hosting TIMEWEB
Stable hosting, on which the social network EVILEG is located. For projects on Django we recommend VDS hosting.
Добрый день, запустил ваш пример при нажатии на кнопку получаю вот эту ошибку

ASSERT failure in QList<T>::operator[]: "index out of range", file ../../Qt5.11.0/5.11.0/gcc_64/include/QtCore/qlist.h, line 545

Подскажите пожалуйста в чём может быть дело на что она указывает где искать ?
Разобрался, не правильное добавление записи в БД а именно лишний запрос query.bindValue стоял в методе inserIntoTable.
W
  • #
  • June 15, 2018, 2:08 p.m.

Добрый день, пытаюсь передать текст из QML слоя в C++ при нажатии на кнопку. При нажатии на кнопку выводит ошибку.


TypeError: Property 'remove_db' of object [object Object] is not a function
Не могу понять в чем ошибка(новичок в Qt) Если есть возможно можно простой пример как передать текст или число из QML лося в C++ или где ошибка в моем коде. Спасибо заранее)
QML:

import QtQuick 2.0
import Sailfish.Silica 1.0
import QtPositioning 5.3
import QtLocation 5.0
import QtQuick 2.0
import QtWebKit 3.0
import MyModule 1.0

Page{
    id: pageMenu
    GPSCoor{
        id:data
        // @disable-check M16
        onSendToTime:
        {
            myModel.append({"time" : data_time_real_time})
        }
    }

    Rectangle{
        id: kv_menu
        anchors.fill: parent                                                 //Привязка к радителю
        color: "steelblue"
        ListView
        {
            id: myListView
            anchors
            {
                top: kv_menu.top
                right: kv_menu.right
                left: kv_menu.left
                bottom: buttonHistory.top

                rightMargin: 30
                leftMargin: 30
                topMargin: 30
                bottomMargin: 100
            }

            model: myModel
            delegate: Item{
                id:itemrec
                width: myListView.width
                height: 90

                Button{
                    id: rectest
                    anchors.margins: 6
                    anchors.fill: parent

                    Text
                    {
                        id:textNuj
                        objectName: "textZae"
                        color: "white"
                        font.pixelSize: 40
                        text: time + " - " + (model.index+1)
                        anchors.horizontalCenter: rectest.horizontalCenter
                        anchors.verticalCenter: rectest.verticalCenter
                    }
                    onClicked:
                    {
//                        console.log("text - " + text)
//                        console.log("modelN - "+ model.index)
//                        console.log("textNuj - " + textNuj.text)
//                        //pageStack.push(dialog)
                        data.remove_db(model.index);
                    }
                }
            }
        }
        ListModel
        {
            id:myModel
        }
        Button
        {
            id: buttonHistory
            height: 90
            anchors{
                right: kv_menu.right
                left: kv_menu.left
                bottom: kv_menu.bottom

                rightMargin: 30
                leftMargin: 30
                bottomMargin: 30
            }
            Label{
                color: "white"
                text: "Показать треки"
                anchors.horizontalCenter: buttonHistory.horizontalCenter
                anchors.verticalCenter: buttonHistory.verticalCenter
            }
            onClicked: {
                data.pageMapX()
            }
        }
    }
    Component{
        id: dialog
        Dialog {
            id: winDialog
            property string name

            Rectangle{
                id:winDialogRec1
                color: "steelblue"
                anchors.fill: parent
                property string name
                DialogHeader
                {   id: dialogHeader
                    acceptText: qsTr("Принять")
                    cancelText: qsTr("Отменить")
                }
                Rectangle{
                    id:winDialogRec
                    color: "steelblue"
                    anchors.horizontalCenter: parent.horizontalCenter
                    anchors.top: parent.top
                    anchors.topMargin: 400

                    Label{
                        id:label1
                        anchors{
                           horizontalCenter: winDialogRec.horizontalCenter
                           top: parent.top
                        }
                        color: "white"
                        text: "Вы действительно хотите удалить трек?"
                    }
                    Label{
                        id: label2
                        anchors{
                            horizontalCenter: winDialogRec.horizontalCenter
                            top: parent.top

                            topMargin: 250

                        }
                        color: "white"
                        text: name
                    }
                    Button{
                        width: parent / 2 - 45
                        anchors{
                            top: parent.top
                            left: parent.left
                            topMargin: 120
                            leftMargin: 30
                        }
                        text: "Нет"
                        onClicked:
                        {
                           label2.text = "Нет, не удалять этот трек"
                        }
                    }
                    Button{

                        width: parent / 2 - 45
                        anchors{
                            top: parent.top
                            right: parent.right
                            topMargin: 120
                            rightMargin: 30
                        }

                        text: "Да"
                        onClicked:
                        {
                           label2.text = "Да, удалить этот трек"
                         }
                    }

                }

            }

        }
    }
}
Заголовок:
#ifndef GPSCOOR_H
#define GPSCOOR_H
#include <QObject>
#include <QDebug>

class GPSCoor: public QObject
{
    Q_OBJECT
    Q_PROPERTY(double x_cor READ  getSomePropertyX   WRITE setSomePropertyX   NOTIFY sendToQml)     //Для обменна даными с переменной x_cor
    Q_PROPERTY(double y_cor READ  getSomePropertyY   WRITE setSomePropertyY   NOTIFY sendToQml)     //Для обменна даными с переменной y_cor
    Q_PROPERTY(QString way   READ  getSomePropertyWay WRITE setSomePropertyWay NOTIFY sendToWay)     //Для обменна даными о времени t
    Q_PROPERTY(QString data_time_real_time  READ  getSomePropertyTime   WRITE setSomePropertyTime   NOTIFY sendToTime)     //Для обменна даными о расстоянии m

    //    Q_PROPERTY(double arreyXY READ  getSomePropertyX WRITE setSomePropertyX NOTIFY sendToQml)     //Для обменна даными с переменной x_cor

public:
    explicit GPSCoor(QObject *parent = 0);
    Q_INVOKABLE void remove_db();

    double getSomePropertyX()const;                                                             //Для обменна даными с переменной x_cor
    double getSomePropertyY()const;                                                             //Для обменна даными с переменной y_cor
    QString getSomePropertyTime()const;                                                          //Для обменна даными о времени t
    QString getSomePropertyWay()const;                                                           //Для обменна даными о расстоянии m

    void setSomePropertyY(const double &);                                                      //Для обменна даными с переменной y_cor
    void setSomePropertyX(const double &);                                                      //Для обменна даными с переменной x_cor
    void setSomePropertyTime(const QString &);                                                   //Для обменна даными о времени t
    void setSomePropertyWay(const QString &);                                                    //Для обменна даными о расстоянии m

    void creat_db();                                                                            //Для создания базы данных и записи данных
    void insert_db();                                                                           //Для извлечения данных и бызы
    void distance();

    //Для выисления растояния от точки до точки
signals:
    void sendToQml(double);                                                                     //Сигнал для передачи данных в qml
    void sendToWay(QString);
    void sendToTime(QString);

public slots:

    void reciveX();                                                                             //Сигнал для получения данных с qml(FirstPage)
    void reciveTime();                                                                          //Сигнал для получения данных о времени
    //   void reciveWay();
    void pageMapX();                                                                            //Сигнал для получения данных с qml(Map)


private:
    QString data_time_real_time;
    QString way;
    double x_cor;                                                                               //Перменная координата х_cor
    double y_cor;                                                                               //Перменная координата y_cor
    int data_time;                                                                              //Перменная для измерении времени

    double Way_point=0;

    float CMX11 = 0;
    float CMY11 = 0;
    float CMX21 = 0;
    float CMY21 = 0;
    const float pi = 3.141592653589793;
    const float radius = 6378.16;
    double num =  1;                                                                               //Перменная счетчик для цыкла
    double n = 1000;
    double z = 2;
    //    double arreyXY[2][1000];

};
#endif // GPSCOOR_H
С++:
#include "gpscoor.h"
#include <QObject>
#include <QDebug>
#include "QtSql/QSqlDatabase"
#include "QSqlQuery"
#include <QtSql>
#include <QTime>
#include <QLocale>
#include <QDateTime>
#include <QtMath>
#include <math.h>

GPSCoor::GPSCoor(QObject *parent): QObject(parent)
{


}

void GPSCoor::remove_db()
{

    qDebug()<<"remuve_db() = "<<data_time_real_time<<endl;
    QSqlQuery query;                                                     //Осуществляем запрос
    // Удаление строки из базы данных будет производитсья с помощью SQL-запроса


       // Удаление производим по id записи, который передается в качестве аргумента функции
       query.prepare("DELETE FROM my_ta WHERE data_time= :data_time;");
       query.bindValue(":data_time", data_time_real_time);

       // Выполняем удаление
       if(!query.exec()){
           qDebug() << "error delete row " << "my_ta";
           qDebug() << query.lastError().text();

       } else
       {

       }

    //    query.exec("SELECT id, data_time ,x_cor, y_cor FROM my_ta ");
//    while (query.next())                                                 //Выводим значения из запроса
//    {
//        int id = query.value(0).toInt();                                 //Получаю данные из БД
//        data_time = query.value(1).toInt();                          //Получаю данные из БД
//        x_cor = query.value(2).toDouble();                               //Получаю данные из БД
//        y_cor = query.value(3).toDouble();                               //Получаю данные из БД
//        QString data_time_2 = QString::number(data_time);
//        if(data_time_real_time == data_time_2)
//        {
//            query.exec("DELETE FROM jobs WHERE data_time = ?");
//            query.addBindValue(data_time);
//            qDebug()<<"Delete for BD good"<<endl;
//        }
//        else{
//            qDebug()<<"Error Delete for BD bad"<<endl;
//        }
//    }

}

void GPSCoor::reciveTime()
{
   emit sendToTime(data_time_real_time);
}

double GPSCoor::getSomePropertyX()const                 //Для обменна даными с переменной x_cor
{
    return x_cor;
}

double GPSCoor::getSomePropertyY()const                 //Для обменна даными с переменной y_cor
{    
    return y_cor;
}

QString GPSCoor::getSomePropertyWay()const                 //Для обменна даными с переменной way
{
    return way;
}

QString GPSCoor::getSomePropertyTime()const                 //Для обменна даными с переменной time
{
    return data_time_real_time;
}

void GPSCoor::setSomePropertyX(const double &i)         //Для обменна даными с переменной x_cor
{
    x_cor = i;
    emit sendToQml(x_cor);
}

void GPSCoor::setSomePropertyY(const double &i)         //Для обменна даными с переменной y_cor
{
    y_cor = i;
    emit sendToQml(y_cor);
}

void GPSCoor::setSomePropertyWay(const QString &i)         //Для обменна даными с переменной way
{
    way = i;
    emit sendToWay(way);
}

void GPSCoor::setSomePropertyTime(const QString &i)         //Для обменна даными с переменной time
{
    data_time_real_time = i;
    emit sendToTime(data_time_real_time);
}

void GPSCoor::reciveX()                                 //Принимаю данные из QML(FirstPage)
{
    emit sendToQml(x_cor);                              //Принимаю данные в QML(FirstPage)
    emit sendToQml(y_cor);                              //Принимаю данные в QML(FirstPage)
    emit creat_db();                                    //Для создания и записи БД на стороне С++
    //emit insert_db();                                 //Для извлечения данных и бызы на стороне С++
}

void GPSCoor::pageMapX()                                //Принимаю данные из QML(Map)
{
    emit insert_db();                                   //Для извлечения данных и бызы на стороне С++
}

void GPSCoor::creat_db()                                //Создаем SQLite
{
    QTime time = QTime::currentTime();                  //Создаю обект для получения реальное время
    data_time = time.msecsSinceStartOfDay();            //Записываю время в переменную в формате миллисекунд
    qDebug()<<data_time<<endl;

    QSqlDatabase dbase = QSqlDatabase::addDatabase("QSQLITE");          //Создая обект для QSQLite
    dbase.setDatabaseName("test_2.sqlite");                             //Создаю БД
    if (!dbase.open()) {                                                //Проверяю БД
        qDebug() << "Error db";
    }else{
        qDebug()<<"Good db";
    }

    QSqlQuery a_query;
    // DDL query
    QString str = "CREATE TABLE my_ta ("               //создаю таблицу
            "id integer PRIMARY KEY NOT NULL, "
            "data_time integer,"
            "x_cor double, "
            "y_cor double"
            ");";
    bool b = a_query.exec(str);                        //Проверка на создания
    if (!b) {
        qDebug() << "error2!";
    }
    else{
        qDebug()<<"send2";
    }

    //        QString str_insrt = "INSERT INTO my_ta (data_time,x_cor,y_cor) VALUES (%1, %2, %3);";             // Записываю данные в Таблицу
    //        str = str_insrt.arg(data_time)
    //                .arg(x_cor)
    //                .arg(y_cor);
    //        b = a_query.exec(str);
    //        if (!b) {
    //            qDebug() << "error3";
    //        }else{
    //            qDebug()<<"Send3";
    //        }
}

void GPSCoor::insert_db()                               //Вывести данные из db и отправить в map.qml
{

    QSqlQuery query;                                                     //Осуществляем запрос
    query.exec("SELECT id, data_time ,x_cor, y_cor FROM my_ta ");
    while (query.next())                                                 //Выводим значения из запроса
    {

        int id = query.value(0).toInt();                                 //Получаю данные из БД
        data_time = query.value(1).toInt();                              //Получаю данные из БД
        x_cor = query.value(2).toDouble();                               //Получаю данные из БД
        y_cor = query.value(3).toDouble();                               //Получаю данные из БД

        if(id == num)
        {
            emit sendToQml(x_cor);                                      //Отправляю данные в QML(Map)
            emit sendToQml(y_cor);                                      //Отправляю данные в QML(Map)

            QTime time = QTime::fromMSecsSinceStartOfDay(data_time);
            data_time_real_time = time.toString("hh:mm:ss"); //str = "20:04:23.003"
            emit sendToTime(data_time_real_time);

            qDebug()<< "id - "<< id << endl;                            //простая проерка данных, вывожу на экран
            qDebug()<< "data_time_real_time - "<< data_time_real_time << endl;              //простая проерка данных, вывожу на экран
            qDebug()<< "y_cor - "<< x_cor << endl;
            qDebug()<< "x_cor - "<< y_cor << endl;
            //Вычисление растояния между 2 координатами гипатенуза
            CMX11 = y_cor;
            CMY11 = x_cor;
            if(id==1)
            {
//                CMX21 = y_cor;
//                CMY21 = x_cor;
            }
            else{
               emit distance();

                qDebug()<<"Way (км)  "<< Way_point << endl;
            }
            CMX21 = CMX11;
            CMY21 = CMY11;

        }
        else
        {
        }

    }
    num += 20;                       //Увеличиваю num++
}
void GPSCoor::distance(){
    Way_point = round((Way_point + sqrt(pow((CMX21 - CMX11),2) + pow((CMY21 - CMY11),2))*100)*100)/100;
    way = QString::number(Way_point);
    emit sendToWay(way);
}

что-то мне сдаётся, что здесь просто пересобрать проект нужно с удалением build каталога

Comments

Only authorized users can post comments.
Please, Log in or Sign up
МБ
April 21, 2019, 9:40 a.m.
Моисей Бушуев

Qt - Test 001. Signals and slots

  • Result:0points,
  • Rating points-10
AA
April 17, 2019, 7:40 p.m.
Anton Ablin

Qt - Test 001. Signals and slots

  • Result:73points,
  • Rating points1
E
April 17, 2019, 6:16 p.m.
Evgeny

Qt - Test 001. Signals and slots

  • Result:100points,
  • Rating points10
Last comments
April 21, 2019, 4:22 p.m.
Евгений Легоцкой

Через метод setIcon table.horizontalHeaderItem(0).setIcon("qrc://path/to/icon.png")
April 21, 2019, 3:48 p.m.
Евгений Легоцкой

Добрый день! Спасибо за комментарий. Там действительно лучше будет сделать с инициализацией по умолчанию.
U
April 18, 2019, 3:37 p.m.
Unreal_man

А как иконку в хедер задать?
u
April 18, 2019, 2:15 a.m.
uaa

доброго времени,большое спасибо за пример для начинающего)при адаптации к своему проекту столкнулся с таким ньансом:в vepolyline.h в 47 строке нужна инициализация по умолчанию: int m_pointF...
E
April 11, 2019, 12:49 p.m.
Evgeny

Спасибо за ответ) У меня компоновщик на нее ругался просто. Оказалось, просто забыл Q_OBJECT в начале класса указать.
Now discuss on the forum
April 21, 2019, 4:16 p.m.
Евгений Легоцкой

Приветствую Нужно сохранять где-то выбранное значение, а потом восстанавливать его. Или использовать QSettings или добавить метод open(), в который передавать начальные значения для того...
R
April 19, 2019, 9:55 a.m.
RED_Spider

мені важко це зараз навіть перевірити, тому що знайшов коміт, це ще було в 2016 році, і цей код не буде працювати коректно зараз, єдине скажу що це були QThread
i
April 17, 2019, 3:03 p.m.
ilya.guzikov

BlinCT, на стороне ++ это делать необходимо так как в qml при использовании функции append происходит перерисовка всех точек лини(как я понимаю) и из-за этого при использовании больших массиво...
April 10, 2019, 11:20 a.m.
Алексей Внуков

может тоже кому надо будет - QML не принимает QVector<QVector<int>> , при попытке вывести полученый вектор QML показывает что это QVariant(QVector<QVector<int> ...
Join us in social networks

For registered users on the site there is a minimum amount of advertising