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. QAbstractTableModel + QML TableView: How to call setData?
Forum Updated to NodeBB v4.3 + New Features

QAbstractTableModel + QML TableView: How to call setData?

Scheduled Pinned Locked Moved Unsolved General and Desktop
40 Posts 3 Posters 10.5k 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.
  • VRoninV VRonin

    @Bremenpl said in QAbstractTableModel + QML TableView: How to call setData?:

    One could use it to locate itself in the table as well as read model data.

    now you don't need it anymore. you just access role names directly to read data and you can use index, row and column directly to locate yourself within the model

    Btw, this doesnt call setData:

    Yes it does. If the dataChanged signal is not enough to convince you you can add the below to MyModel

    bool setData(const QModelIndex &index, const QVariant &value, int role = Qt::EditRole) override{
            qDebug() << "Called setData";
            return QStringListModel::setData(index,value,role);
        }
    
    B Offline
    B Offline
    Bremenpl
    wrote on last edited by
    #22

    @VRonin Ok, you are right! Thanks.
    It feels like we are really close this time. So this is the components now:

    		TableView
    		{
    			anchors.fill: parent;
    			model: tableModel;
    
    			delegate: TextInput
    			{
    				text: Name;
    
    				onEditingFinished:
    				{
    					Name = text
    				}
    			}
    		}
    

    My columns and roles are still mixed together because of the obsolete behavior- this needs to be disconnected. In this case, what should the roleNames override method return actually?

    lprzenioslo.zut.edu.pl

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

      @Bremenpl said in QAbstractTableModel + QML TableView: How to call setData?:

      hat should the roleNames override method return actually?

      I would not override it at all and just use the default edit

      				text: edit
      
      				onEditingFinished:
      				{
      					edit = text
      				}
      

      "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

      B 1 Reply Last reply
      1
      • VRoninV VRonin

        @Bremenpl said in QAbstractTableModel + QML TableView: How to call setData?:

        hat should the roleNames override method return actually?

        I would not override it at all and just use the default edit

        				text: edit
        
        				onEditingFinished:
        				{
        					edit = text
        				}
        
        B Offline
        B Offline
        Bremenpl
        wrote on last edited by
        #24

        @VRonin , yeah I just came to realize that too. I did:

        delegate: TextInput
        			{
        				text: display;
        
        				onEditingFinished:
        				{
        					edit = text
        				}
        			}
        

        Which I believe in this context gives the same effect.
        Alright... Thank you very much for your feedback, you helped me a lot.
        Now I only need to figure out either headerData can be utilized and that would be it.

        lprzenioslo.zut.edu.pl

        VRoninV 1 Reply Last reply
        0
        • B Bremenpl

          @VRonin , yeah I just came to realize that too. I did:

          delegate: TextInput
          			{
          				text: display;
          
          				onEditingFinished:
          				{
          					edit = text
          				}
          			}
          

          Which I believe in this context gives the same effect.
          Alright... Thank you very much for your feedback, you helped me a lot.
          Now I only need to figure out either headerData can be utilized and that would be it.

          VRoninV Offline
          VRoninV Offline
          VRonin
          wrote on last edited by
          #25

          @Bremenpl said in QAbstractTableModel + QML TableView: How to call setData?:

          Now I only need to figure out either headerData can be utilized and that would be it.

          I'm afraid that part has not been developed by Qt yet

          We’re also working on a TableHeader, TableModel, as well as a DelegateChooser.

          "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

          B 1 Reply Last reply
          0
          • VRoninV VRonin

            @Bremenpl said in QAbstractTableModel + QML TableView: How to call setData?:

            Now I only need to figure out either headerData can be utilized and that would be it.

            I'm afraid that part has not been developed by Qt yet

            We’re also working on a TableHeader, TableModel, as well as a DelegateChooser.

            B Offline
            B Offline
            Bremenpl
            wrote on last edited by
            #26

            @VRonin So as for now, is there a way to set the column header at all?

            lprzenioslo.zut.edu.pl

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

              Not exactly what I would call a header. There's this: https://doc.qt.io/qt-5/qml-qtquick-tableview.html#overlays-and-underlays but it's far from anything that is actually useful

              "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

              B 1 Reply Last reply
              0
              • VRoninV VRonin

                Not exactly what I would call a header. There's this: https://doc.qt.io/qt-5/qml-qtquick-tableview.html#overlays-and-underlays but it's far from anything that is actually useful

                B Offline
                B Offline
                Bremenpl
                wrote on last edited by
                #28

                @VRonin Yes, I have just checked this. It overlaps my first row... Do you know either rows inserting and removing work? Meaning- If I remove or insert a row at runtime, will it update the view?
                This seems to still be a very beta thing, I wonder either old or new controls should be used.

                lprzenioslo.zut.edu.pl

                VRoninV 1 Reply Last reply
                0
                • B Bremenpl

                  Hello there,
                  I have a custom model class subclassing the QAbstractTableModel. On the QML side, I have a TableView component. I am trying to connect those 2 things. As for now, I have the TableView reading the data correctly using the data method on C++ side.

                  Now, I am editing the cells on the QML side and after I am done, I dont know how to make the TreeView call the setData method. I could call it by hand, but the problem is that it requires a valid QModelIndex object:

                  bool setData(const QModelIndex &index, const QVariant &value, int role = Qt::EditRole) override;
                  

                  I dont know how to create one one the QML side. I think there should be a method to call it indirectly from QML, but I dont know how. I would appreciate all help regarding this issue. This is my QML test component:

                  import QtQuick 2.12
                  import QtQuick.Controls 2.3
                  import QtQuick.Controls 1.4
                  import QtGraphicalEffects 1.0
                  import "."
                  
                  Popup
                  {
                  	id: thePopup;
                  	modal: true;
                  	focus: true;
                  	closePolicy: Popup.CloseOnEscape | Popup.CloseOnPressOutside;
                  
                  	leftPadding: 0;
                  	rightPadding: 0;
                  	topPadding: 0;
                  	bottomPadding: 0;
                  
                  	property real closeMargin: 20;
                  	property real localScale: 1;
                  	property real fontSizeVal: 15;
                  	property Ucolors cg;
                  	property variant tableModel;
                  
                  	Rectangle
                  	{
                  		id: popRect;
                  
                  		width: parent.width;
                  		height: parent.height;
                  		color: cg.canvas;
                  
                  		TableView
                  		{
                  			anchors.fill: parent;
                  			model: tableModel;
                  
                  			// TEMP solution
                  			TableViewColumn {title: "1"; role: tableModel ? tableModel.role(0) : ""; width: 70 }
                  			TableViewColumn {title: "2"; role: tableModel ? tableModel.role(1) : "";  width: 70   }
                  			TableViewColumn {title: "3"; role: tableModel ? tableModel.role(2) : "";  width: 70 }
                  
                  			itemDelegate: Rectangle
                  			{
                  				id: delegateRec;
                  				color: colGlob.canvas;
                  
                  				Text
                  				{
                  					id: theCellText;
                  
                  					anchors
                  					{
                  						verticalCenter: parent.verticalCenter;
                  						left: parent.left;
                  						margins: 10;
                  					}
                  
                  					//color: colGlob.text;
                  					text: tableModel ? styleData.value : "";
                  					//font.pixelSize: fontSize;
                  					//font.family: Uconsts.roboFont.name;
                  				}
                  
                  				MouseArea
                  				{
                  					id: cellMouseArea
                  
                  					anchors.fill: parent;
                  					onClicked:
                  					{
                  						theCellText.visible = false;
                  						theLoader.visible = true;
                  						theLoader.item.forceActiveFocus();
                  					}
                  				}
                  
                  				Loader
                  				{
                  					id: theLoader;
                  
                  					anchors
                  					{
                  						verticalCenter: parent.verticalCenter;
                  						left: parent.left;
                  						margins: 10;
                  					}
                  
                  					height: parent.height;
                  					width: parent.width;
                  					visible: false;
                  					sourceComponent: visible ? theInputComp : undefined;
                  
                  					Component
                  					{
                  						id: theInputComp;
                  
                  						TextInput
                  						{
                  							id: textInputId;
                  							anchors.fill: parent;
                  
                  							onEditingFinished:
                  							{
                  								console.log("Edited");
                  								theLoader.visible = false;
                  								theCellText.visible = true;
                  
                  								// TODO how to call setData?
                  							}
                  						}
                  					}
                  				}
                  			}
                  		}
                  	}
                  }
                  

                  I also dont know how to force the QML TreeView to call the C++ headerData method, but this is of less importance than setData...
                  I would appreciate all help.

                  raven-worxR Offline
                  raven-worxR Offline
                  raven-worx
                  Moderators
                  wrote on last edited by raven-worx
                  #29

                  @Bremenpl said in QAbstractTableModel + QML TableView: How to call setData?:

                  I also dont know how to force the QML TreeView to call the C++ headerData method

                  since you use QtQuick.Controls 1 TableView you need to use the TableViewColumn element, which only supports roles.
                  So you can add custom role names and forward those header roles to the headerData() method in the data() method.

                  virtual QHash<int, QByteArray> roleNames() const {
                      QHash<int, QByteArray> rn = QAbstractItemModel::roleNames();
                      rn[MyHeaderRole1] = QByteArrayLiteral("header1");
                      return rn;
                  }
                  
                  QVariantdata(const QModelIndex &index, int role = Qt::DisplayRole) const {
                       switch( role )
                       {
                          case MyHeaderRole1:  return headerData(0, Qt::Horizontal);
                          ...
                       }
                       return QVariant();
                  }
                  

                  --- SUPPORT REQUESTS VIA CHAT WILL BE IGNORED ---
                  If you have a question please use the forum so others can benefit from the solution in the future

                  B 1 Reply Last reply
                  0
                  • raven-worxR raven-worx

                    @Bremenpl said in QAbstractTableModel + QML TableView: How to call setData?:

                    I also dont know how to force the QML TreeView to call the C++ headerData method

                    since you use QtQuick.Controls 1 TableView you need to use the TableViewColumn element, which only supports roles.
                    So you can add custom role names and forward those header roles to the headerData() method in the data() method.

                    virtual QHash<int, QByteArray> roleNames() const {
                        QHash<int, QByteArray> rn = QAbstractItemModel::roleNames();
                        rn[MyHeaderRole1] = QByteArrayLiteral("header1");
                        return rn;
                    }
                    
                    QVariantdata(const QModelIndex &index, int role = Qt::DisplayRole) const {
                         switch( role )
                         {
                            case MyHeaderRole1:  return headerData(0, Qt::Horizontal);
                            ...
                         }
                         return QVariant();
                    }
                    
                    B Offline
                    B Offline
                    Bremenpl
                    wrote on last edited by
                    #30

                    @raven-worx thanks for answer. The thing is that at this point I am not certain anymore which version TableView I should opt for. On one hand I dont want to use the obsolete component which has columns and roles functionality mixed, and on the other this.new one doesnt seem to be ready for usage.

                    lprzenioslo.zut.edu.pl

                    raven-worxR VRoninV 2 Replies Last reply
                    0
                    • B Bremenpl

                      @raven-worx thanks for answer. The thing is that at this point I am not certain anymore which version TableView I should opt for. On one hand I dont want to use the obsolete component which has columns and roles functionality mixed, and on the other this.new one doesnt seem to be ready for usage.

                      raven-worxR Offline
                      raven-worxR Offline
                      raven-worx
                      Moderators
                      wrote on last edited by raven-worx
                      #31

                      @Bremenpl said in QAbstractTableModel + QML TableView: How to call setData?:

                      and on the other this.new one doesnt seem to be ready for usage.

                      Based on the example from the docs (untested though):

                      TableView {
                          id: tableView
                      
                          columnWidthProvider: function (column) { 
                                  var colWidth = ...;
                                  var headerItem = headerRepeater.itemAt(column)
                                  if( headerItem )
                                      headerItem.width = colWidth;
                                  return colWidth; 
                            }
                      
                          topMargin: header.height
                      
                          Row {
                              id: header
                              height: 40
                              width: implicitWidth
                              padding: 0
                              spacing: 0
                      
                              Repeater {
                                  id: headerRepeater
                                  model: tableView.columns 
                                  Item {
                                         height: parent.height
                                        // your column delegate
                                  }
                              }
                          }
                      }
                      

                      Could be easier/built-in indeed, but i think this should work (with minor adaptions probably).

                      QAbstractItemModel::headerData() is directly invokable from within QML

                      --- SUPPORT REQUESTS VIA CHAT WILL BE IGNORED ---
                      If you have a question please use the forum so others can benefit from the solution in the future

                      B 1 Reply Last reply
                      1
                      • B Bremenpl

                        @raven-worx thanks for answer. The thing is that at this point I am not certain anymore which version TableView I should opt for. On one hand I dont want to use the obsolete component which has columns and roles functionality mixed, and on the other this.new one doesnt seem to be ready for usage.

                        VRoninV Offline
                        VRoninV Offline
                        VRonin
                        wrote on last edited by
                        #32

                        @Bremenpl said in QAbstractTableModel + QML TableView: How to call setData?:

                        On one hand I dont want to use the obsolete component which has columns and roles functionality mixed, and on the other this.new one doesnt seem to be ready for usage.

                        I'm not aware of a possibility to use headers directly even in the old tebleview

                        "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

                        B 1 Reply Last reply
                        0
                        • raven-worxR raven-worx

                          @Bremenpl said in QAbstractTableModel + QML TableView: How to call setData?:

                          and on the other this.new one doesnt seem to be ready for usage.

                          Based on the example from the docs (untested though):

                          TableView {
                              id: tableView
                          
                              columnWidthProvider: function (column) { 
                                      var colWidth = ...;
                                      var headerItem = headerRepeater.itemAt(column)
                                      if( headerItem )
                                          headerItem.width = colWidth;
                                      return colWidth; 
                                }
                          
                              topMargin: header.height
                          
                              Row {
                                  id: header
                                  height: 40
                                  width: implicitWidth
                                  padding: 0
                                  spacing: 0
                          
                                  Repeater {
                                      id: headerRepeater
                                      model: tableView.columns 
                                      Item {
                                             height: parent.height
                                            // your column delegate
                                      }
                                  }
                              }
                          }
                          

                          Could be easier/built-in indeed, but i think this should work (with minor adaptions probably).

                          QAbstractItemModel::headerData() is directly invokable from within QML

                          B Offline
                          B Offline
                          Bremenpl
                          wrote on last edited by
                          #33

                          @raven-worx Thanks for answer, but I am really lost at this one. What is supposed to be my column delegate?

                          I am playing with this new TableView for over an hour now and I am not even able to set variable columns width (when the container width change). I wonder either this is a bug or a feature.

                          lprzenioslo.zut.edu.pl

                          raven-worxR 1 Reply Last reply
                          0
                          • VRoninV VRonin

                            @Bremenpl said in QAbstractTableModel + QML TableView: How to call setData?:

                            On one hand I dont want to use the obsolete component which has columns and roles functionality mixed, and on the other this.new one doesnt seem to be ready for usage.

                            I'm not aware of a possibility to use headers directly even in the old tebleview

                            B Offline
                            B Offline
                            Bremenpl
                            wrote on last edited by
                            #34

                            @VRonin But would you say the new one or old one is more fit to use...?

                            lprzenioslo.zut.edu.pl

                            1 Reply Last reply
                            0
                            • B Bremenpl

                              @raven-worx Thanks for answer, but I am really lost at this one. What is supposed to be my column delegate?

                              I am playing with this new TableView for over an hour now and I am not even able to set variable columns width (when the container width change). I wonder either this is a bug or a feature.

                              raven-worxR Offline
                              raven-worxR Offline
                              raven-worx
                              Moderators
                              wrote on last edited by
                              #35

                              @Bremenpl said in QAbstractTableModel + QML TableView: How to call setData?:

                              What is supposed to be my column delegate?

                              what every you want it to look like. A Rectangle with a Text inside maybe?

                              --- SUPPORT REQUESTS VIA CHAT WILL BE IGNORED ---
                              If you have a question please use the forum so others can benefit from the solution in the future

                              B 1 Reply Last reply
                              1
                              • raven-worxR raven-worx

                                @Bremenpl said in QAbstractTableModel + QML TableView: How to call setData?:

                                What is supposed to be my column delegate?

                                what every you want it to look like. A Rectangle with a Text inside maybe?

                                B Offline
                                B Offline
                                Bremenpl
                                wrote on last edited by
                                #36

                                @raven-worx I tried a simple Text component and all that was visible was a single text (not sure either they were stacked one on another).

                                Arent you guys aware any single code example showing how to do this all from ground up?

                                lprzenioslo.zut.edu.pl

                                raven-worxR 1 Reply Last reply
                                0
                                • B Bremenpl

                                  @VRonin Yes, I have just checked this. It overlaps my first row... Do you know either rows inserting and removing work? Meaning- If I remove or insert a row at runtime, will it update the view?
                                  This seems to still be a very beta thing, I wonder either old or new controls should be used.

                                  VRoninV Offline
                                  VRoninV Offline
                                  VRonin
                                  wrote on last edited by
                                  #37

                                  I understand and share your frustration on the state of views in QML, development has been focused on components that work well on mobile platforms (as QtWidgets is not really an option there) so views have been neglected.

                                  @Bremenpl said in QAbstractTableModel + QML TableView: How to call setData?:

                                  Do you know either rows inserting and removing work?

                                  It does, the example I linked actually does it

                                  I have just checked this. It overlaps my first row

                                  looks like you forgot the topMargin: header.implicitHeight part

                                  "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

                                  B 1 Reply Last reply
                                  0
                                  • B Bremenpl

                                    @raven-worx I tried a simple Text component and all that was visible was a single text (not sure either they were stacked one on another).

                                    Arent you guys aware any single code example showing how to do this all from ground up?

                                    raven-worxR Offline
                                    raven-worxR Offline
                                    raven-worx
                                    Moderators
                                    wrote on last edited by
                                    #38

                                    @Bremenpl said in QAbstractTableModel + QML TableView: How to call setData?:

                                    I tried a simple Text component and all that was visible was a single text (not sure either they were stacked one on another).

                                    maybe there is only 1 column?
                                    is your model's columnCount() method called?

                                    --- SUPPORT REQUESTS VIA CHAT WILL BE IGNORED ---
                                    If you have a question please use the forum so others can benefit from the solution in the future

                                    B 1 Reply Last reply
                                    0
                                    • raven-worxR raven-worx

                                      @Bremenpl said in QAbstractTableModel + QML TableView: How to call setData?:

                                      I tried a simple Text component and all that was visible was a single text (not sure either they were stacked one on another).

                                      maybe there is only 1 column?
                                      is your model's columnCount() method called?

                                      B Offline
                                      B Offline
                                      Bremenpl
                                      wrote on last edited by
                                      #39

                                      @raven-worx It is. I will give it another go, thank you.

                                      lprzenioslo.zut.edu.pl

                                      1 Reply Last reply
                                      0
                                      • VRoninV VRonin

                                        I understand and share your frustration on the state of views in QML, development has been focused on components that work well on mobile platforms (as QtWidgets is not really an option there) so views have been neglected.

                                        @Bremenpl said in QAbstractTableModel + QML TableView: How to call setData?:

                                        Do you know either rows inserting and removing work?

                                        It does, the example I linked actually does it

                                        I have just checked this. It overlaps my first row

                                        looks like you forgot the topMargin: header.implicitHeight part

                                        B Offline
                                        B Offline
                                        Bremenpl
                                        wrote on last edited by
                                        #40

                                        @VRonin Thanks for answer. I did snap a little bit, sorry for that...
                                        I will give the new TableView another go according to yours and @raven-worx hints but as for now I think the Version 1 is more complete. The only lacking thing is to make the TreeView to call setData automatically (I only got this working in the new version). In the 1st version I am still calling a wrapper for it.

                                        Thank you for help guys.

                                        lprzenioslo.zut.edu.pl

                                        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