Skip to content
  • Categories
  • Recent
  • Tags
  • Popular
  • Users
  • Groups
  • Search
  • Get Qt Extensions
  • Unsolved
Collapse
Brand Logo
  1. Home
  2. Qt Development
  3. General and Desktop
  4. Is it possible to Convert a QSqlQuery Model to a QsqlTableModel
Forum Updated to NodeBB v4.3 + New Features

Is it possible to Convert a QSqlQuery Model to a QsqlTableModel

Scheduled Pinned Locked Moved Solved General and Desktop
20 Posts 3 Posters 6.3k Views 2 Watching
  • Oldest to Newest
  • Newest to Oldest
  • Most Votes
Reply
  • Reply as topic
Log in to reply
This topic has been deleted. Only users with topic management privileges can see it.
  • AsimovA Offline
    AsimovA Offline
    Asimov
    wrote on last edited by Asimov
    #11

    Hi SGaist,

    I have tried again this time I am using my model which is created in DbManager class. In the header file the class is set up DbManager myDatabase; and modelBox which is my model is created in that class.

    connect(myDatabase.modelBox, SIGNAL(dataChanged(const QModelIndex&)),this,SLOT(test()));
    

    I am just getting it to respond, but it isn't

    void MainWindow::test(){
        qDebug() << "signal";
    }
    

    So the signal does not seem to be working. I am very perplexed.
    I have tried to look at the new qt5 format and that is even more confusing. I don't even now where to put the callback on that. Once I have got the old one to work, I might look into the new one again.

    On another note I am now using

    delete query;
    

    Which should free up the memory on the stack hopefully.

    PS. I am getting this error

    QObject::connect: No such signal QStandardItemModel::dataChanged(const QModelIndex&)
    QObject::connect:  (receiver name: 'MainWindow')
    
    1 Reply Last reply
    0
    • AsimovA Offline
      AsimovA Offline
      Asimov
      wrote on last edited by Asimov
      #12

      Hi,

      After making my last post I decided to call connect from my DbManager class like this

      void DbManager::boxList(Ui::MainWindow* ui){
          QSqlQuery* query=new QSqlQuery(mydb);
          query->prepare("select `boxID`,`boxName`,`boxLocation` from `boxes`");
          query->exec();
      
          modelBox= new QStandardItemModel(sqlSize(query), 3);
          int i=0;
          while (query->next())
          {
              modelBox->setData(modelBox->index(i, 0), query->value("boxID"));
              modelBox->setData(modelBox->index(i, 1), query->value("boxName"));
              modelBox->setData(modelBox->index(i, 2), query->value("boxLocation"));
              i++;
          }
          modelBox->setHeaderData(1, Qt::Horizontal, QObject::tr("Box ID / Name"));
          modelBox->setHeaderData(2, Qt::Horizontal, QObject::tr("Box Location"));
          ui->boxTable->setModel(modelBox);
          ui->boxTable->setColumnHidden(0, true);
          delete query;
          QObject::connect(modelBox, SIGNAL(dataChanged(const QModelIndex &, const QModelIndex &)),modelBox,SLOT(updateBoxList(ui,const QModelIndex & , const QModelIndex &)));
      }
      

      The good news is that I have now got rid of the signal error, but now I am getting a slot error like this

      QObject::connect: No such slot QStandardItemModel::updateBoxList(ui,const QModelIndex & , const QModelIndex &)
      

      In my DbManager class header I have

      public slots:
              void updateBoxList(Ui::MainWindow *ui,const QModelIndex & , const QModelIndex &);
      
      1 Reply Last reply
      0
      • SGaistS Offline
        SGaistS Offline
        SGaist
        Lifetime Qt Champion
        wrote on last edited by
        #13

        Then, why do you pass modelBox as the object containing that slot ?

        Again, there's no need to allocate query on the heap, use a local stack variable, that's enough.

        Interested in AI ? www.idiap.ch
        Please read the Qt Code of Conduct - https://forum.qt.io/topic/113070/qt-code-of-conduct

        1 Reply Last reply
        0
        • AsimovA Offline
          AsimovA Offline
          Asimov
          wrote on last edited by Asimov
          #14

          I used modelBox as the container of the slot because originally I used this, but then I got an error by doing this. Then I changed it to modelBox the name of my model. Anyway I changed it back to this, and it still says there is no slot. I am getting a little confused.

          modelBox is the name of the model, which holds the data for the table. You said in your last post not to use the QTableView but the name of the model. So I used the name of the model instead of ui->boxTable which was the name of the QTableView.

          I don't know how to use a local stack variable.
          It has been a couple of years since I have done any C++, and I am trying to get back into it.
          Also I have only been using QT for about a week, so I am new at all this, and having to learn fast.

          1 Reply Last reply
          0
          • SGaistS Offline
            SGaistS Offline
            SGaist
            Lifetime Qt Champion
            wrote on last edited by
            #15

            From the code you posted, the slot is in DbManager.

            Note that you are trying to do something wrong here. It seems you try to pass the ui variable in SLOT which is not possible.

            Since it seems that you manage the model directly in DbManager, there's no need to involve your MainWindow class. Once you update modelBox, it will trigger updates in boxTable automatically.

            Interested in AI ? www.idiap.ch
            Please read the Qt Code of Conduct - https://forum.qt.io/topic/113070/qt-code-of-conduct

            1 Reply Last reply
            0
            • AsimovA Offline
              AsimovA Offline
              Asimov
              wrote on last edited by Asimov
              #16

              Well SGaist you have solved my signal problem. Taking out the ui worked. My signal is now firing and running my update function, thankyou.

              The problem is that I have been passing the ui so I can update the ui. You see when I call void DbManager::boxList(Ui::MainWindow* ui) I send in the ui because my class has no access to the ui, so if I don't pass it in, I can't update anything on the window. So I pass the ui from MainWindow to my class DbManager. This is why I was sending the ui to my function in the slot.

              If my function needs to update any ui element then it won't be able to because I have not passed it the ui.
              Hmm just had an idea, perhaps when I setup my Dbmanager class I can pass the ui in the contructor and then all my functions will have acces to the ui.

              I think I solved the local stack problem now. I had to change query-> to query. all through the code. Here is my new code.

              void DbManager::boxList(Ui::MainWindow* ui){
                  QSqlQuery query;
                  query.prepare("select `boxID`,`boxName`,`boxLocation` from `boxes`");
                  query.exec();
                  modelBox= new QStandardItemModel(sqlSize(query), 3);
                  int i=0;
                  while (query.next())
                  {
                      modelBox->setData(modelBox->index(i, 0), query.value("boxID"));
                      modelBox->setData(modelBox->index(i, 1), query.value("boxName"));
                      modelBox->setData(modelBox->index(i, 2), query.value("boxLocation"));
                      i++;
                  }
                  modelBox->setHeaderData(1, Qt::Horizontal, QObject::tr("Box ID / Name"));
                  modelBox->setHeaderData(2, Qt::Horizontal, QObject::tr("Box Location"));
                  ui->boxTable->setModel(modelBox);
                  ui->boxTable->setColumnHidden(0, true);
                  QObject::connect(modelBox, SIGNAL(dataChanged(const QModelIndex &, const QModelIndex &)),this,SLOT(updateBoxList(const QModelIndex & , const QModelIndex &)));
              }
              
              1 Reply Last reply
              0
              • SGaistS Offline
                SGaistS Offline
                SGaist
                Lifetime Qt Champion
                wrote on last edited by
                #17

                Then your design is not good. You are creating a tight coupling that doesn't do much good.

                DbManager should not need to know MainWindow nor should it car about it. From what I gathered from your code, it should only operate on the model. If you need your MainWindow to do stuff based on actions from DbManager, then you should implement it through signals and slots. Make your DbManager share information as needed and plug your MainWindow on that. Doing so will make your encapsulation cleaner and if you need to change anything in your MainWindow to modify your GUI then you won't have to change anything in your DbManager class.

                Interested in AI ? www.idiap.ch
                Please read the Qt Code of Conduct - https://forum.qt.io/topic/113070/qt-code-of-conduct

                AsimovA 1 Reply Last reply
                1
                • SGaistS SGaist

                  Then your design is not good. You are creating a tight coupling that doesn't do much good.

                  DbManager should not need to know MainWindow nor should it car about it. From what I gathered from your code, it should only operate on the model. If you need your MainWindow to do stuff based on actions from DbManager, then you should implement it through signals and slots. Make your DbManager share information as needed and plug your MainWindow on that. Doing so will make your encapsulation cleaner and if you need to change anything in your MainWindow to modify your GUI then you won't have to change anything in your DbManager class.

                  AsimovA Offline
                  AsimovA Offline
                  Asimov
                  wrote on last edited by
                  #18

                  @SGaist

                  Partly I agree with you, but it could cause me a few problems.
                  My DbManager class is to do all database related functions.

                  In my previous post I showed my function boxList which sets up the model from the database and this is in my Dbmanager class, but without the ui, I couldn't run the following line.

                  ui->boxTable->setModel(modelBox);
                  

                  I think I could have more ui functions in MainWindow, and limit my use of ui in my DbManager class.
                  So I agree in principle, but whether I can get it to work is another thing LOL

                  1 Reply Last reply
                  0
                  • SGaistS Offline
                    SGaistS Offline
                    SGaist
                    Lifetime Qt Champion
                    wrote on last edited by
                    #19

                    The request the model from your DbManager through a getter and let the MainWindow set it to whatever widget you want for this task. This will again make the DbManager independent from the GUI.

                    Interested in AI ? www.idiap.ch
                    Please read the Qt Code of Conduct - https://forum.qt.io/topic/113070/qt-code-of-conduct

                    1 Reply Last reply
                    0
                    • AsimovA Offline
                      AsimovA Offline
                      Asimov
                      wrote on last edited by Asimov
                      #20

                      I think I understand.
                      So I can have a function in DbManager like

                      QStandardItemModel DbManager::getModelBox()
                      {
                           return modelBox;
                      }
                      

                      Then in Windows Main I can call it like this

                      myDatabase.getModelbox()->setModel(modelBox);
                      

                      I am going to give tihs a go now. Thanks.

                      PS. After playing with it for a while I realise my code above was wrong. So here is the code that worked, in case anyone is following this thread

                      QStandardItemModel* DbManager::getmodelBox()
                      {
                           return modelBox;
                      }
                      

                      And in MainWindow I can call it like tihs

                      ui->boxTable->setModel(myDatabase.getmodelBox());
                      

                      Thanks SGaist I have learnt a lot. Will mark this thread as solved, even though I got a lot of answers, thanks

                      1 Reply Last reply
                      0

                      • Login

                      • Login or register to search.
                      • First post
                        Last post
                      0
                      • Categories
                      • Recent
                      • Tags
                      • Popular
                      • Users
                      • Groups
                      • Search
                      • Get Qt Extensions
                      • Unsolved