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. Set background of specific row in QListView
QtWS25 Last Chance

Set background of specific row in QListView

Scheduled Pinned Locked Moved Solved General and Desktop
10 Posts 2 Posters 5.6k Views
  • 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.
  • cerrC Offline
    cerrC Offline
    cerr
    wrote on last edited by cerr
    #1

    Re: Set background of specific row in QTableView
    Hi,

    I have copied the setRowColor() from the link above into my code base call it like:

    void Widget::on_HostList_doubleClicked(const QModelIndex &index)
    {
        QAbstractItemModel *model = ui->HostList->model();
        setRowColor(model,index.row(),Qt::red,index);
    }
    

    but it does not seem to work, the color is not changing. Can someone help me here?

    A 1 Reply Last reply
    0
    • cerrC cerr

      Re: Set background of specific row in QTableView
      Hi,

      I have copied the setRowColor() from the link above into my code base call it like:

      void Widget::on_HostList_doubleClicked(const QModelIndex &index)
      {
          QAbstractItemModel *model = ui->HostList->model();
          setRowColor(model,index.row(),Qt::red,index);
      }
      

      but it does not seem to work, the color is not changing. Can someone help me here?

      A Offline
      A Offline
      ambershark
      wrote on last edited by
      #2

      @cerr You'll have to give a bit more info...

      1. Is model valid? Check to see if it is not null at least just to make sure. I usually just use a Q_ASSERT(model) when I'm having problems, as it's not something that needs to be checked in release mode.

      2. Is index.valid() true?

      3. is index.row() in the valid range?

      4. Based on the setRowColor VRonin posted you are passing the index you want to change as the parent. This is probably causing an issue, try setRowColor(model, index.row(), Qt::red);

      My L-GPL'd C++ Logger github.com/ambershark-mike/sharklog

      1 Reply Last reply
      0
      • cerrC Offline
        cerrC Offline
        cerr
        wrote on last edited by cerr
        #3

        @ambershark
        Thanks for your reply! I have changed my method now to look like:

        void Widget::on_HostList_doubleClicked(const QModelIndex &index)
        {
            QAbstractItemModel *model = ui->HostList->model();
            Q_ASSERT(model);
            Q_ASSERT(index.isValid());
            if (index.row() >= 0 && index.row() < model->rowCount()) {
                setRowColor(model,index.row(),Qt::red);
                qDebug() << "changing row " << index.row();
            } else
                qDebug() << "Row " << index.row() << " is out of range!";
        
        }
        

        But the color still isn't changing as I'd expect. Now, I think my model might be the issue, I'm loading my data into the list with this:

        int JTFTools::ListViewPopulate(QListView *listView, QStringList *stringList)
        {
            int rv = OK;
        
            QStringListModel* listModel = new QStringListModel(*stringList, listView);
            QItemSelectionModel *oldModel = listView->selectionModel();
            listView->setModel(listModel);
        
            delete oldModel;
        
            return rv;
        }
        

        do you have any further ideas?

        A 1 Reply Last reply
        0
        • cerrC cerr

          @ambershark
          Thanks for your reply! I have changed my method now to look like:

          void Widget::on_HostList_doubleClicked(const QModelIndex &index)
          {
              QAbstractItemModel *model = ui->HostList->model();
              Q_ASSERT(model);
              Q_ASSERT(index.isValid());
              if (index.row() >= 0 && index.row() < model->rowCount()) {
                  setRowColor(model,index.row(),Qt::red);
                  qDebug() << "changing row " << index.row();
              } else
                  qDebug() << "Row " << index.row() << " is out of range!";
          
          }
          

          But the color still isn't changing as I'd expect. Now, I think my model might be the issue, I'm loading my data into the list with this:

          int JTFTools::ListViewPopulate(QListView *listView, QStringList *stringList)
          {
              int rv = OK;
          
              QStringListModel* listModel = new QStringListModel(*stringList, listView);
              QItemSelectionModel *oldModel = listView->selectionModel();
              listView->setModel(listModel);
          
              delete oldModel;
          
              return rv;
          }
          

          do you have any further ideas?

          A Offline
          A Offline
          ambershark
          wrote on last edited by
          #4

          @cerr It's probably something you are doing with the model or the view. I can write up a quick example in a bit that shows it in action if you want and you can take it from there.

          Your code in the second part you listed is wrong. You are using selectionModel() instead of model(). They are completely different things. I'm actually surprised by you deleting an owned selectionModel() that things aren't crashing.

          I also would continually delete then create new models like that. It's not really designed to be used that way. It would also cause heap fragmentation, which isn't as big a deal as it used to be back in the day, but still hurts your memory usage. You also double set your model by parenting it then using setModel().

          Here is a replacement function for that:

          int JTFTools::ListViewPopulate(QListView *listView, QStringList *stringList)
          {
              int rv = OK;
          
              auto model = qobject_cast<QStringListModel *>(listView->model());
             model->setStringList(*stringList);
          
              return rv;
          }
          

          Oh, and I wouldn't pass by non-const pointer if you don't edit the contents.. so I would change that stringList to const QStringList * or use a reference with const QStringList &. That's just protection for you as a developer and any other coders that come behind you though so not a huge deal. It's just a smart practice to get into.

          Changing that function may fix your problem, but I doubt it, so let me know if you want me to write up a quick example later on.

          My L-GPL'd C++ Logger github.com/ambershark-mike/sharklog

          cerrC 1 Reply Last reply
          2
          • A ambershark

            @cerr It's probably something you are doing with the model or the view. I can write up a quick example in a bit that shows it in action if you want and you can take it from there.

            Your code in the second part you listed is wrong. You are using selectionModel() instead of model(). They are completely different things. I'm actually surprised by you deleting an owned selectionModel() that things aren't crashing.

            I also would continually delete then create new models like that. It's not really designed to be used that way. It would also cause heap fragmentation, which isn't as big a deal as it used to be back in the day, but still hurts your memory usage. You also double set your model by parenting it then using setModel().

            Here is a replacement function for that:

            int JTFTools::ListViewPopulate(QListView *listView, QStringList *stringList)
            {
                int rv = OK;
            
                auto model = qobject_cast<QStringListModel *>(listView->model());
               model->setStringList(*stringList);
            
                return rv;
            }
            

            Oh, and I wouldn't pass by non-const pointer if you don't edit the contents.. so I would change that stringList to const QStringList * or use a reference with const QStringList &. That's just protection for you as a developer and any other coders that come behind you though so not a huge deal. It's just a smart practice to get into.

            Changing that function may fix your problem, but I doubt it, so let me know if you want me to write up a quick example later on.

            cerrC Offline
            cerrC Offline
            cerr
            wrote on last edited by
            #5

            @ambershark
            Oh wow, Thank you very much! Hmm, let's see: I would love I you could provide me with an example whenever you get to it, definitely! Thanks in advance!
            So to the improved ListViewPopulate method you provided:
            I thought I read somewhere that you should delete the old model after you've set the new one... let me see... yeah here, I found it, it says:

            void QAbstractItemView::setModel ( QAbstractItemModel * model ) [virtual]
            Sets the model for the view to present.

            This function will create and set a new selection model, replacing any model that was previously set with setSelectionModel(). However, the old selection model will not be deleted as it may be shared between several views. We recommend that you delete the old selection model if it is no longer required. This is done with the following code:

            QItemSelectionModel *m = view->selectionModel();
            view->setModel(new model);
            delete m;
            

            plus, what you provided doesn't compile for me, I get:

                 auto model = qobject_cast<QStringListModel *>(listView->model());
                      ^
            

            shouldn't model just be of type QStringListModel *? I tried that but now it crashes with a SIGSEGV segmentation fault.

            A 1 Reply Last reply
            0
            • cerrC cerr

              @ambershark
              Oh wow, Thank you very much! Hmm, let's see: I would love I you could provide me with an example whenever you get to it, definitely! Thanks in advance!
              So to the improved ListViewPopulate method you provided:
              I thought I read somewhere that you should delete the old model after you've set the new one... let me see... yeah here, I found it, it says:

              void QAbstractItemView::setModel ( QAbstractItemModel * model ) [virtual]
              Sets the model for the view to present.

              This function will create and set a new selection model, replacing any model that was previously set with setSelectionModel(). However, the old selection model will not be deleted as it may be shared between several views. We recommend that you delete the old selection model if it is no longer required. This is done with the following code:

              QItemSelectionModel *m = view->selectionModel();
              view->setModel(new model);
              delete m;
              

              plus, what you provided doesn't compile for me, I get:

                   auto model = qobject_cast<QStringListModel *>(listView->model());
                        ^
              

              shouldn't model just be of type QStringListModel *? I tried that but now it crashes with a SIGSEGV segmentation fault.

              A Offline
              A Offline
              ambershark
              wrote on last edited by
              #6

              @cerr Sure I'll do an example later tonight or tomorrow.

              So that documentation looks like a copy/paste error. It references setSelectionModel inside a setModel docs. If you set a new model using setModel then yes you should clean your old one.

              Likewise if you set a new selection model using setSelectionModel then you should clean the old selection model.

              Your delete wasn't wrong or anything in your old code, just you mixed up setModel and setSelectionModel. They are 2 very different things. :)

              As for the not compiling, sorry I used c++11 syntax with the auto, yes you can safely change that to QStringListModel *model = .... Or you can add --std=c++11 (assuming gcc compiler) to your build.

              QItemSelectionModel *m = view->selectionModel();
              view->setModel(new model);
              delete m;
              

              You did it again in this code... you are mixing a selectionModel and a data model. Selection models are used to show what is currently selected in your view/model. Data models are used to store the contents of the entire model/view.

              So your crash is coming from you getting the selection model into m and then setting a new regular data model with setModel and then deleting a still in use selection model when you say delete m.

              My L-GPL'd C++ Logger github.com/ambershark-mike/sharklog

              cerrC 1 Reply Last reply
              0
              • A ambershark

                @cerr Sure I'll do an example later tonight or tomorrow.

                So that documentation looks like a copy/paste error. It references setSelectionModel inside a setModel docs. If you set a new model using setModel then yes you should clean your old one.

                Likewise if you set a new selection model using setSelectionModel then you should clean the old selection model.

                Your delete wasn't wrong or anything in your old code, just you mixed up setModel and setSelectionModel. They are 2 very different things. :)

                As for the not compiling, sorry I used c++11 syntax with the auto, yes you can safely change that to QStringListModel *model = .... Or you can add --std=c++11 (assuming gcc compiler) to your build.

                QItemSelectionModel *m = view->selectionModel();
                view->setModel(new model);
                delete m;
                

                You did it again in this code... you are mixing a selectionModel and a data model. Selection models are used to show what is currently selected in your view/model. Data models are used to store the contents of the entire model/view.

                So your crash is coming from you getting the selection model into m and then setting a new regular data model with setModel and then deleting a still in use selection model when you say delete m.

                cerrC Offline
                cerrC Offline
                cerr
                wrote on last edited by
                #7

                @ambershark said in Set background of specific row in QListView:

                QItemSelectionModel *m = view->selectionModel();
                view->setModel(new model);
                delete m;

                You did it again in this code...

                Hehe no, sorry! I just pasted the code braket from the example, it just wouldn't let me quote the code lines....
                Staying tuned and looking forward to seeing your example...
                Thank you!

                A 1 Reply Last reply
                0
                • cerrC cerr

                  @ambershark said in Set background of specific row in QListView:

                  QItemSelectionModel *m = view->selectionModel();
                  view->setModel(new model);
                  delete m;

                  You did it again in this code...

                  Hehe no, sorry! I just pasted the code braket from the example, it just wouldn't let me quote the code lines....
                  Staying tuned and looking forward to seeing your example...
                  Thank you!

                  A Offline
                  A Offline
                  ambershark
                  wrote on last edited by ambershark
                  #8

                  @cerr Ok so by writing the example I figured out your problem. It looks like QStringListModel does not support coloring as part of a data role. You can do it via a delegate but not in the style you are trying to use in your example.

                  Here is a screenshot of my example using a QStandardItemModel:
                  alt text

                  And the code --

                  main.cpp:

                  #include <QApplication>
                  #include "window.h"
                  
                  int main(int ac, char **av)
                  {
                  	QApplication app(ac, av);
                          Window w;
                          w.show();
                  	return app.exec();
                  }
                  

                  window.h:

                  #pragma once
                  
                  #include <QWidget>
                  
                  class QListView;
                  
                  class Window : public QWidget
                  {
                      Q_OBJECT
                  
                  public:
                      Window(QWidget *parent = 0);
                      
                  private:
                      QListView *view_;
                  };
                  

                  window.cpp:

                  #include "window.h"
                  #include <QListView>
                  #include <QVBoxLayout>
                  #include <QStandardItemModel>
                  
                  Window::Window(QWidget *parent)
                      : QWidget(parent)
                  {
                      resize(600,400);
                      
                      // create layout
                      auto layout = new QVBoxLayout();
                      
                      // create view and model
                      view_ = new QListView();
                      auto model = new QStandardItemModel();
                      model->appendRow(new QStandardItem("line 1"));
                      model->appendRow(new QStandardItem("line 2"));
                      model->appendRow(new QStandardItem("line 3"));
                      model->appendRow(new QStandardItem("line 4"));
                      view_->setModel(model);
                      
                      // add view to layout
                      layout->addWidget(view_);
                      setLayout(layout);
                      
                      // set the bg color of row 2
                      model->setData(model->index(1, 0), QBrush(Qt::red), Qt::BackgroundRole);
                  }
                  

                  In case you want to build here's my CMakeLists.txt
                  CMakeLists.txt:

                  cmake_minimum_required(VERSION 3.4)
                  project(rowcolor)
                  
                  find_package(Qt5Gui REQUIRED)
                  
                  set(CMAKE_AUTOMOC ON)
                  
                  include_directories(
                  	src
                  	)
                  
                  set(SRCS
                  	src/main.cpp
                      src/window.cpp
                      )
                  
                  add_executable(${PROJECT_NAME} ${SRCS})
                  qt5_use_modules(${PROJECT_NAME} Core Gui Widgets)
                  

                  I can make a zip of the project if you need it.

                  My L-GPL'd C++ Logger github.com/ambershark-mike/sharklog

                  cerrC 1 Reply Last reply
                  3
                  • A ambershark

                    @cerr Ok so by writing the example I figured out your problem. It looks like QStringListModel does not support coloring as part of a data role. You can do it via a delegate but not in the style you are trying to use in your example.

                    Here is a screenshot of my example using a QStandardItemModel:
                    alt text

                    And the code --

                    main.cpp:

                    #include <QApplication>
                    #include "window.h"
                    
                    int main(int ac, char **av)
                    {
                    	QApplication app(ac, av);
                            Window w;
                            w.show();
                    	return app.exec();
                    }
                    

                    window.h:

                    #pragma once
                    
                    #include <QWidget>
                    
                    class QListView;
                    
                    class Window : public QWidget
                    {
                        Q_OBJECT
                    
                    public:
                        Window(QWidget *parent = 0);
                        
                    private:
                        QListView *view_;
                    };
                    

                    window.cpp:

                    #include "window.h"
                    #include <QListView>
                    #include <QVBoxLayout>
                    #include <QStandardItemModel>
                    
                    Window::Window(QWidget *parent)
                        : QWidget(parent)
                    {
                        resize(600,400);
                        
                        // create layout
                        auto layout = new QVBoxLayout();
                        
                        // create view and model
                        view_ = new QListView();
                        auto model = new QStandardItemModel();
                        model->appendRow(new QStandardItem("line 1"));
                        model->appendRow(new QStandardItem("line 2"));
                        model->appendRow(new QStandardItem("line 3"));
                        model->appendRow(new QStandardItem("line 4"));
                        view_->setModel(model);
                        
                        // add view to layout
                        layout->addWidget(view_);
                        setLayout(layout);
                        
                        // set the bg color of row 2
                        model->setData(model->index(1, 0), QBrush(Qt::red), Qt::BackgroundRole);
                    }
                    

                    In case you want to build here's my CMakeLists.txt
                    CMakeLists.txt:

                    cmake_minimum_required(VERSION 3.4)
                    project(rowcolor)
                    
                    find_package(Qt5Gui REQUIRED)
                    
                    set(CMAKE_AUTOMOC ON)
                    
                    include_directories(
                    	src
                    	)
                    
                    set(SRCS
                    	src/main.cpp
                        src/window.cpp
                        )
                    
                    add_executable(${PROJECT_NAME} ${SRCS})
                    qt5_use_modules(${PROJECT_NAME} Core Gui Widgets)
                    

                    I can make a zip of the project if you need it.

                    cerrC Offline
                    cerrC Offline
                    cerr
                    wrote on last edited by cerr
                    #9

                    @ambershark Hi Ambershark, Excellent, Thank you very much! I appreciate your efforts! I can't copy and duplicate work just yet but I'll get onto it asap! Thank you very much! :D
                    I don't know why but it doesn't let me accept your reply as answer... ? :(
                    Now maybe you can give me another hint: How would I have found out that I need to use a QStandardItemModel instead of QStringListModel as a newbie? Is there a good an easy to oversee index where I can find which features are supported by which components? Or did you "just know" it?

                    A 1 Reply Last reply
                    1
                    • cerrC cerr

                      @ambershark Hi Ambershark, Excellent, Thank you very much! I appreciate your efforts! I can't copy and duplicate work just yet but I'll get onto it asap! Thank you very much! :D
                      I don't know why but it doesn't let me accept your reply as answer... ? :(
                      Now maybe you can give me another hint: How would I have found out that I need to use a QStandardItemModel instead of QStringListModel as a newbie? Is there a good an easy to oversee index where I can find which features are supported by which components? Or did you "just know" it?

                      A Offline
                      A Offline
                      ambershark
                      wrote on last edited by
                      #10

                      @cerr Not really any good docs/resource for that unfortunately. It will just come with time and experience. As for me just knowing, I actually didn't... I implemented it with the QStringListModel and was surprised when it didn't work. That's when I got the idea that it might be the model causing the issue so I used my default model which was the QStandardItemModel, and it worked.

                      So I figured out there was an issue with QStringListModel and honoring data roles. Not a bug, but more of a lack of support. :)

                      You can look up all the models in the Qt Docs though if that helps. And of course you can always create your own custom models.

                      My L-GPL'd C++ Logger github.com/ambershark-mike/sharklog

                      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