Page 1 of 4 123 ... LastLast
Results 1 to 20 of 61

Thread: using an isntance of QSqlDatabase for connection defiinition

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

    Default using an isntance of QSqlDatabase for connection defiinition

    I have a Sqlite database I need to connect to...

    Instead of running the connection code every-time my method is called I would like to create an instance of the QSqlDatabase class

    I'm new to QT and still learning C++

    my understanding the code will run more efficiently and will "clean up" the code as well and make it so only create a connection once unless needed

    if you can explain the how the instance of the class will allow me to do this that would be awesome

    ----------old way-----------
    Qt Code:
    1. void myClass::insertLogMessage(QString msg)
    2. {
    3. //---Contects to a database | Uses QSQLITE driver---//
    4. QSqlDatabase userEventDB = QSqlDatabase::addDatabase("QSQLITE");
    5. //---Sepcifies database path---//
    6. userEventDB.setDatabaseName("/home/amet/git/rnd/userLog.db");
    7. //---Checks if database is open---//
    8. if (userEventDB.open()) {
    9. qDebug() << "Connected to userEventLog database";
    10. }
    11. else {
    12. qDebug() << "Error: no connection was found!";
    13. }
    14. //---Opens database---//
    15. userEventDB.open();
    16.  
    17. qDebug() << "insert Log Message called";
    18. QSqlQuery query;
    19. query.prepare("INSERT INTO userlogevents (firstName, lastName, userName, eventMessage, dateTime) VALUES('John', 'Doe', 'JohnnyD', '"+msg+"', datetime(current_timestamp))");
    20. //---Executes Query Statement---//
    21. query.exec();
    22. }
    To copy to clipboard, switch view to plain text mode 



    ------using instance (QSqlDatabase) variable-----------
    Qt Code:
    1. void myClass::insertLogMessage(QString msg)
    2. {
    3. m_insertDataBase = QSqlDatabase::addDatabase("QSQLITE", "conn1");
    4. m_insertDataBase = QSqlDatabase::database("conn1");
    5. m_insertDataBase.setDatabaseName("/home/amet/userLog.db");
    6. m_insertDataBase.open();
    7.  
    8. if(m_insertDataBase.isOpen()){
    9.  
    10. qDebug() <<"connected to DB" ;
    11. }
    12. else{
    13. qDebug() <<"error in opening DB";
    14. m_insertDataBase.open();
    15. }
    16.  
    17. qDebug() << "insert Log Message called";
    18. QSqlQuery insertQuery("INSERT INTO userlogevents (firstName, lastName, userName, eventMessage, dateTime) VALUES('John', 'Doe', 'JohnnyD', '"+msg+"', datetime(current_timestamp))", conn1);
    19. insertQuery.exec();
    20. m_insertDataBase.close();
    21. }
    To copy to clipboard, switch view to plain text mode 


    --------Header file with instance of QSqlDatabase object---------
    Qt Code:
    1. private:
    2. QSqlDatabase m_insertDataBase;
    3. };
    To copy to clipboard, switch view to plain text mode 

    I'm running into issues trying to implement an instance of the QSqlDatabase class (to connect to database just once) When I call my query with my database named connection ("conn1") I get 'conn1' was not declared in this scope I need to create an instance of this class (QSqlDatabase) to connect/open database once...? can any one help me get a better understanding of instances and creating a connection to a database with an instance of QSqlDatabase class so you only have to connect to it once or if you need to connect to it agian you just use the instance variable?
    Last edited by jfinn88; 23rd August 2016 at 23:14.

  2. #2
    Join Date
    Mar 2008
    Location
    Kraków, Poland
    Posts
    1,536
    Thanked 284 Times in 279 Posts
    Qt products
    Qt4
    Platforms
    Unix/X11 Windows

    Default Re: using an isntance of QSqlDatabase for connection defiinition

    conn1 is the name of db connection not C++ variable. Variable name is m_insertDataBase - C++ ABC.
    And line 4
    Qt Code:
    1. m_insertDataBase = QSqlDatabase::database("conn1");
    To copy to clipboard, switch view to plain text mode 
    is unnecessary.

  3. #3
    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

    You also don't want to do the addDatabase() and setDatabaseName() calls every time, just once, when "m_insertDataBase" is not valid yet.
    See QSqlDatabase:::isValid().

    Also, as someone had already pointed out in another thread, don't concatenated an input string into a SQL Query, always use prepare() and bound values for proper escaping.

    Cheers,
    _

  4. #4
    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

    Quote Originally Posted by Lesiok View Post
    conn1 is the name of db connection not C++ variable. Variable name is m_insertDataBase - C++ ABC.
    And line 4
    Qt Code:
    1. m_insertDataBase = QSqlDatabase::database("conn1");
    To copy to clipboard, switch view to plain text mode 
    is unnecessary.
    It didn't seem to work when passing the driver and the connection name with the line of code above this one. So I tried setting the connection name again but kept getting "conn1 was not declared in this scope". I know conn1 is the db connection name I declare it in the code above and in this line and I declare the instance variable in my header file. I only used the above code seeing if setting the db connection name would work like this I realize its unnecessary, I was just trying something to get it to work. I'm not sure if I need to declare the instance variable under public or not in the header file?


    Added after 4 minutes:


    Quote Originally Posted by anda_skoa View Post
    You also don't want to do the addDatabase() and setDatabaseName() calls every time, just once, when "m_insertDataBase" is not valid yet.
    See QSqlDatabase:::isValid().

    Also, as someone had already pointed out in another thread, don't concatenated an input string into a SQL Query, always use prepare() and bound values for proper escaping.

    Cheers,
    _
    You are talking about binding my Msg variable correct? the parameter I'm using in my sql statement?

    I was using a prepare statement before but took it out to try to short my code and it only takes one parameter wasn’t sure how to tell if its using the right connection. I will go back to using the prepare statement as suggested to allow proper escaping. How do I set the conn1 connection since The prepare() fcn only takes one argument can't pass it the connection name with sql statement do I just set the connection by

    Qt Code:
    1. m_selectDataBase = QSqlDatabase::database("conn2");
    To copy to clipboard, switch view to plain text mode 

    I will look at documentation on isValid(). How do I only call those methods once when the instance is not valid? little explanation on how this works be great, you got a example?
    Last edited by jfinn88; 24th August 2016 at 17:29.

  5. #5
    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
    You are talking about binding my Msg variable correct? the parameter I'm using in my sql statement?
    Yes

    Quote Originally Posted by jfinn88 View Post
    How do I set the conn1 connection since The prepare() fcn only takes one argument can't pass it the connection name with sql statement
    You pass the QSqlDatabase handle to the QSqlQuery constructor.
    Qt Code:
    1. QSqlQuery insertQuery(m_insertDataBase);
    2. insertQuery.prepare(...);
    To copy to clipboard, switch view to plain text mode 

    Quote Originally Posted by jfinn88 View Post
    I will look at documentation on isValid(). How do I only call those methods once when the instance is not valid? little explanation on how this works be great, you got a example?
    Qt Code:
    1. if (!m_insertDataBase.isValid() {
    2. // addDatabase, setDatabaseName
    3. }
    To copy to clipboard, switch view to plain text mode 

    Cheers,
    _

  6. #6
    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

    I have two classes I need to use an instance variable of the class QSqlDatabase to set database connections. I created an instance variable of the QSqlDatabase class in both classes under private:
    --------------- Header file----------------
    Qt Code:
    1. //Data struct for user event log
    2. struct userEventLogMsg{
    3. //hold all values for a single list entry,
    4. QString id;
    5. QString username;
    6. QString eventmessage;
    7. QString datetime;
    8. };
    9.  
    10. //---Class UserEventDailyLog responsible for XMUI UserEvnetLog | Subed classed: QAbstractTableModel---//
    11. class UserEventLog : public QAbstractListModel
    12. {
    13. Q_OBJECT
    14.  
    15. public:
    16. explicit UserEventLog(QObject *parent = 0);
    17.  
    18. ~UserEventLog();
    19.  
    20. enum userEventRoles {idRole= Qt::UserRole + 220, nameRole, msgRole, dateRole};
    21.  
    22. int rowCount(const QModelIndex & parent) const;
    23.  
    24. QHash<int, QByteArray> roleNames() const;
    25.  
    26. QVariant data(const QModelIndex &index, int role=Qt::DisplayRole) const;
    27.  
    28. Q_INVOKABLE void addEvent(const userEventLogMsg &msg);
    29.  
    30. void dbConnect();
    31.  
    32. void sqlSelect();
    33.  
    34. private:
    35. QList<userEventLogMsg> m_userEventList;
    36. QSqlDatabase m_selectDataBase;
    37. };
    To copy to clipboard, switch view to plain text mode 

    Qt Code:
    1. //---------CPP file--------------//
    2. //
    3. // UserEventLogModel
    4. //
    5.  
    6. //---Constructor---//
    7. UserEventLog::UserEventLog(QObject *parent):QAbstractListModel(parent) {
    8.  
    9. }
    10. //---Destructor---//
    11. UserEventLog::~UserEventLog() {
    12.  
    13. }
    14.  
    15. int UserEventLog::rowCount(const QModelIndex &parent) const {
    16. Q_UNUSED(parent);
    17. qDebug()<< m_userEventList.count();
    18. return m_userEventList.count();
    19. }
    20.  
    21. QHash<int, QByteArray> UserEventLog::roleNames() const {
    22. QHash<int, QByteArray> roleNames;
    23. roleNames.insert(idRole, "id");
    24. roleNames.insert(nameRole, "userName");
    25. roleNames.insert(msgRole, "eventMessage");
    26. roleNames.insert(dateRole, "dateTime");
    27. qDebug()<< roleNames;
    28. return roleNames;
    29. }
    30.  
    31. QVariant UserEventLog::data(const QModelIndex &index, int role) const {
    32. if (index.row() < 0 || index.row() >= m_userEventList.count()){
    33. return QVariant();
    34. }
    35.  
    36. QVariant text;
    37.  
    38. if(role == idRole) {
    39. userEventLogMsg msg = m_userEventList.at(index.row());
    40. text = msg.id;
    41. qDebug() << text;
    42. }
    43. else if(role == nameRole) {
    44. userEventLogMsg msg = m_userEventList.at(index.row());
    45. text = msg.username;
    46. qDebug() << text;
    47. }
    48. else if(role == msgRole) {
    49. userEventLogMsg msg = m_userEventList.at(index.row());
    50. text = msg.eventmessage;
    51. qDebug() << text;
    52. }
    53. if(role == dateRole) {
    54. userEventLogMsg msg = m_userEventList.at(index.row());
    55. text = msg.datetime;
    56. qDebug() << text;
    57. }
    58. return text;
    59. }
    60.  
    61. void UserEventLog::addEvent(const userEventLogMsg &msg) {
    62.  
    63. beginInsertRows(QModelIndex(), 0, 0);
    64. m_userEventList.insert(0, msg);
    65. endInsertRows();
    66. }
    67.  
    68. void UserEventLog::dbConnect() {
    69. m_selectDataBase = QSqlDatabase::addDatabase("QSQLITE", "conn2");
    70. qDebug() << m_selectDataBase.isValid();
    71. m_selectDataBase.setDatabaseName("/home/amet/userLog.db");
    72. m_selectDataBase.open();
    73.  
    74. if(!m_selectDataBase.open()){
    75. qDebug() <<"error in opening DB";
    76. }
    77. else{
    78. qDebug() <<"connected to DB" ;
    79. }
    80. }
    81. void UserEventLog::sqlSelect() {
    82.  
    83. //m_selectDataBase = QSqlDatabase::database("conn2");
    84. qDebug() << m_selectDataBase.isValid();
    85. m_selectDataBase.open();
    86. QSqlQuery selectQuery;
    87. selectQuery.prepare("SELECT id, userName, eventMessage, dateTime FROM userlogevents");
    88. qDebug() <<selectQuery.lastError();
    89.  
    90. if(selectQuery.exec()){
    91. qDebug()<<"sql statement exicuted fine";
    92. }
    93. else{
    94. qDebug() <<"Errors accured with sql statement";
    95. qDebug() <<selectQuery.lastError();
    96. }
    97.  
    98. while (selectQuery.next()){
    99. userEventLogMsg msg;
    100. UserEventLog model;
    101. msg.id = selectQuery.value(0).toString();
    102. msg.username = selectQuery.value(1).toString();
    103. msg.eventmessage = selectQuery.value(2).toString();
    104. msg.datetime = selectQuery.value(3).toString();
    105. model.addEvent(msg);
    106. }
    107. //m_selectDataBase.close();
    108. //m_selectDataBase.removeDatabase("conn2");
    109. }
    110. //----------------------------------------------------------------//
    To copy to clipboard, switch view to plain text mode 

    my other class that need a database connection to the same database

    ---------CPP file-----------
    Qt Code:
    1. void XMUI::hdpiWindow()
    2. {
    3. mUserEventLogModel = new UserEventLog();
    4. mUserEventLogModel->dbConnect();
    5. mUserEventLogModel->sqlSelect();
    6. m_QmlEngine->rootContext()->setContextProperty("UserEventLog", mUserEventLogModel);
    7. }
    8.  
    9. void XMUI::insertLogMessage(QString msg)
    10. {
    11. m_insertDataBase = QSqlDatabase::addDatabase("QSQLITE", "conn1");
    12. m_insertDataBase.setDatabaseName("/home/amet/userLog.db");
    13. m_insertDataBase.open();
    14.  
    15. if(m_insertDataBase.isOpen()){
    16.  
    17. qDebug() <<"connected to DB" ;
    18. }
    19. else{
    20. qDebug() <<"error in opening DB";
    21. m_insertDataBase.open();
    22. }
    23.  
    24. qDebug() << "insert Log Message called";
    25. QSqlQuery insertQuery(m_insertDataBase);
    26. insertQuery.prepare("INSERT INTO userlogevents (firstName, lastName, userName, eventMessage, dateTime) VALUES('John', 'Doe', 'JohnnyD', ':eventMessage', datetime(current_timestamp))");
    27. insertQuery.bindValue(":eventMessage", msg);
    28. insertQuery.exec();
    29. //m_insertDataBase.close();
    30. //m_insertDataBase.removeDatabase("conn1");
    31. }
    To copy to clipboard, switch view to plain text mode 


    ----header file--------
    Qt Code:
    1. class XMUI : public QObject
    2. {
    3. Q_OBJECT
    4.  
    5. public:
    6. explicit XMUI(QQuickWidget* _quickWidget);
    7.  
    8. void hdpiWindow();
    9.  
    10. Q_INVOKABLE void insertLogMessage(QString msg);
    11.  
    12. private:
    13. QSqlDatabase m_insertDataBase;
    To copy to clipboard, switch view to plain text mode 


    Added after 18 minutes:


    Quote Originally Posted by anda_skoa View Post
    Yes


    You pass the QSqlDatabase handle to the QSqlQuery constructor.
    Qt Code:
    1. QSqlQuery insertQuery(m_insertDataBase);
    2. insertQuery.prepare(...);
    To copy to clipboard, switch view to plain text mode 
    I was passing the name of my connection not the instance variable, changed it to instance variable.

    Qt Code:
    1. if (!m_insertDataBase.isValid() {
    2. // addDatabase, setDatabaseName
    3. }
    To copy to clipboard, switch view to plain text mode 

    Cheers,
    _
    I moved the add and set methods inside an if condition to set them if the database is not valid. However I get confused because I need to connect to the database to begin with... If I'm only setting them when it not valid how do I initially set the connect the first time. set it in the constructor?

    Qt Code:
    1. void XMUI::insertLogMessage(QString msg)
    2. {
    3. //qDebug() << m_insertDataBase.connectionNames();
    4.  
    5. if(!m_insertDataBase.isValid()){
    6. qDebug() <<"error in opening DB";
    7. m_insertDataBase = QSqlDatabase::addDatabase("QSQLITE", "conn1");
    8. m_insertDataBase.setDatabaseName("/home/amet/userLog.db");
    9. qDebug() << m_insertDataBase.connectionNames();
    10. }
    11. else{
    12. qDebug() <<"connected to DB";
    13. m_insertDataBase.open();
    14. //qDebug() << m_insertDataBase.lastError();
    15. }
    16.  
    17. m_insertDataBase.open();
    18. QSqlQuery m_insertQuery(m_insertDataBase);
    19. m_insertQuery.prepare("INSERT INTO userlogevents (firstName, lastName, userName, eventMessage, dateTime) VALUES('John', 'Doe', 'JohnnyD', ':eventMessage', datetime(current_timestamp))");
    20. m_insertQuery.bindValue(":eventMessage", msg);
    21. m_insertQuery.exec();
    22. qDebug() << m_insertQuery.lastError();
    23. //m_insertDataBase.close();
    24. //QSqlDatabase::removeDatabase("conn1");
    25. }
    To copy to clipboard, switch view to plain text mode 
    Last edited by jfinn88; 24th August 2016 at 22:38.

  7. #7
    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

    You can call open inside the same if(), or after the whole if/else block.

    There is no point in calling open() before it is valid and there is no point in passing the instance to QSqlQuery before it is opened.

    There is also no point in using prepare if you are still just concenating strings instead of passing the msg value as via bindValue().

    You also might want to think what your while loop is doing, in particular the life time of the "model" object and which class you are in.

    Cheers,
    _

  8. #8
    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

    Quote Originally Posted by anda_skoa View Post
    There is also no point in using prepare if you are still just concenating strings instead of passing the msg value as via bindValue().
    I updated this right before you posted this. I'm using the bind value method now with the prepare method

    Quote Originally Posted by anda_skoa View Post
    There is no point in calling open() before it is valid and there is no point in passing the instance to QSqlQuery before it is opened.
    Now that you point it out that makes sense will move open() call inside if() statement, since the if statement is checking for validation would you also pass the instance to QSqlQuery inside the if() block?
    Qt Code:
    1. //---------Inserts data into database (XMUI Global Funciton)--------------//
    2. void XMUI::insertLogMessage(QString msg)
    3. {
    4. //qDebug() << m_insertDataBase.connectionNames();
    5.  
    6. if(!m_insertDataBase.isValid()){
    7. qDebug() <<"error in opening DB";
    8. m_insertDataBase = QSqlDatabase::addDatabase("QSQLITE", "conn1");
    9. m_insertDataBase.setDatabaseName("/home/amet/userLog.db");
    10. qDebug() << m_insertDataBase.connectionNames();
    11. }
    12. else{
    13. qDebug() <<"connected to DB";
    14. m_insertDataBase.open();
    15. //qDebug() << m_insertDataBase.lastError();
    16. }
    17.  
    18. m_insertDataBase.open();
    19. QSqlQuery m_insertQuery(m_insertDataBase);
    20. m_insertQuery.prepare("INSERT INTO userlogevents (firstName, lastName, userName, eventMessage, dateTime) VALUES('John', 'Doe', 'JohnnyD', :eventMessage, datetime(current_timestamp))");
    21. m_insertQuery.bindValue(":eventMessage", msg);
    22. m_insertQuery.exec();
    23. qDebug() << m_insertQuery.lastError();
    24. //m_insertDataBase.close();
    25. //QSqlDatabase::removeDatabase("conn1");
    26. }
    27. //----------------------------------------------------------------//
    To copy to clipboard, switch view to plain text mode 

    Having trouble with connection to database... app crashes. I use a default connection for a user login and close it in the destructor, once the user logins in a series of method calls to insertLogMessage() takes place It seems like it never changes connection from default to conn1...

    Tried placing some qdebug error checks:
    Qt Code:
    1. qDebug() << m_insertDataBase.lastError(); & qDebug() << m_insertQuery.lastError();
    To copy to clipboard, switch view to plain text mode 
    but I dont get any errors back: QSqlError("", "", "") I list the connection names using
    Qt Code:
    1. qDebug() << m_insertDataBase.connectionNames();
    To copy to clipboard, switch view to plain text mode 
    it shows the default connection and the conn1 connection | verified insert query pushes to database data is showing up now!

    do I need to close or remove the database?

    Now I need help fixing my function in my other class

    Qt Code:
    1. void UserEventLog::dbConnect() {
    2.  
    3. if(!m_selectDataBase.isValid()){
    4. qDebug() << "error in opening DB";
    5. m_selectDataBase = QSqlDatabase::addDatabase("QSQLITE", "conn2");
    6. m_selectDataBase.setDatabaseName("/home/amet/userLog.db");
    7. }
    8. else{
    9. qDebug() <<"connected to DB" ;
    10. }
    11. m_selectDataBase.open();
    12. }
    13. void UserEventLog::sqlSelect() {
    14.  
    15. //---Check is Database is valid---//
    16. if(!m_selectDataBase.isValid())
    17. {
    18. qDebug() << "error in opening DB";
    19. m_selectDataBase = QSqlDatabase::addDatabase("QSQLITE", "conn2");
    20. m_selectDataBase.setDatabaseName("/home/amet/userLog.db");
    21. m_selectDataBase.open();
    22. }
    23. else{
    24. qDebug()<<"connected to DB";
    25. m_selectDataBase.open();
    26. }
    27.  
    28. //---Check if database is open---//
    29. if(!m_selectDataBase.open())
    30. {
    31. qDebug() << "database was closed";
    32. m_selectDataBase.open();
    33. }
    34. else{
    35. qDebug() << "database is open";
    36. }
    37.  
    38. QSqlQuery selectQuery("SELECT id, userName, eventMessage, dateTime FROM userlogevents");
    39.  
    40. //---Check if Sql Query Ran---//
    41. if(selectQuery.exec()){
    42. qDebug()<<"sql statement exicuted fine";
    43. }
    44. else{
    45. qDebug() << "Errors accured with sql statement";
    46. qDebug() << selectQuery.lastError();
    47. }
    48.  
    49. while (selectQuery.next()){
    50. //---Instance of userEventLogMsg Class Struct---//
    51. userEventLogMsg msg;
    52. //---Instance of userEventlog Class---//
    53. UserEventLog model;
    54. //---Add query data to the msg class struct---//
    55. msg.id = selectQuery.value(0).toString();
    56. msg.username = selectQuery.value(1).toString();
    57. msg.eventmessage = selectQuery.value(2).toString();
    58. msg.datetime = selectQuery.value(3).toString();
    59. //---Use model object to access an call addEvent()---//
    60. model.addEvent(msg);
    61. }
    62. //m_selectDataBase.close();
    63. //QSqlDatabase::removeDatabase("conn2");
    64. }
    To copy to clipboard, switch view to plain text mode 
    Last edited by jfinn88; 25th August 2016 at 00:41.

  9. #9
    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
    Now that you point it out that makes sense will move open() call inside if() statement, since the if statement is checking for validation would you also pass the instance to QSqlQuery inside the if() block?
    No, I would leave the QSqlQuery outside.

    Quote Originally Posted by jfinn88 View Post
    do I need to close or remove the database?
    No, you should be able to keep more than one connection at any given time.


    Now I need help fixing my function in my other class

    Quote Originally Posted by jfinn88 View Post
    Qt Code:
    1. QSqlQuery selectQuery("SELECT id, userName, eventMessage, dateTime FROM userlogevents");
    To copy to clipboard, switch view to plain text mode 
    You likely want to use the m_selectDataBase for this query, no?

    Quote Originally Posted by jfinn88 View Post
    Qt Code:
    1. while (selectQuery.next()){
    2. //---Instance of userEventLogMsg Class Struct---//
    3. userEventLogMsg msg;
    4. //---Instance of userEventlog Class---//
    5. UserEventLog model;
    6. //---Add query data to the msg class struct---//
    7. msg.id = selectQuery.value(0).toString();
    8. msg.username = selectQuery.value(1).toString();
    9. msg.eventmessage = selectQuery.value(2).toString();
    10. msg.datetime = selectQuery.value(3).toString();
    11. //---Use model object to access an call addEvent()---//
    12. model.addEvent(msg);
    13. }
    To copy to clipboard, switch view to plain text mode 
    This doesn't look at all what I assume you want.
    This creates a new model instance in every loop iteration, adds one record and then destroys the model (when it goes out of scope).

    Cheers,
    _

  10. #10
    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

    Quote Originally Posted by anda_skoa View Post
    No, I would leave the QSqlQuery outside.
    Okay, That makes sense played with it and I declare it before the if() block.

    No, you should be able to keep more than one connection at any given time.
    Okay, so I'm fine with leaving conn1, and conn2 connected.

    You likely want to use the m_selectDataBase for this query, no?
    I can pass it with the sql statement correct ?

    Qt Code:
    1. QSqlQuery selectQuery("SELECT id, userName, eventMessage, dateTime FROM userlogevents", m_selectDataBase);
    To copy to clipboard, switch view to plain text mode 

    This doesn't look at all what I assume you want.
    This creates a new model instance in every loop iteration, adds one record and then destroys the model (when it goes out of scope).
    you are correct I do not want to create a new object every time it goes threw while loop moved object declaration above while loop. Will calling addEvent () in the while loop be fine or should it be called once after the while loop is done putting data in struct?

    I’m still little confused how the virtual functions get called... from my understanding is when the instance variable of my class is created (to pass the model to C++ by setting rootContext item) it makes a call to the constructor and when the constructor gets called the virtual functions get called (trying to clear any confuse I still have with models and virtual functions) ?
    Qt Code:
    1. //---Instance of userEventLogMsg Class Struct---//
    2. userEventLogMsg msg;
    3.  
    4. while (selectQuery.next()){
    5. //---Add query data to the userEventLogMsg class struct---//
    6. msg.id = selectQuery.value(0).toString();
    7. msg.username = selectQuery.value(1).toString();
    8. msg.eventmessage = selectQuery.value(2).toString();
    9. msg.datetime = selectQuery.value(3).toString();
    10. //---Use model object to access an call addEvent()---//
    11. addEvent(msg);
    12. }
    To copy to clipboard, switch view to plain text mode 

    Also I want to call dbConnect and selectQuery() methods from QML (button click)
    in the header file I declare the function as Q_INVOKABLE now I know I could register the QML type to make the class accessible in QML and import it in the QML to call the function but I think I would have to make the class global object? is there a simpler way to do this ?

    I have seen an example with Q_INVOKABLE and setting the context property, but I get confused on what engine object/class I need to use to set it. I don't quit understand the rootContext methodology yet and have a QML engine already defined and in use that I don't want to mess up, Im not sure if replacing what is currently on the engine stack is the right way todo it? or if using a new engine object is correct... would I need to create an instance object of a qml engine in my userEvetnLog class? (how can I tell what object this is pointing to?)

    Qt Code:
    1. mUserEventLogModel = new UserEventLog();
    2. m_QmlEngine->rootContext()->setContextProperty("UserEventLog", mUserEventLogModel);
    To copy to clipboard, switch view to plain text mode 

    In my QML I call my funtions

    Qt Code:
    1. Action {
    2. id: action_userEventLogBtn
    3. enabled:!inSequence
    4. onTriggered:{
    5. //----Code to Load User Event Database into tableView-----//
    6. input_loader.filename = ""
    7. UserEventLog.dbConnect();
    8. UserEventLog.sqlSelect();
    9. weld_view.state = "USEREVENT"
    10. onLoaded: console.log("User Event Log");
    To copy to clipboard, switch view to plain text mode 

    update: Okay I got my functions working in QML used previously defined QQmlEngine and instance of UserEventLog class that was used to make my model available to QML

    update: made a stupid mistake when calling my addEvent function and now just realized it. Was getting a segfault fixed by removing UserEventLog object and just calling addEvent since Im in the class.
    Last edited by jfinn88; 25th August 2016 at 20:37.

  11. #11
    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
    I can pass it with the sql statement correct ?
    Yes.

    Quote Originally Posted by jfinn88 View Post
    Will calling addEvent () in the while loop be fine or should it be called once after the while loop is done putting data in struct?
    In every loop iteration.
    You can basically keep your code, but instead of calling addEvent() on a different model you just call addEvent() of the current object.

    Quote Originally Posted by jfinn88 View Post
    I’m still little confused how the virtual functions get called... from my understanding is when the instance variable of my class is created (to pass the model to C++ by setting rootContext item) it makes a call to the constructor and when the constructor gets called the virtual functions get called (trying to clear any confuse I still have with models and virtual functions) ?
    When you create an object, the constructor for that class is called.

    Once the object is created, calls to virtual functions always end up in the most specific subclass.
    E.g. if you overwrite roleNames() a call to roleNames() will end up calling your implementation.

    Quote Originally Posted by jfinn88 View Post
    Also I want to call dbConnect and selectQuery() methods from QML (button click)
    For what purpose?
    I can see a use case of re-running the query on demand, but dbConnect?
    dbConnect() is really internal, no? It has to be called before database access happens, so the class itself should know when to call it.

    Quote Originally Posted by jfinn88 View Post
    in the header file I declare the function as Q_INVOKABLE now I know I could register the QML type to make the class accessible in QML and import it in the QML to call the function but I think I would have to make the class global object? is there a simpler way to do this ?
    That is unnecessary.
    Q_INVOKABLE methods and slots are already accessible as functions on an object set as a context property.
    Registration of a type is only necessary if instances of that type need to be created from QML or if it has enum definitions where the QML code should be able to use the names.

    Quote Originally Posted by jfinn88 View Post
    I have seen an example with Q_INVOKABLE and setting the context property, but I get confused on what engine object/class I need to use to set it.
    You don't have to change anything in your code.

    Cheers,
    _

  12. The following user says thank you to anda_skoa for this useful post:

    jfinn88 (26th August 2016)

  13. #12
    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; 27th August 2016 at 00:26.

  14. #13
    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,
    _

  15. #14
    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

    So I been reading an working on figuring out how to implement a sorting feature using sortProxyFilter class But I'm little confused on how it works with the model... I know its filters between the QML and the model data. I want to search by userName (separately) want to search by Date (separately) and then be able to search by userName and date... I was thinking at first I could use sql script just to select the data from the data base then display using model but not sure how that would work with re-running slq statement then refreshing model. Seems like every one uses a ProxyFilter class to filter tableView.

    I started by creating a Proxy Filter class and subclass QSortProxyFilter and start of with overriding the sortAsspectRow() method but relaized that will just filter the column and not use the search fields given, can you help me get started in the right direction for what I need? I'm not sure if I should be passing a string to compare with the filter? I need to set the filterString and use it to filter tableView (evaluate the data based on a string)

    ============= Main.cpp ===========
    Qt Code:
    1. #include <QGuiApplication>
    2. #include <QQmlApplicationEngine>
    3. #include <QSqlDatabase>
    4. #include <QAbstractTableModel>
    5. #include <QAbstractItemModel>
    6. #include "sqlitemodel.h"
    7. #include "sortproxyfilter.h"
    8. #include <QUrl>
    9.  
    10. int main(int argc, char *argv[])
    11. {
    12. QGuiApplication app(argc, argv);
    13.  
    14. sqliteModel *model = new sqliteModel;
    15.  
    16. sortProxyFilter *myProxyFilter = new sortProxyFilter;
    17. myProxyFilter->setSourceModel(model);
    18.  
    19. QQmlApplicationEngine engine;
    20. QQmlContext *contxt = engine.rootContext();
    21. contxt->setContextProperty("sqliteModel", model);
    22. contxt->setContextProperty("proxyFilter", myProxyFilter);
    23. engine.load(QUrl("qrc:/main.qml"));
    24.  
    25. //---Insert Proxy Model between model and view---//
    26. //proxy = new QSortFilterProxyModel(parent);
    27. //proxy->setSourceModel(model);
    28. //engine.setModel(proxy);
    29.  
    30. return app.exec();
    31. }
    To copy to clipboard, switch view to plain text mode 

    ===========sortProxyFilter.cpp=============
    Qt Code:
    1. #include "sortproxyfilter.h"
    2. #include "sqlitemodel.h"
    3.  
    4. sortProxyFilter::sortProxyFilter(QObject *parent):QSortFilterProxyModel(parent)
    5. {
    6.  
    7. }
    8.  
    9. sortProxyFilter::~sortProxyFilter()
    10. {
    11.  
    12. }
    13.  
    14. //Need to figure out what functions I will need (filterString(), setFilterString etc...)
    To copy to clipboard, switch view to plain text mode 

    ============sortProxyFilter.h============
    Qt Code:
    1. #ifndef SORTPROXYFILTER_H
    2. #define SORTPROXYFILTER_H
    3. #include <QSortFilterProxyModel>
    4.  
    5.  
    6. class sortProxyFilter:public QSortFilterProxyModel
    7. {
    8. public:
    9. explicit sortProxyFilter(QObject *parent = 0);
    10.  
    11. ~sortProxyFilter();
    12.  
    13. //add filter string functions
    14.  
    15. signals:
    16.  
    17. public slots:
    18.  
    19. private:
    20. };
    21. #endif // SORTPROXYFILTER_H
    To copy to clipboard, switch view to plain text mode 


    ===========slqiteModel.cpp============
    Qt Code:
    1. #include "sqlitemodel.h"
    2.  
    3. sqliteModel::sqliteModel(QObject *parent):QAbstractListModel(parent){
    4.  
    5. }
    6.  
    7. sqliteModel::~sqliteModel(){
    8.  
    9. }
    10.  
    11. int sqliteModel::rowCount(const QModelIndex &parent) const{
    12. Q_UNUSED(parent);
    13. return m_msgList.count();
    14. qDebug()<< m_msgList.count();
    15. }
    16.  
    17. QHash<int, QByteArray> sqliteModel::roleNames() const{
    18. QHash<int, QByteArray> roleNames;
    19. roleNames.insert(idRole, "id");
    20. roleNames.insert(nameRole, "userName");
    21. roleNames.insert(msgRole, "eventMessage");
    22. roleNames.insert(dateRole, "dateTime");
    23. qDebug()<< roleNames;
    24. return roleNames;
    25. }
    26.  
    27. QVariant sqliteModel::data(const QModelIndex &index, int role) const
    28. {
    29. if (index.row() < 0 || index.row() >= m_msgList.count()){
    30. return QVariant();
    31. }
    32. QVariant text;
    33. if(role == idRole){
    34. userEventLogMsg msg = m_msgList[index.row()];
    35. text = msg.id;
    36. qDebug() << text;
    37. }
    38. else if(role == nameRole){
    39. userEventLogMsg msg = m_msgList[index.row()];
    40. text = msg.username;
    41. qDebug() << text;
    42. }
    43. else if(role == msgRole){
    44. userEventLogMsg msg = m_msgList[index.row()];
    45. text = msg.eventmessage;
    46. qDebug() << text;
    47. }
    48. if(role == dateRole){
    49. userEventLogMsg msg = m_msgList[index.row()];
    50. text = msg.datetime;
    51. qDebug() << text;
    52. }
    53. return text;
    54. }
    55.  
    56. void sqliteModel::addEvent(const userEventLogMsg &msg){
    57. beginInsertRows(QModelIndex(), 0, 0);
    58. m_msgList.insert(0, msg);
    59. endInsertRows();
    60. }
    61.  
    62. void sqliteModel::dbConnect() {
    63. if(!m_selectDataBase.isValid()){
    64. qDebug() << "error in opening DB";
    65. m_selectDataBase = QSqlDatabase::addDatabase("QSQLITE", "conn2");
    66. m_selectDataBase.setDatabaseName("/home/amet/userLog.db");
    67. }
    68. else{
    69. qDebug() <<"connected to DB" ;
    70. }
    71. m_selectDataBase.open();
    72. }
    73. void sqliteModel::sqlSelect() {
    74. dbConnect();
    75. if(!m_selectDataBase.open())
    76. {
    77. qDebug() << "database was closed";
    78. m_selectDataBase.open();
    79. }
    80. else{
    81. qDebug() << "database is open";
    82. }
    83. QSqlQuery selectQuery("SELECT id, userName, eventMessage, dateTime FROM userlogevents", m_selectDataBase);
    84. if(selectQuery.exec()){
    85. qDebug()<<"sql statement exicuted fine";
    86. }
    87. else{
    88. qDebug() << "Errors accured with sql statement";
    89. qDebug() << selectQuery.lastError();
    90. }
    91. userEventLogMsg msg;
    92. while (selectQuery.next()){
    93. msg.id = selectQuery.value(0).toString();
    94. msg.username = selectQuery.value(1).toString();
    95. msg.eventmessage = selectQuery.value(2).toString();
    96. msg.datetime = selectQuery.value(3).toString();
    97. addEvent(msg);
    98. }
    99. m_selectDataBase.close();
    100. }
    101.  
    102. void sqliteModel::createDailyTable()
    103. {
    104. dbConnect();
    105. QSqlQuery createTableQry(m_selectDataBase);
    106. createTableQry.prepare("CREATE TABLE userlogevents1 AS SELECT * FROM userlogevents WHERE 0");
    107. createTableQry.exec();
    108. m_selectDataBase.close();
    109. }
    110.  
    111. void sqliteModel::deleteDailyTable()
    112. {
    113. dbConnect();
    114. QSqlQuery selectTables(m_selectDataBase);
    115. //---Selects all tables older than 30 days in database | Gets date created---//
    116. selectTables.prepare("SELECT usereventlog, create_date FROM sys.tables WHERE DATEDIFF(day, create_date, getdate()) > 30");
    117. selectTables.exec();
    118. QString selectTableResult;
    119. selectTableResult = selectTables.value(0).toString();
    120. selectTableResult.append(selectTables.value(1).toString());
    121. selectTableResult.append(selectTables.value(2).toString());
    122. qDebug() << selectTableResult;
    123. //--- If the table is older than 30 days drop it---//
    124. QSqlQuery deleteTableQry(m_selectDataBase);
    125. deleteTableQry.prepare("DROP TABLE userlogevetns");
    126. deleteTableQry.exec();
    127. m_selectDataBase.close();
    128. }
    129.  
    130. void sqliteModel::searchDateText(const QString &dateText)
    131. {
    132. qDebug() << "c++: sqliteModel::searchDateText:" << dateText;
    133. dbConnect();
    134. QSqlQuery searchDateQry(m_selectDataBase);
    135. searchDateQry.prepare("SELECT id, userName, eventMessage, dateTime FROM usereventlog WHERE dateTime = "+ dateText);
    136. searchDateQry.exec();
    137. m_selectDataBase.close();
    138. }
    139.  
    140. void sqliteModel::searchUserNameText(const QString &userNameText)
    141. {
    142. qDebug() << "c++: sqliteModel::searchUserNameText:" << userNameText;
    143. dbConnect();
    144. QSqlQuery searchDateQry(m_selectDataBase);
    145. searchDateQry.prepare("SELECT id, userName, eventMessage, dateTime FROM usereventlog WHERE userName = "+ userNameText);
    146. searchDateQry.exec();
    147. m_selectDataBase.close();
    148. }
    To copy to clipboard, switch view to plain text mode 

    ===========sqliteModel.h===========
    Qt Code:
    1. #ifndef SQLITEMODEL_H
    2. #define SQLITEMODEL_H
    3. #include <assert.h>
    4. #include <list>
    5. #include <QList>
    6. #include <QColor>
    7. #include <QObject>
    8. #include <QDebug>
    9. #include <QString>
    10. #include <QDateTime>
    11. #include <QQmlError>
    12. #include <QtSql/QSqlDatabase>
    13. #include <QtSql/QSqlQuery>
    14. #include <QtSql/QSqlError>
    15. #include <QtSql/QSqlRecord>
    16. #include <QModelIndex>
    17. #include <QAbstractListModel>
    18.  
    19. struct userEventLogMsg{
    20. QString id;
    21. QString username;
    22. QString eventmessage;
    23. QString datetime;
    24. };
    25.  
    26. class sqliteModel:public QAbstractListModel
    27. {
    28. Q_OBJECT
    29. public:
    30. explicit sqliteModel(QObject *parent = 0);
    31. ~sqliteModel();
    32. enum userEventRoles {idRole= Qt::UserRole + 220, nameRole, msgRole, dateRole};
    33. int rowCount(const QModelIndex & parent) const;
    34. QHash<int, QByteArray> roleNames() const;
    35. QVariant data(const QModelIndex &index, int role=Qt::DisplayRole) const;
    36. Q_INVOKABLE void addEvent(const userEventLogMsg &msg);
    37. Q_INVOKABLE void dbConnect();
    38. Q_INVOKABLE void sqlSelect();
    39. void createDailyTable();
    40. void deleteDailyTable();
    41. public slots:
    42. void searchDateText(const QString &dateIn);
    43. void searchUserNameText(const QString &userNameIn);
    44. private:
    45. QList<userEventLogMsg> m_msgList;
    46. QSqlDatabase m_selectDataBase;
    47. QSqlQuery m_selectQuery;
    48. };
    49. #endif // SQLITEMODEL_H
    To copy to clipboard, switch view to plain text mode 

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

  16. #15
    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

    Updated function went back to using sql statements to filter results not sure if this is a good way however it works well for the most part... If this way seems fine is there a better way to refresh my view/model?

    Qt Code:
    1. void sqliteModel::searchDateText(const QString &dateText)
    2. {
    3. qDebug() << "c++: sqliteModel::searchDateText:" << dateText;
    4.  
    5. dbConnect();
    6.  
    7. if(!m_selectDataBase.open())
    8. {
    9. qDebug() << "database was closed";
    10. m_selectDataBase.open();
    11. }
    12. else{
    13. qDebug() << "database is open";
    14. }
    15.  
    16. QSqlQuery selectQuery(m_selectDataBase);
    17. selectQuery.prepare("SELECT id, userName, eventMessage, dateTime FROM userlogevents WHERE userName = ?");
    18. selectQuery.addBindValue(dateText);
    19.  
    20.  
    21. if(selectQuery.exec()){
    22. qDebug()<<"sql statement exicuted fine";
    23. }
    24. else{
    25. qDebug() << "Errors accured with sql statement";
    26. qDebug() << selectQuery.lastError();
    27. }
    28.  
    29. userEventLogMsg msg;
    30.  
    31. while (selectQuery.next()){
    32. msg.id = selectQuery.value(0).toString();
    33. msg.username = selectQuery.value(1).toString();
    34. msg.eventmessage = selectQuery.value(2).toString();
    35. msg.datetime = selectQuery.value(3).toString();
    36. addEvent(msg);
    37. }
    38. m_selectDataBase.close();
    39. }
    40.  
    41. void sqliteModel::searchUserNameText(const QString &userNameText)
    42. {
    43. qDebug() << "c++: sqliteModel::searchUserNameText:" << userNameText;
    44.  
    45. dbConnect();
    46.  
    47. if(!m_selectDataBase.open())
    48. {
    49. qDebug() << "database was closed";
    50. m_selectDataBase.open();
    51. }
    52. else{
    53. qDebug() << "database is open";
    54. }
    55.  
    56. QSqlQuery selectQuery(m_selectDataBase);
    57. selectQuery.prepare("SELECT id, userName, eventMessage, dateTime FROM userlogevents WHERE userName = ?");
    58. selectQuery.addBindValue(userNameText);
    59.  
    60.  
    61. if(selectQuery.exec()){
    62. qDebug()<<"sql statement exicuted fine";
    63. }
    64. else{
    65. qDebug() << "Errors accured with sql statement";
    66. qDebug() << selectQuery.lastError();
    67. }
    68.  
    69. userEventLogMsg msg;
    70.  
    71. while (selectQuery.next()){
    72. msg.id = selectQuery.value(0).toString();
    73. msg.username = selectQuery.value(1).toString();
    74. msg.eventmessage = selectQuery.value(2).toString();
    75. msg.datetime = selectQuery.value(3).toString();
    76. addEvent(msg);
    77. }
    78. m_selectDataBase.close();
    79. }
    To copy to clipboard, switch view to plain text mode 

  17. #16
    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

    Both functions have a query that uses userName as the parameter, so both search for userName.

    If you are replacing a model's content, the best way is to use begin/end reset model and just do all the data changes in betwee.

    Qt Code:
    1. beginResetModel();
    2.  
    3. m_userEventList.clear(); // get rid of old content
    4.  
    5. // run query
    6.  
    7. while (... ) {
    8. userEventLogMsg msg;
    9. // fill msg
    10. m_userEventList << msg;
    11. }
    12.  
    13. endResetModel();
    To copy to clipboard, switch view to plain text mode 

    For the proxy model approach you would have to store the current filter strings, implement the filterAcceptsRow() function and use these strings and call invalidateFilter() whenever the strings change.

    Cheers,
    _

  18. The following user says thank you to anda_skoa for this useful post:

    jfinn88 (1st September 2016)

  19. #17
    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

    Quote Originally Posted by anda_skoa View Post
    Both functions have a query that uses userName as the parameter, so both search for userName.
    Yeah sorry was just copy error

    If you are replacing a model's content, the best way is to use begin/end reset model and just do all the data changes in betwee.

    Qt Code:
    1. beginResetModel();
    2.  
    3. m_userEventList.clear(); // get rid of old content
    4.  
    5. // run query
    6.  
    7. while (... ) {
    8. userEventLogMsg msg;
    9. // fill msg
    10. m_userEventList << msg;
    11. }
    12.  
    13. endResetModel();
    To copy to clipboard, switch view to plain text mode 

    For the proxy model approach you would have to store the current filter strings, implement the filterAcceptsRow() function and use these strings and call invalidateFilter() whenever the strings change.

    Cheers,
    _
    Which approach would you recommend?

    I added a comboBox to my QML to select the different tables (~30 days, one table for each day) from the database and display the table in the tableView and if the user needs to can search the table based on date user name would it be fine to pass the select item from the combo box to the select query to display the data or would it need to be refreshed like you describe above with resetModel?

    I want to display the results of a certain query in the comboBox (list of database tables) based of the selection change the model...
    Qt Code:
    1. selectTables.prepare("SELECT name, create_date FROM sqlite_master WHERE DATEDIFF(day, create_date, getdate()) > 30");
    To copy to clipboard, switch view to plain text mode 
    Last edited by jfinn88; 31st August 2016 at 17:15.

  20. #18
    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

    It depends.

    If you need to retain current item/selection, then resetting the model is out of question.

    If you want to filter as you type, then I would filter in the model itself but implement filtering manually.

    If you only need to apply the filter on a trigger, e.g. on button click, then the easiest way is to reset the model to that query and let the database do the filtering.

    Cheers,
    _

  21. The following user says thank you to anda_skoa for this useful post:

    jfinn88 (31st August 2016)

  22. #19
    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

    having issue with using a second model for display tableNames in comboBox

    Think it has to do with tableNameComboBox() method that call my addTableName()

    =====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. signal submitDatabaseTable(string text)
    13.  
    14. visible: true
    15. width: 760
    16. height: 450
    17. title: "User Event Log"
    18. RowLayout {
    19. id: comboBoxRowLayout
    20. anchors.topMargin: 25
    21. anchors.leftMargin: 25
    22. anchors.horizontalCenter: parent.horizontalCenter
    23. Label {
    24. id: comboLabel
    25. width: 150
    26. height: 25
    27. text: qsTr("Select Database/Date")
    28. verticalAlignment: Text.AlignVCenter
    29. }
    30. ComboBox {
    31. id: dataBaseComboBox
    32. width: 150
    33. height: 25
    34. model: tableNameModel
    35. textRole: "tableName"
    36. //MouseArea{
    37. //anchors.fill: parent
    38. //onClicked: {
    39. //tableNameModel.tableNameComboBox();
    40. //}
    41. //}
    42. }
    43. }
    44. TableView {
    45. width: 750;
    46. height: 350;
    47. anchors.centerIn: parent;
    48. horizontalScrollBarPolicy: 0
    49. frameVisible: true
    50. model: sqliteModel
    51. //sortIndicatorColumn : 1
    52. //sortIndicatorVisible: true
    53. TableViewColumn {
    54. role: "id"
    55. title: "id"
    56. width: 100
    57. }
    58. TableViewColumn {
    59. role: "userName"
    60. title: "User Name"
    61. width: 200
    62. }
    63. TableViewColumn {
    64. role: "eventMessage"
    65. title: "Event Message"
    66. width: 200
    67. }
    68. TableViewColumn {
    69. role: "dateTime"
    70. title: "Date Time"
    71. width: 200
    72. }
    73. }
    74. RowLayout {
    75. id: searchRowLayout
    76. x: 201
    77. y: 403
    78. anchors.horizontalCenter: parent.horizontalCenter;
    79. anchors.bottom: parent.bottom
    80. width: 750
    81. height: 47;
    82. clip: false
    83. opacity: 0.9
    84. Button {
    85. id: load_btn
    86. text: qsTr("Load")
    87. MouseArea{
    88. anchors.fill: parent
    89. onClicked: {
    90. sqliteModel.sqlSelect(tableName);
    91. }
    92. }
    93. }
    94. Label {
    95. id: userNameLabel
    96. text: qsTr("User Name")
    97. }
    98. TextField {
    99. id: userNameTextField
    100. placeholderText: qsTr("User Name")
    101. }
    102. Label {
    103. id: dateLabel
    104. width: 39
    105. height: 17
    106. text: qsTr("Date")
    107. }
    108. TextField {
    109. id: dateTextField
    110. width: 125
    111. height: 25
    112. placeholderText: qsTr("mm//dd/yyyy")
    113. }
    114. Button {
    115. id: searchBtn
    116. text: qsTr("Search")
    117. MouseArea{
    118. anchors.fill: parent
    119. onClicked: {
    120. //---emit the submitDateText & submitUserNameText signal---//
    121. //sqliteModel.searchDateText(dateTextField.text);
    122. //sqliteModel.searchUserNameText(userNameTextField.text);
    123. sqliteModel.deleteDailyTable();
    124. }
    125. }
    126. }
    127. Button {
    128. id: exit_btn
    129. text: qsTr("Exit")
    130. MouseArea{
    131. anchors.fill: parent
    132. onClicked: close();
    133. }
    134. }
    135. }
    136. }
    To copy to clipboard, switch view to plain text mode 

    ======databasetables.cpp=====
    Qt Code:
    1. #include "databasetables.h"
    2.  
    3. dataBaseTables::dataBaseTables(QObject *parent):QAbstractListModel(parent){
    4.  
    5. }
    6.  
    7. dataBaseTables::~dataBaseTables(){
    8.  
    9. }
    10.  
    11. int dataBaseTables::rowCount(const QModelIndex &parent) const{
    12. Q_UNUSED(parent);
    13. return m_tableNameList.count();
    14. qDebug()<< m_tableNameList.count();
    15. }
    16.  
    17. QHash<int, QByteArray> dataBaseTables::roleNames() const{
    18. QHash<int, QByteArray> roleNames;
    19. roleNames.insert(tableNameRole, "TableName");
    20. qDebug()<< roleNames;
    21. return roleNames;
    22. }
    23.  
    24. QVariant dataBaseTables::data(const QModelIndex &index, int role) const{
    25. if (index.row() < 0 || index.row() >= m_tableNameList.count()){
    26. return QVariant();
    27. }
    28. QVariant text;
    29. if(role == tableNameRole){
    30. tableNames tables = m_tableNameList[index.row()];
    31. text = tables.tableName;
    32. qDebug() << text;
    33. }
    34. return text;
    35. }
    36.  
    37. void dataBaseTables::addTableName(const tableNames &tables){
    38. beginInsertRows(QModelIndex(), 0, 0);
    39. m_tableNameList.insert(0, tables);
    40. endInsertRows();
    41. }
    42.  
    43. void dataBaseTables::dbConnect(){
    44.  
    45. if(!m_selectTableNames.isValid()){
    46. qDebug() << "error in opening DB";
    47. m_selectTableNames = QSqlDatabase::addDatabase("QSQLITE", "conn2");
    48. m_selectTableNames.setDatabaseName("/home/amet/userLog.db");
    49. }
    50. else{
    51. qDebug() <<"connected to DB" ;
    52. }
    53. m_selectTableNames.open();
    54. }
    55.  
    56. QString dataBaseTables::tableNameComboBox(){
    57. dbConnect();
    58. QSqlQuery selectTables(m_selectTableNames);
    59.  
    60. //---Selects all tables older than 30 days in database | Gets date created---//
    61. selectTables.prepare("SELECT name FROM sqlite_master WHERE type='table';");
    62.  
    63. if(selectTables.exec()){
    64. qDebug()<<"sql statement exicuted fine";
    65. }
    66. else{
    67. qDebug() << "Errors accured with sql statement";
    68. qDebug() << selectTables.lastError();
    69. }
    70.  
    71. tableNames tables;
    72. QString tableName;
    73. while (selectTables.next()){
    74. tables.tableName = selectTables.value(0).toString();
    75. tableName = selectTables.value(0).toString();
    76. qDebug() << "Table Results: "+tableName;
    77. addTableName(tables);
    78. }
    79. m_selectTableNames.close();
    80. return tableName;
    81. }
    To copy to clipboard, switch view to plain text mode 

    =====databasetables.h===========
    Qt Code:
    1. #ifndef DATABASETABLES_H
    2. #define DATABASETABLES_H
    3.  
    4. #include <QString>
    5. #include <QDebug>
    6. #include <QQmlContext>
    7. #include <QtSql/QSqlDatabase>
    8. #include <QtSql/QSqlQuery>
    9. #include <QtSql/QSqlError>
    10. #include <QtSql/QSqlRecord>
    11. #include <QModelIndex>
    12. #include <QSqlDatabase>
    13. #include <QAbstractListModel>
    14. #include <QAbstractItemModel>
    15.  
    16. struct tableNames{
    17. QString tableName;
    18. };
    19.  
    20. class dataBaseTables: public QAbstractListModel
    21. {
    22. Q_OBJECT
    23.  
    24. public:
    25. explicit dataBaseTables(QObject *parent = 0);
    26.  
    27. ~dataBaseTables();
    28.  
    29. enum dataTableNameRoles {tableNameRole= Qt::UserRole + 220};
    30.  
    31. int rowCount(const QModelIndex & parent) const;
    32.  
    33. QHash<int, QByteArray> roleNames() const;
    34.  
    35. QVariant data(const QModelIndex &index, int role=Qt::DisplayRole) const;
    36.  
    37. Q_INVOKABLE void addTableName(const tableNames &tables);
    38.  
    39. Q_INVOKABLE void dbConnect();
    40.  
    41. Q_INVOKABLE QString tableNameComboBox();
    42.  
    43. public slots:
    44.  
    45. private:
    46. QList<tableNames> m_tableNameList;
    47. QSqlDatabase m_selectTableNames;
    48. QSqlQuery m_tableNamesQuery;
    49. };
    50. #endif // DATABASETABLES_H
    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 <QAbstractTableModel>
    5. #include <QAbstractItemModel>
    6. #include <QUrl>
    7. #include "sqlitemodel.h"
    8. #include "sortproxyfilter.h"
    9. #include "databasetables.h"
    10.  
    11.  
    12. int main(int argc, char *argv[])
    13. {
    14. QGuiApplication app(argc, argv);
    15.  
    16. sqliteModel *model = new sqliteModel;
    17.  
    18. dataBaseTables *model2 = new dataBaseTables;
    19.  
    20. QQmlApplicationEngine engine;
    21. QQmlContext *contxt = engine.rootContext();
    22. contxt->setContextProperty("sqliteModel", model);
    23. contxt->setContextProperty("tableNameModel", model2);
    24. engine.load(QUrl("qrc:/main.qml"));
    25.  
    26. return app.exec();
    27. }
    To copy to clipboard, switch view to plain text mode 
    Last edited by jfinn88; 31st August 2016 at 21:05.

  23. #20
    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

    Different capitalization in QML and C++ for the role: "tableName" vs. "TableName"

    Cheers,
    _

  24. The following user says thank you to anda_skoa for this useful post:

    jfinn88 (31st August 2016)

Similar Threads

  1. Replies: 16
    Last Post: 4th September 2013, 01:49
  2. How to set x509 on a QSqlDatabase Connection?
    By m3rlin in forum Qt Programming
    Replies: 24
    Last Post: 21st February 2012, 05:04
  3. Windows OCI QSqlDatabase connection
    By hollyberry in forum Newbie
    Replies: 10
    Last Post: 13th February 2012, 23:13
  4. QSqlDatabase Connection Close on Destruction
    By Sanuden in forum Qt Programming
    Replies: 1
    Last Post: 1st September 2011, 16:32
  5. QSqlDatabase connection timeout?
    By joseprl89 in forum Qt Programming
    Replies: 6
    Last Post: 27th March 2011, 03: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.