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. fill QTableView with items from lineedit
Qt 6.11 is out! See what's new in the release blog

fill QTableView with items from lineedit

Scheduled Pinned Locked Moved Solved General and Desktop
17 Posts 4 Posters 6.0k Views 1 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.
  • H hobbyProgrammer

    @JonB said in fill QTableView with items from lineedit:

    Before we start on your code. Do you mean your model is actually a QAbstractItemModel, or do you mean it's a class derived from that? Because as per docs

    The model is actually a QAbstractItemModel

    Since you're starting out QStandardItemModel would be a recommended choice.

    Okay thank you. I will look into that.

    Or, your code only attempts to put a single "name" into a row, and you talk about one QLineEdit, will you actually want multiple columns, because if you only have a single column you may instead only want a QStringListModel?

    Currently I only need 1 column, but I'd like to expand it to two. So I would like to create an easily expandable solution.

    JonBJ Offline
    JonBJ Offline
    JonB
    wrote on last edited by JonB
    #6

    @hobbyProgrammer
    OK. For your code, scribbled in haste:

    1. QAbstractItemModel::setData() won't do anything. So you can't use it to store data. (As an end-user of a library, you usually never want to create/instantiate any class named *Abstract*!) Try QStandardItemModel.

    2. You need to make your QModelIndex modelIndex refer to where you want to insert in your code. [EDIT From what @VRonin has just posted below, that's the magic of model->index(newRowIndex,0) (https://doc.qt.io/qt-5/qabstractitemmodel.html#index).]

    3. You can now use QStandardItemModel::insertRow(int row, QStandardItem *item) (https://doc.qt.io/qt-5/qstandarditemmodel.html#insertRow-1) instead.

    4. Don't put the ui->tableView->setModel(model); when adding an item, put it once at the start outside of here.

    1 Reply Last reply
    0
    • VRoninV Offline
      VRoninV Offline
      VRonin
      wrote on last edited by VRonin
      #7

      Assuming the model works:

      const int newRowIndex = model->rowCount();
      model->insertRow(newRowIndex);
      model->setData(model->index(newRowIndex,0),name);
      

      I agree the easiest way is just to use QAbstractItemModel* model = new QStandardItemModel as a model. It works out of the box and gives you the flexibility to change it in the future if you really want a custom model

      "La mort n'est rien, mais vivre vaincu et sans gloire, c'est mourir tous les jours"
      ~Napoleon Bonaparte

      On a crusade to banish setIndexWidget() from the holy land of Qt

      H 1 Reply Last reply
      3
      • VRoninV VRonin

        Assuming the model works:

        const int newRowIndex = model->rowCount();
        model->insertRow(newRowIndex);
        model->setData(model->index(newRowIndex,0),name);
        

        I agree the easiest way is just to use QAbstractItemModel* model = new QStandardItemModel as a model. It works out of the box and gives you the flexibility to change it in the future if you really want a custom model

        H Offline
        H Offline
        hobbyProgrammer
        wrote on last edited by
        #8

        @VRonin Hi,

        For the model I just do this in the constructor:

            model = new QStandardItemModel(100,1,this);
            ui->tableView->setModel(model);
        

        and it's in the mainwindow.h file like this:

           QStandardItemModel  *model;
        

        and to add an item:

        void MainWindow::addItemToTableView(QString name)
        {
            qDebug () << "insert: " << name;
            const int newRowIndex = model->rowCount();
            model->insertRow(newRowIndex);
            model->setData(model->index(newRowIndex, 0), name);
        }
        

        it does print insert: name in the debugger, so the function is being called, but all the cells remain empty. Any idea why?

        JonBJ 1 Reply Last reply
        0
        • Christian EhrlicherC Offline
          Christian EhrlicherC Offline
          Christian Ehrlicher
          Lifetime Qt Champion
          wrote on last edited by
          #9

          Since you're using a QStandardItemModel you have to first create an item for this index. Or even better - only work with QStandardItems since this is what QStandardItemModel is created for. See https://doc-snapshots.qt.io/qt5-dev/qstandarditemmodel.html#details on how to add a QStandardItem.
          When you check the return value of setData() you would have noticed that it returns false for you.

          Qt Online Installer direct download: https://download.qt.io/official_releases/online_installers/
          Visit the Qt Academy at https://academy.qt.io/catalog

          1 Reply Last reply
          4
          • H hobbyProgrammer

            @VRonin Hi,

            For the model I just do this in the constructor:

                model = new QStandardItemModel(100,1,this);
                ui->tableView->setModel(model);
            

            and it's in the mainwindow.h file like this:

               QStandardItemModel  *model;
            

            and to add an item:

            void MainWindow::addItemToTableView(QString name)
            {
                qDebug () << "insert: " << name;
                const int newRowIndex = model->rowCount();
                model->insertRow(newRowIndex);
                model->setData(model->index(newRowIndex, 0), name);
            }
            

            it does print insert: name in the debugger, so the function is being called, but all the cells remain empty. Any idea why?

            JonBJ Offline
            JonBJ Offline
            JonB
            wrote on last edited by
            #10

            @hobbyProgrammer
            As @Christian-Ehrlicher has said and I wrote earlier, get rid of setData(), now use void QStandardItemModel::appendRow(QStandardItem *item) instead.

            1 Reply Last reply
            0
            • VRoninV Offline
              VRoninV Offline
              VRonin
              wrote on last edited by VRonin
              #11

              I disagree with @Christian-Ehrlicher and @JonB for once. This is rare. The QAbstractItemModel interface works perfectly well without any need to use specific subclass methods.

              This minimal complete example illustrates how it works, try it out. It should be straightforward then to adapt it to your situation

              #include <QTableView>
              #include <QGridLayout>
              #include <QLineEdit>
              #include <QStandardItemModel>
              #include <QApplication>
              #include <QPushButton>
              #include <QHeaderView>
              
              int main(int argc, char *argv[])
              {
                  QApplication a(argc, argv);
                  QWidget mainWid;
                  QAbstractItemModel* model = new QStandardItemModel(&mainWid);
                  model->insertColumn(0);
                  model->setHeaderData(0,Qt::Horizontal,QStringLiteral("My Column"));
                  QTableView* table = new QTableView(&mainWid);
                  table->setModel(model);
                  table->horizontalHeader()->setStretchLastSection(true);
                  QPushButton* insertLineButton = new QPushButton(QStringLiteral("Insert Row"),&mainWid);
                  QLineEdit* lineInsertEdit = new QLineEdit(&mainWid);
                  QObject::connect(insertLineButton,&QPushButton::clicked,[model,lineInsertEdit]()->void{
                      const int newRowIndex = model->rowCount();
                      model->insertRow(newRowIndex);
                      model->setData(model->index(newRowIndex, 0), lineInsertEdit->text());
                      lineInsertEdit->clear();
                  });
                  QGridLayout* mainLay = new QGridLayout(&mainWid);
                  mainLay->addWidget(table,0,0,1,2);
                  mainLay->addWidget(lineInsertEdit,1,0);
                  mainLay->addWidget(insertLineButton,1,1);
                  mainWid.show();
                  return a.exec();
              }
              

              "La mort n'est rien, mais vivre vaincu et sans gloire, c'est mourir tous les jours"
              ~Napoleon Bonaparte

              On a crusade to banish setIndexWidget() from the holy land of Qt

              JonBJ 1 Reply Last reply
              2
              • VRoninV VRonin

                I disagree with @Christian-Ehrlicher and @JonB for once. This is rare. The QAbstractItemModel interface works perfectly well without any need to use specific subclass methods.

                This minimal complete example illustrates how it works, try it out. It should be straightforward then to adapt it to your situation

                #include <QTableView>
                #include <QGridLayout>
                #include <QLineEdit>
                #include <QStandardItemModel>
                #include <QApplication>
                #include <QPushButton>
                #include <QHeaderView>
                
                int main(int argc, char *argv[])
                {
                    QApplication a(argc, argv);
                    QWidget mainWid;
                    QAbstractItemModel* model = new QStandardItemModel(&mainWid);
                    model->insertColumn(0);
                    model->setHeaderData(0,Qt::Horizontal,QStringLiteral("My Column"));
                    QTableView* table = new QTableView(&mainWid);
                    table->setModel(model);
                    table->horizontalHeader()->setStretchLastSection(true);
                    QPushButton* insertLineButton = new QPushButton(QStringLiteral("Insert Row"),&mainWid);
                    QLineEdit* lineInsertEdit = new QLineEdit(&mainWid);
                    QObject::connect(insertLineButton,&QPushButton::clicked,[model,lineInsertEdit]()->void{
                        const int newRowIndex = model->rowCount();
                        model->insertRow(newRowIndex);
                        model->setData(model->index(newRowIndex, 0), lineInsertEdit->text());
                        lineInsertEdit->clear();
                    });
                    QGridLayout* mainLay = new QGridLayout(&mainWid);
                    mainLay->addWidget(table,0,0,1,2);
                    mainLay->addWidget(lineInsertEdit,1,0);
                    mainLay->addWidget(insertLineButton,1,1);
                    mainWid.show();
                    return a.exec();
                }
                
                JonBJ Offline
                JonBJ Offline
                JonB
                wrote on last edited by JonB
                #12

                @VRonin
                I don't understand. @Christian-Ehrlicher wrote:

                When you check the return value of setData() you would have noticed that it returns false for you.

                I took him at his word! So your model->setData(model->index(newRowIndex, 0), lineInsertEdit->text()); should do noting and return false? And your code looks the same as the OP's attempt where he says "but all the cells remain empty."?

                I was actually going to create a new post to ask: I have never used QStandardItemModel, but in light of @Christian-Ehrlicher's comment I was going to ask what the "philosophy" of its design is if it does not allow setData() and you have to use a whole QStandardItem at a time instead of via row/column index? I'm confused :(

                1 Reply Last reply
                1
                • VRoninV Offline
                  VRoninV Offline
                  VRonin
                  wrote on last edited by VRonin
                  #13

                  I'll take it as a "citation needed":
                  QStandardItemModel::setData fetches the item coresponding to the cell using QStandardItemModel::itemFromIndex (see relevant code)

                  itemFromIndex then has a section, marked as "lazy part" that takes care of creating the item if it wasn't done already (see relevant code).

                  Hence calling setData works perfectly in any case with QStandardItemModel. It will return false only if an invalid index is passed to it

                  In the case of QStandardItemModel, the only reason to use methods of the derived class rather than the interface is if you use the (rather useful) QStandardItem::setFlags.

                  "La mort n'est rien, mais vivre vaincu et sans gloire, c'est mourir tous les jours"
                  ~Napoleon Bonaparte

                  On a crusade to banish setIndexWidget() from the holy land of Qt

                  Christian EhrlicherC 1 Reply Last reply
                  4
                  • VRoninV VRonin

                    I'll take it as a "citation needed":
                    QStandardItemModel::setData fetches the item coresponding to the cell using QStandardItemModel::itemFromIndex (see relevant code)

                    itemFromIndex then has a section, marked as "lazy part" that takes care of creating the item if it wasn't done already (see relevant code).

                    Hence calling setData works perfectly in any case with QStandardItemModel. It will return false only if an invalid index is passed to it

                    In the case of QStandardItemModel, the only reason to use methods of the derived class rather than the interface is if you use the (rather useful) QStandardItem::setFlags.

                    Christian EhrlicherC Offline
                    Christian EhrlicherC Offline
                    Christian Ehrlicher
                    Lifetime Qt Champion
                    wrote on last edited by
                    #14

                    @VRonin : you're right, I missed that part.

                    Qt Online Installer direct download: https://download.qt.io/official_releases/online_installers/
                    Visit the Qt Academy at https://academy.qt.io/catalog

                    JonBJ 1 Reply Last reply
                    2
                    • Christian EhrlicherC Christian Ehrlicher

                      @VRonin : you're right, I missed that part.

                      JonBJ Offline
                      JonBJ Offline
                      JonB
                      wrote on last edited by JonB
                      #15

                      @Christian-Ehrlicher said in fill QTableView with items from lineedit:

                      @VRonin : you're right, I missed that part.

                      OMG! OK, well at least now I don't have to post to ask why QStandardItemModel::setData() isn't implemented since it is after all, right? :)

                      @VRonin

                      In the case of QStandardItemModel, the only reason to use methods of the derived class rather than the interface is if you use the (rather useful) QStandardItem::setFlags.

                      Don't you think e.g. QStandardItemModel::appendRow(QStandardItem *item) looks rather neater than getting the row count and setData()ing for each column? :) I agree in this case when the user only wants to set one column it's not so needed, but in other cases?

                      1 Reply Last reply
                      1
                      • H Offline
                        H Offline
                        hobbyProgrammer
                        wrote on last edited by
                        #16

                        @JonB @Christian-Ehrlicher @VRonin

                        Thanks for all of your help!

                        It works now. This is the source code for anyone who has the same question:

                        void MainWindow::addItemToTableView(QString name)
                        {
                            QStandardItem *item = new QStandardItem(name);
                            items << item;
                        
                            for(int i = 0; i < items.size(); i++)
                            {
                                for(int j = 0; j < 1; j++)
                                {
                        
                                    model->setItem(i, j, items.at(i));
                                }
                            }
                        }
                        
                        class MainWindow : public QMainWindow
                        {
                            Q_OBJECT
                        
                        public:
                            MainWindow(QWidget *parent = nullptr);
                            ~MainWindow();
                        
                        private slots:
                            void on_pushButton_clicked();
                        
                        private:
                            Ui::MainWindow *ui;
                        
                            void addItemToTableView(QString);
                            QList<QStandardItem*> items;
                            QStandardItemModel  *model;
                        };
                        
                        1 Reply Last reply
                        0
                        • VRoninV Offline
                          VRoninV Offline
                          VRonin
                          wrote on last edited by
                          #17

                          disappointed

                          "La mort n'est rien, mais vivre vaincu et sans gloire, c'est mourir tous les jours"
                          ~Napoleon Bonaparte

                          On a crusade to banish setIndexWidget() from the holy land of Qt

                          1 Reply Last reply
                          2

                          • Login

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