Results 1 to 20 of 61

Thread: using an isntance of QSqlDatabase for connection defiinition

Hybrid View

Previous Post Previous Post   Next Post Next Post
  1. #1
    Join Date
    Jun 2016
    Posts
    99
    Thanks
    18
    Thanked 1 Time in 1 Post
    Qt products
    Qt5
    Platforms
    Unix/X11

    Default Re: using an isntance of QSqlDatabase for connection defiinition

    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===============
    Qt Code:
    1. import QtQuick 2.5
    2. import QtQuick.Layouts 1.1
    3. import QtQuick.Controls 1.3
    4. import QtQuick.Window 2.2
    5. import QtQuick.Dialogs 1.2
    6. import QtQuick.Layouts 1.1
    7. import QtQuick.Controls 1.4
    8.  
    9. Window {
    10. signal submitDateText(string text)
    11. signal submitUserNameText(string text)
    12. visible: true
    13. width: 760
    14. height: 450
    15. title: "User Event Log"
    16. TableView {
    17. width: 750;
    18. height: 350;
    19. anchors.centerIn: parent;
    20. horizontalScrollBarPolicy: 0
    21. frameVisible: true
    22. model: sqliteModel
    23. TableViewColumn {
    24. role: "id"
    25. title: "id"
    26. width: 100
    27. }
    28. TableViewColumn {
    29. role: "userName"
    30. title: "User Name"
    31. width: 200
    32. }
    33. TableViewColumn {
    34. role: "eventMessage"
    35. title: "Event Message"
    36. width: 200
    37. }
    38. TableViewColumn {
    39. role: "dateTime"
    40. title: "Date Time"
    41. width: 200
    42. }
    43. }
    44. RowLayout {
    45. id: row1
    46. x: 201
    47. y: 403
    48. anchors.horizontalCenter: parent.horizontalCenter;
    49. anchors.bottom: parent.bottom
    50. width: 750
    51. height: 47;
    52. clip: false
    53. opacity: 0.9
    54. Button {
    55. id: load_btn
    56. text: qsTr("Load")
    57. MouseArea{
    58. anchors.fill: parent
    59. onClicked: {
    60. sqliteModel.dbConnect();
    61. sqliteModel.sqlSelect();
    62. }
    63. }
    64. }
    65. Label {
    66. id: userNameLabel
    67. text: qsTr("User Name")
    68. }
    69. TextField {
    70. id: userNameTextField
    71. placeholderText: qsTr("User Name")
    72. }
    73. Label {
    74. id: dateLabel
    75. width: 39
    76. height: 17
    77. text: qsTr("Date")
    78. }
    79. TextField {
    80. id: dateTextField
    81. width: 125
    82. height: 25
    83. placeholderText: qsTr("mm//dd/yyyy")
    84. }
    85. Button {
    86. id: searchBtn
    87. text: qsTr("Search")
    88. MouseArea{
    89. anchors.fill: parent
    90. onClicked: {
    91. // emit the submitTextField signal
    92. submitDateText(dateTextField.text);
    93. submitUserNameText(userNameTextField.text);
    94. }
    95. }
    96. }
    97. Button {
    98. id: exit_btn
    99. text: qsTr("Exit")
    100. MouseArea{
    101. anchors.fill: parent
    102. onClicked: close();
    103. }
    104. }
    105. }
    106. }
    To copy to clipboard, switch view to plain text mode 

    =========== main.cpp===============
    Qt Code:
    1. #include <QGuiApplication>
    2. #include <QQmlApplicationEngine>
    3. #include <QSqlDatabase>
    4. #include "sqlitemodel.h"
    5. #include <QUrl>
    6.  
    7. int main(int argc, char *argv[])
    8. {
    9. QGuiApplication app(argc, argv);
    10. sqliteModel *model = new sqliteModel;
    11. QQmlApplicationEngine engine;
    12. QQmlContext *contxt = engine.rootContext();
    13. contxt->setContextProperty("sqliteModel", model);
    14. engine.load(QUrl("qrc:/main.qml"));
    15. return app.exec();
    16. }
    To copy to clipboard, switch view to plain text mode 

    =========== sqliteModel.cpp==========
    Qt Code:
    1. #include "sqlitemodel.h"
    2.  
    3. sqliteModel::sqliteModel(QObject *parent):QAbstractListModel(parent)
    4. {
    5. // connect our QML signal to our C++ slot
    6. QObject::connect(/*QMLObject(?)*/, SIGNAL(submitDateText(QString)), this, SLOT(searchDateText(QString)));
    7. }
    8.  
    9. sqliteModel::~sqliteModel()
    10. {
    11. }
    12.  
    13. void sqliteModel::createDailyTable()
    14. {
    15. dbConnect();
    16. int addOne;
    17. QSqlQuery createTableQry(m_selectDataBase);
    18. createTableQry.prepare("CREATE TABLE userlogevents1 AS SELECT * FROM userlogevents WHERE 0");
    19. createTableQry.exec();
    20. m_selectDataBase.close();
    21. }
    22.  
    23. void sqliteModel::deleteDailyTable()
    24. {
    25. dbConnect();
    26. QSqlQuery selectTables(m_selectDataBase);
    27. //---Selects all tables older than 30 days in database | Gets date created---//
    28. selectTables.prepare("SELECT usereventlog, create_date FROM sys.tables WHERE DATEDIFF(day, create_date, getdate()) > 30");
    29. selectTables.exec();
    30. QString selectTableResult;
    31. selectTableResult = selectTables.value(0).toString();
    32. selectTableResult.append(selectTables.value(1).toString());
    33. selectTableResult.append(selectTables.value(2).toString());
    34. qDebug() << selectTableResult;
    35.  
    36. //--- If the table is older than 30 days drop it---//
    37. QSqlQuery deleteTableQry(m_selectDataBase);
    38. deleteTableQry.prepare("DROP TABLE userlogevetns");
    39. deleteTableQry.exec();
    40. m_selectDataBase.close();
    41. }
    42.  
    43. void sqliteModel::searchDateFcn(QString dateText)
    44. {
    45. dbConnect();
    46. QSqlQuery searchDateQry(m_selectDataBase);
    47. searchDateQry.prepare("SELECT id, userName, eventMessage, dateTime FROM usereventlog WHERE userName = "+dateText);
    48. searchDateQry.exec();
    49. m_selectDataBase.close();
    50. }
    51.  
    52. void sqliteModel::searchUserNameFcn(QString userNameText)
    53. {
    54. dbConnect();
    55. QSqlQuery searchDateQry(m_selectDataBase);
    56. searchDateQry.prepare("SELECT id, userName, eventMessage, dateTime FROM usereventlog WHERE userName = "+ userNameText);
    57. searchDateQry.exec();
    58. m_selectDataBase.close();
    59. }
    60.  
    61. void sqliteModel::searchDateText(const QString &dateText)
    62. {
    63. qDebug() << "c++: sqliteModel::searchDateText:" << dateText;
    64. }
    65.  
    66. void sqliteModel::searchUserNameText(const QString &userNameText)
    67. {
    68. qDebug() << "c++: sqliteModel::searchUserNameText:" << userNameText;
    69. }
    To copy to clipboard, switch view to plain text mode 

    =========== sqliteModel.h===============
    Qt Code:
    1. #ifndef SQLITEMODEL_H
    2. #define SQLITEMODEL_H
    3.  
    4. #include <assert.h>
    5. #include <list>
    6. #include <QList>
    7. #include <QColor>
    8. #include <QObject>
    9. #include <QDebug>
    10. #include <QString>
    11. #include <QFileInfo>
    12. #include <QDateTime>
    13. #include <QQmlError>
    14. #include <QQmlApplicationEngine>
    15. #include <QQmlEngine>
    16. #include <QQmlContext>
    17. #include <QtSql/QSqlDatabase>
    18. #include <QtSql/QSqlQuery>
    19. #include <QtSql/QSqlError>
    20. #include <QtSql/QSqlRecord>
    21. #include <QModelIndex>
    22. #include <QAbstractListModel>
    23.  
    24. struct userEventLogMsg{
    25. QString id;
    26. QString username;
    27. QString eventmessage;
    28. QString datetime;
    29. };
    30.  
    31. class sqliteModel:public QAbstractListModel
    32. {
    33. Q_OBJECT
    34. public:
    35. explicit sqliteModel(QObject *parent = 0);
    36. ~sqliteModel();
    37. enum userEventRoles {idRole= Qt::UserRole + 220, nameRole, msgRole, dateRole};
    38. int rowCount(const QModelIndex & parent) const;
    39. QHash<int, QByteArray> roleNames() const;
    40. QVariant data(const QModelIndex &index, int role=Qt::DisplayRole) const;
    41. Q_INVOKABLE void addEvent(const userEventLogMsg &msg);
    42. Q_INVOKABLE void dbConnect();
    43. Q_INVOKABLE void sqlSelect();
    44. void createDailyTable();
    45. void deleteDailyTable();
    46. void searchDateFcn(QString userDateText);
    47. void searchUserNameFcn(QString userNameText);
    48. public slots:
    49. void searchDateText(const QString &dateIn);
    50. void searchUserNameText(const QString &userNameIn);
    51. private:
    52. QList<userEventLogMsg> m_msgList;
    53. QSqlDatabase m_selectDataBase;
    54. QSqlQuery m_selectQuery;
    55. };
    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:
    Qt Code:
    1. Button {
    2. id: searchBtn
    3. text: qsTr("Search")
    4. MouseArea{
    5. anchors.fill: parent
    6. onClicked: {
    7. sqliteModel.searchDateText(dateTextField.text);
    8. sqliteModel.searchUserNameText(userNameTextField.text);
    9. }
    10. }
    11. }
    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?
    Last edited by jfinn88; 26th August 2016 at 23:26.

  2. #2
    Join Date
    Jan 2006
    Location
    Graz, Austria
    Posts
    8,416
    Thanks
    37
    Thanked 1,544 Times in 1,494 Posts
    Qt products
    Qt3 Qt4 Qt5
    Platforms
    Unix/X11 Windows

    Default Re: using an isntance of QSqlDatabase for connection defiinition

    Quote Originally Posted by jfinn88 View Post
    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 ?
    You just call the slots directly.
    Slots, like Q_INVOKABLE methods, can be called from QML.

    Your QML code suggests that you want to pass both date and user name when clicking search, so a single slot with two arguments will do.

    Quote Originally Posted by jfinn88 View Post
    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)
    I guess you have two options:
    - use an additional table that maps from a date to a table name for that date
    - encode the date in the table name

    Quote Originally Posted by jfinn88 View Post
    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.
    Yes, exactly, though you probably want to use a single method if both inputs are to be used in the search.

    Quote Originally Posted by jfinn88 View Post
    (?) 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
    They have to be slots or Q_INVOKABLE.

    From the QML side's point of view there is actually no difference.
    It is customary though to use Q_INVOKABLE when methods return something, as slots usually don't do that.

    In your case all methods you have so far could be slots.

    Quote Originally Posted by jfinn88 View Post
    I would like to pass the QML text using a QML signal to a CPP slot using the QObject::connect() mainly for learning purposes...
    I would advise against that, you would put effort into learning something that you then don't want to use.
    I.e. you don't want your C++ code to be dependent on specific QML objects or their specific signals.

    Quote Originally Posted by jfinn88 View Post
    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()
    Yes, but you really don't want to do that.

    Quote Originally Posted by jfinn88 View Post
    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?
    Theoretically yes, but the QML scene has not been loaded yet when the model's constructor runs, so the connect would have to happen from outside after both model and QML objects exist.

    Cheers,
    _

Similar Threads

  1. Replies: 16
    Last Post: 4th September 2013, 00:49
  2. How to set x509 on a QSqlDatabase Connection?
    By m3rlin in forum Qt Programming
    Replies: 24
    Last Post: 21st February 2012, 04:04
  3. Windows OCI QSqlDatabase connection
    By hollyberry in forum Newbie
    Replies: 10
    Last Post: 13th February 2012, 22:13
  4. QSqlDatabase Connection Close on Destruction
    By Sanuden in forum Qt Programming
    Replies: 1
    Last Post: 1st September 2011, 15:32
  5. QSqlDatabase connection timeout?
    By joseprl89 in forum Qt Programming
    Replies: 6
    Last Post: 27th March 2011, 01:43

Tags for this Thread

Bookmarks

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •  
Digia, Qt and their respective logos are trademarks of Digia Plc in Finland and/or other countries worldwide.