Thank you for all the help anda_skoa,
Model seems to be working good now I will posted updated code
I'm now wanting to add some functionality to my tableView, Like to be able to search by date and userName... I want to pass text values back to my c++ function a would like to use the signal and slot mechanism to perform this action. However I get lost with what Object I need to pass the QObject::connect() method, for it to work.
I created two signals and two slots one for the date text field in qml and the other is for the userName text field in qml.
in C++ I created to slots to receive the qml signals and to out put the text data passed to the console using a debug() method.
I'm little confused on where to place the QObject::connect method in my project... main.cpp or sqliteModel.cpp in the constructor ?
I am unsure what objects to pass the connect() method for the signal to receive the slot ?
I would also Like to create a table in the database for each separate day for user event logging and delete old tables after 30 days
here is my code: (had to remove functions for model in cpp file to get it to fit)
=========== main.qml===============
import QtQuick 2.5
import QtQuick.Layouts 1.1
import QtQuick.Controls 1.3
import QtQuick.Window 2.2
import QtQuick.Dialogs 1.2
import QtQuick.Layouts 1.1
import QtQuick.Controls 1.4
Window {
signal submitDateText(string text)
signal submitUserNameText(string text)
visible: true
width: 760
height: 450
title: "User Event Log"
TableView {
width: 750;
height: 350;
anchors.centerIn: parent;
horizontalScrollBarPolicy: 0
frameVisible: true
model: sqliteModel
TableViewColumn {
role: "id"
title: "id"
width: 100
}
TableViewColumn {
role: "userName"
title: "User Name"
width: 200
}
TableViewColumn {
role: "eventMessage"
title: "Event Message"
width: 200
}
TableViewColumn {
role: "dateTime"
title: "Date Time"
width: 200
}
}
RowLayout {
id: row1
x: 201
y: 403
anchors.horizontalCenter: parent.horizontalCenter;
anchors.bottom: parent.bottom
width: 750
height: 47;
clip: false
opacity: 0.9
Button {
id: load_btn
text: qsTr("Load")
MouseArea{
anchors.fill: parent
onClicked: {
sqliteModel.dbConnect();
sqliteModel.sqlSelect();
}
}
}
Label {
id: userNameLabel
text: qsTr("User Name")
}
TextField {
id: userNameTextField
placeholderText: qsTr("User Name")
}
Label {
id: dateLabel
width: 39
height: 17
text: qsTr("Date")
}
TextField {
id: dateTextField
width: 125
height: 25
placeholderText: qsTr("mm//dd/yyyy")
}
Button {
id: searchBtn
text: qsTr("Search")
MouseArea{
anchors.fill: parent
onClicked: {
// emit the submitTextField signal
submitDateText(dateTextField.text);
submitUserNameText(userNameTextField.text);
}
}
}
Button {
id: exit_btn
text: qsTr("Exit")
MouseArea{
anchors.fill: parent
onClicked: close();
}
}
}
}
import QtQuick 2.5
import QtQuick.Layouts 1.1
import QtQuick.Controls 1.3
import QtQuick.Window 2.2
import QtQuick.Dialogs 1.2
import QtQuick.Layouts 1.1
import QtQuick.Controls 1.4
Window {
signal submitDateText(string text)
signal submitUserNameText(string text)
visible: true
width: 760
height: 450
title: "User Event Log"
TableView {
width: 750;
height: 350;
anchors.centerIn: parent;
horizontalScrollBarPolicy: 0
frameVisible: true
model: sqliteModel
TableViewColumn {
role: "id"
title: "id"
width: 100
}
TableViewColumn {
role: "userName"
title: "User Name"
width: 200
}
TableViewColumn {
role: "eventMessage"
title: "Event Message"
width: 200
}
TableViewColumn {
role: "dateTime"
title: "Date Time"
width: 200
}
}
RowLayout {
id: row1
x: 201
y: 403
anchors.horizontalCenter: parent.horizontalCenter;
anchors.bottom: parent.bottom
width: 750
height: 47;
clip: false
opacity: 0.9
Button {
id: load_btn
text: qsTr("Load")
MouseArea{
anchors.fill: parent
onClicked: {
sqliteModel.dbConnect();
sqliteModel.sqlSelect();
}
}
}
Label {
id: userNameLabel
text: qsTr("User Name")
}
TextField {
id: userNameTextField
placeholderText: qsTr("User Name")
}
Label {
id: dateLabel
width: 39
height: 17
text: qsTr("Date")
}
TextField {
id: dateTextField
width: 125
height: 25
placeholderText: qsTr("mm//dd/yyyy")
}
Button {
id: searchBtn
text: qsTr("Search")
MouseArea{
anchors.fill: parent
onClicked: {
// emit the submitTextField signal
submitDateText(dateTextField.text);
submitUserNameText(userNameTextField.text);
}
}
}
Button {
id: exit_btn
text: qsTr("Exit")
MouseArea{
anchors.fill: parent
onClicked: close();
}
}
}
}
To copy to clipboard, switch view to plain text mode
=========== main.cpp===============
#include <QGuiApplication>
#include <QQmlApplicationEngine>
#include <QSqlDatabase>
#include "sqlitemodel.h"
#include <QUrl>
int main(int argc, char *argv[])
{
QGuiApplication app(argc, argv);
sqliteModel *model = new sqliteModel;
QQmlApplicationEngine engine;
QQmlContext *contxt = engine.rootContext();
contxt->setContextProperty("sqliteModel", model);
engine.
load(QUrl("qrc:/main.qml"));
return app.exec();
}
#include <QGuiApplication>
#include <QQmlApplicationEngine>
#include <QSqlDatabase>
#include "sqlitemodel.h"
#include <QUrl>
int main(int argc, char *argv[])
{
QGuiApplication app(argc, argv);
sqliteModel *model = new sqliteModel;
QQmlApplicationEngine engine;
QQmlContext *contxt = engine.rootContext();
contxt->setContextProperty("sqliteModel", model);
engine.load(QUrl("qrc:/main.qml"));
return app.exec();
}
To copy to clipboard, switch view to plain text mode
=========== sqliteModel.cpp==========
#include "sqlitemodel.h"
{
// connect our QML signal to our C++ slot
QObject::connect(/*QMLObject(?)*/,
SIGNAL(submitDateText
(QString)),
this,
SLOT(searchDateText
(QString)));
}
sqliteModel::~sqliteModel()
{
}
void sqliteModel::createDailyTable()
{
dbConnect();
int addOne;
createTableQry.prepare("CREATE TABLE userlogevents1 AS SELECT * FROM userlogevents WHERE 0");
createTableQry.exec();
m_selectDataBase.close();
}
void sqliteModel::deleteDailyTable()
{
dbConnect();
//---Selects all tables older than 30 days in database | Gets date created---//
selectTables.prepare("SELECT usereventlog, create_date FROM sys.tables WHERE DATEDIFF(day, create_date, getdate()) > 30");
selectTables.exec();
selectTableResult = selectTables.value(0).toString();
selectTableResult.append(selectTables.value(1).toString());
selectTableResult.append(selectTables.value(2).toString());
qDebug() << selectTableResult;
//--- If the table is older than 30 days drop it---//
deleteTableQry.prepare("DROP TABLE userlogevetns");
deleteTableQry.exec();
m_selectDataBase.close();
}
void sqliteModel
::searchDateFcn(QString dateText
) {
dbConnect();
searchDateQry.prepare("SELECT id, userName, eventMessage, dateTime FROM usereventlog WHERE userName = "+dateText);
searchDateQry.exec();
m_selectDataBase.close();
}
void sqliteModel
::searchUserNameFcn(QString userNameText
) {
dbConnect();
searchDateQry.prepare("SELECT id, userName, eventMessage, dateTime FROM usereventlog WHERE userName = "+ userNameText);
searchDateQry.exec();
m_selectDataBase.close();
}
void sqliteModel
::searchDateText(const QString &dateText
) {
qDebug() << "c++: sqliteModel::searchDateText:" << dateText;
}
void sqliteModel
::searchUserNameText(const QString &userNameText
) {
qDebug() << "c++: sqliteModel::searchUserNameText:" << userNameText;
}
#include "sqlitemodel.h"
sqliteModel::sqliteModel(QObject *parent):QAbstractListModel(parent)
{
// connect our QML signal to our C++ slot
QObject::connect(/*QMLObject(?)*/, SIGNAL(submitDateText(QString)), this, SLOT(searchDateText(QString)));
}
sqliteModel::~sqliteModel()
{
}
void sqliteModel::createDailyTable()
{
dbConnect();
int addOne;
QSqlQuery createTableQry(m_selectDataBase);
createTableQry.prepare("CREATE TABLE userlogevents1 AS SELECT * FROM userlogevents WHERE 0");
createTableQry.exec();
m_selectDataBase.close();
}
void sqliteModel::deleteDailyTable()
{
dbConnect();
QSqlQuery selectTables(m_selectDataBase);
//---Selects all tables older than 30 days in database | Gets date created---//
selectTables.prepare("SELECT usereventlog, create_date FROM sys.tables WHERE DATEDIFF(day, create_date, getdate()) > 30");
selectTables.exec();
QString selectTableResult;
selectTableResult = selectTables.value(0).toString();
selectTableResult.append(selectTables.value(1).toString());
selectTableResult.append(selectTables.value(2).toString());
qDebug() << selectTableResult;
//--- If the table is older than 30 days drop it---//
QSqlQuery deleteTableQry(m_selectDataBase);
deleteTableQry.prepare("DROP TABLE userlogevetns");
deleteTableQry.exec();
m_selectDataBase.close();
}
void sqliteModel::searchDateFcn(QString dateText)
{
dbConnect();
QSqlQuery searchDateQry(m_selectDataBase);
searchDateQry.prepare("SELECT id, userName, eventMessage, dateTime FROM usereventlog WHERE userName = "+dateText);
searchDateQry.exec();
m_selectDataBase.close();
}
void sqliteModel::searchUserNameFcn(QString userNameText)
{
dbConnect();
QSqlQuery searchDateQry(m_selectDataBase);
searchDateQry.prepare("SELECT id, userName, eventMessage, dateTime FROM usereventlog WHERE userName = "+ userNameText);
searchDateQry.exec();
m_selectDataBase.close();
}
void sqliteModel::searchDateText(const QString &dateText)
{
qDebug() << "c++: sqliteModel::searchDateText:" << dateText;
}
void sqliteModel::searchUserNameText(const QString &userNameText)
{
qDebug() << "c++: sqliteModel::searchUserNameText:" << userNameText;
}
To copy to clipboard, switch view to plain text mode
=========== sqliteModel.h===============
#ifndef SQLITEMODEL_H
#define SQLITEMODEL_H
#include <assert.h>
#include <list>
#include <QList>
#include <QColor>
#include <QObject>
#include <QDebug>
#include <QString>
#include <QFileInfo>
#include <QDateTime>
#include <QQmlError>
#include <QQmlApplicationEngine>
#include <QQmlEngine>
#include <QQmlContext>
#include <QtSql/QSqlDatabase>
#include <QtSql/QSqlQuery>
#include <QtSql/QSqlError>
#include <QtSql/QSqlRecord>
#include <QModelIndex>
#include <QAbstractListModel>
struct userEventLogMsg{
};
{
Q_OBJECT
public:
explicit sqliteModel
(QObject *parent
= 0);
~sqliteModel();
enum userEventRoles {idRole= Qt::UserRole + 220, nameRole, msgRole, dateRole};
QHash<int, QByteArray> roleNames() const;
Q_INVOKABLE void addEvent(const userEventLogMsg &msg);
Q_INVOKABLE void dbConnect();
Q_INVOKABLE void sqlSelect();
void createDailyTable();
void deleteDailyTable();
void searchDateFcn
(QString userDateText
);
void searchUserNameFcn
(QString userNameText
);
public slots:
void searchDateText
(const QString &dateIn
);
void searchUserNameText
(const QString &userNameIn
);
private:
QList<userEventLogMsg> m_msgList;
};
#ifndef SQLITEMODEL_H
#define SQLITEMODEL_H
#include <assert.h>
#include <list>
#include <QList>
#include <QColor>
#include <QObject>
#include <QDebug>
#include <QString>
#include <QFileInfo>
#include <QDateTime>
#include <QQmlError>
#include <QQmlApplicationEngine>
#include <QQmlEngine>
#include <QQmlContext>
#include <QtSql/QSqlDatabase>
#include <QtSql/QSqlQuery>
#include <QtSql/QSqlError>
#include <QtSql/QSqlRecord>
#include <QModelIndex>
#include <QAbstractListModel>
struct userEventLogMsg{
QString id;
QString username;
QString eventmessage;
QString datetime;
};
class sqliteModel:public QAbstractListModel
{
Q_OBJECT
public:
explicit sqliteModel(QObject *parent = 0);
~sqliteModel();
enum userEventRoles {idRole= Qt::UserRole + 220, nameRole, msgRole, dateRole};
int rowCount(const QModelIndex & parent) const;
QHash<int, QByteArray> roleNames() const;
QVariant data(const QModelIndex &index, int role=Qt::DisplayRole) const;
Q_INVOKABLE void addEvent(const userEventLogMsg &msg);
Q_INVOKABLE void dbConnect();
Q_INVOKABLE void sqlSelect();
void createDailyTable();
void deleteDailyTable();
void searchDateFcn(QString userDateText);
void searchUserNameFcn(QString userNameText);
public slots:
void searchDateText(const QString &dateIn);
void searchUserNameText(const QString &userNameIn);
private:
QList<userEventLogMsg> m_msgList;
QSqlDatabase m_selectDataBase;
QSqlQuery m_selectQuery;
};
To copy to clipboard, switch view to plain text mode
I was able to pass the text form qml to my cpp slot by expose Qt slot to QML element. By using the context property I set for my model to be exposed to QML.
now my searchDateText fcn and searchUserName fcn can be called in qml by:
Button {
id: searchBtn
text: qsTr("Search")
MouseArea{
anchors.fill: parent
onClicked: {
sqliteModel.searchDateText(dateTextField.text);
sqliteModel.searchUserNameText(userNameTextField.text);
}
}
}
Button {
id: searchBtn
text: qsTr("Search")
MouseArea{
anchors.fill: parent
onClicked: {
sqliteModel.searchDateText(dateTextField.text);
sqliteModel.searchUserNameText(userNameTextField.text);
}
}
}
To copy to clipboard, switch view to plain text mode
(?) I did the same for my dbConnect and sqlSelect fcns however I have to include Q_INVOKABLE when intializing them in the header file or for some reason or I cant call them in QML with out the Q_INVOKABLE keyword but my searchDateText & searchUserNameText fucntions do??? -> error: Property 'dbConnect' of object sqliteModel() is not a function
I would like to pass the QML text using a QML signal to a CPP slot using the QObject::connect() mainly for learning purposes... The objects that I need to pass the connect() method make more sense now, I need to pass a QML object for the qml signal() and pass a class object (sqliteModel) for the slot(), if I use the connect() method in my cpp class (in the constructor) I can use keyword "this" for the CPP object for the connect method?
Bookmarks