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. QTreeView not displaying values
Qt 6.11 is out! See what's new in the release blog

QTreeView not displaying values

Scheduled Pinned Locked Moved Unsolved General and Desktop
4 Posts 2 Posters 2.2k 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.
  • T Offline
    T Offline
    The newest user
    wrote on last edited by
    #1

    Hello,
    I'm working with a TreeView with my own implementation of the QAbstractItemModel. It's the first time that I'm working with it and I don't really understand what i'm doing wrong. I have 2 problems with my implementation:

    • There is no data in the rows of the TreeView
    • When I expand a node it crashes because of some recursive error that I don't understand

    TreeView when running
    This is the TreeView in my application, there should be text in each of the lines, I have debugged it and the data method from the view model returns text so as far as I know there should be stuff there.

    The error is a stack overflow from the QDataArray, this happens when you press the little expansion arrow in the image above.
    Stack overflow error screenshot

    What am I doing wrong?

    H File:

    class ImageSetViewModel : public QAbstractItemModel
    {
    	struct Set;
    
    	struct Image
    	{
    		int cameraId;
    		QString fileName;
    
    		Set* parent;
    	};
    
    	struct Set
    	{
    		int setId;
    		int row;
    		QString name;
    		QList<Image*>* images = new QList<Image*>();
    	};
    
    	Q_OBJECT
    public:
    	ImageSetViewModel();
    	~ImageSetViewModel();
    
    	int rowCount(const QModelIndex &parent = QModelIndex()) const override;
    	int columnCount(const QModelIndex &parent = QModelIndex()) const override;
    
    	QVariant data(const QModelIndex &index, int role = Qt::DisplayRole) const override;
    	QVariant headerData(int section, Qt::Orientation orientation, int role = Qt::DisplayRole) const override;
    	Qt::ItemFlags flags(const QModelIndex &index) const override;
    	QModelIndex index(int row, int column, const QModelIndex &parent = QModelIndex()) const override;
    	QModelIndex parent(const QModelIndex &index) const override;
    
    	void clear();
    	bool addSet(int, std::string, std::string);
    
    private:
    	bool setExists(int id);
    
    	QList<Set*>* displayData = new QList<Set*>();
    };
    

    Cpp file:

    ImageSetViewModel::ImageSetViewModel()
    {
    }
    
    
    ImageSetViewModel::~ImageSetViewModel()
    {
    }
    
    int ImageSetViewModel::rowCount(const QModelIndex& parent) const
    {
    	if (parent.column() > 0)
    		return 0;
    
    	//amount of items in set
    	if (parent.row() >= 0)
    		return displayData->at(parent.row())->images->size();
    
    	return displayData->size();
    }
    
    int ImageSetViewModel::columnCount(const QModelIndex& parent) const
    {
    	return 2;
    }
    
    QVariant ImageSetViewModel::data(const QModelIndex& index, int role) const
    {
    	if (role == Qt::DisplayRole)
    	{
    		if (typeid(index.internalPointer()) == typeid(Set*))
    		{
    			Set* instance = static_cast<Set*>(index.internalPointer());
    
    			switch (index.column())
    			{
    			case 0:
    				QVariant(instance->images->at(index.row())->fileName);
    			case 1:
    				QVariant(instance->images->at(index.row())->cameraId);
    			default:
    				return QVariant();
    			}
    		}
    
    		switch (index.column())
    		{
    		case 0:
    			QVariant(displayData->at(index.row())->name);
    		case 1:
    			QVariant(displayData->at(index.row())->setId);
    		default:
    			return QVariant();
    		}
    	}
    
    	return QVariant();
    }
    
    QVariant ImageSetViewModel::headerData(int section, Qt::Orientation orientation, int role) const
    {
    	if (role != Qt::DisplayRole) return QVariant();
    	if (orientation != Qt::Horizontal) return QVariant();
    
    	if (section == 1) return "Name";
    	else return "ID";
    }
    
    Qt::ItemFlags ImageSetViewModel::flags(const QModelIndex& index) const
    {
    	return Qt::ItemIsEnabled | Qt::ItemIsSelectable;
    }
    
    QModelIndex ImageSetViewModel::index(int row, int column, const QModelIndex& parent) const
    {
    	if (!hasIndex(row, column, parent))
    		return QModelIndex();
    
    	if (typeid(parent.internalPointer()) == typeid(Set*))
    	{
    		Set* instance = static_cast<Set*>(parent.internalPointer());
    		createIndex(row, column, instance->images->at(row));
    	}
    
    	return createIndex(row, column, displayData->at(row));
    }
    
    QModelIndex ImageSetViewModel::parent(const QModelIndex& index) const
    {
    	if (!index.isValid())
    		return QModelIndex();
    
    	//return image parent (a Set)
    	if (typeid(index.internalPointer()) == typeid(Image*))
    	{
    		Set* instance = static_cast<Image*>(index.internalPointer())->parent;
    		createIndex(instance->row, 0, instance);
    	}
    
    	return QModelIndex();
    }
    
    void ImageSetViewModel::clear()
    {
    	beginResetModel();
    	displayData->clear();
    	endResetModel();
    }
    
    bool ImageSetViewModel::addSet(int id, std::string name, std::string imageJson)
    {
    	if (setExists(id)) return false;
    
    	int rows = rowCount();
    
    	Set* set = new Set();
    	set->setId = id;
    	set->name = QString::fromStdString(name);
    	set->row = rows;
    
    	nlohmann::json data = nlohmann::json::parse(imageJson.c_str());
    	for (int i = 0; i < data.size(); ++i)
    	{
    		Image* img = new Image();
    		img->fileName = QString::fromStdString(data[i]["path"]);
    		img->cameraId = data[i]["id"];
    
    		set->images->append(img);
    	}
    
    	beginInsertRows(QModelIndex(), rows, rows);
    	displayData->append(set);
    	endInsertRows();
    
    	return true;
    }
    
    bool ImageSetViewModel::setExists(int id)
    {
    	for (int i = displayData->size(); i < 0; --i)
    		if (displayData->at(i)->setId == id) return true;
    
    	return false;
    }
    
    1 Reply Last reply
    0
    • VRoninV Offline
      VRoninV Offline
      VRonin
      wrote on last edited by VRonin
      #2

      Introductory remarks:

      • In most (>80%) cases you do not need a custom model, QStandardItemModel works perfectly
      • It's always a good Idea to run custom model through the Model Test

      Now:

      • ImageSetViewModel::rowCount(const QModelIndex& parent) and ImageSetViewModel::columnCount should check parent.isValid()
      • this
      			switch (index.column())
      			{
      			case 0:
      				QVariant(instance->images->at(index.row())->fileName);
      			case 1:
      				QVariant(instance->images->at(index.row())->cameraId);
      			default:
      				return QVariant();
      			}
      

      and this

      		switch (index.column())
      		{
      		case 0:
      			QVariant(displayData->at(index.row())->name);
      		case 1:
      			QVariant(displayData->at(index.row())->setId);
      		default:
      			return QVariant();
      		}
      

      are always equivalent to return QVariant(); you forgot a couple of return

      "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
      1
      • T Offline
        T Offline
        The newest user
        wrote on last edited by The newest user
        #3

        Yes the return thing solves why there were no entries in the fields. Oh I feel so stupid :(

        I wish that the model test that you linked was in more places where people ask questions about QAbstractItemModels that would be super handy.

        Are there any common things that people do which could lead to the recursive error that I'm also having?

        VRoninV 1 Reply Last reply
        0
        • T The newest user

          Yes the return thing solves why there were no entries in the fields. Oh I feel so stupid :(

          I wish that the model test that you linked was in more places where people ask questions about QAbstractItemModels that would be super handy.

          Are there any common things that people do which could lead to the recursive error that I'm also having?

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

          @The-newest-user said in QTreeView not displaying values:

          Are there any common things that people do which could lead to the recursive error that I'm also having?

          A lot. and I mean a lot.
          Since you don't reimplement hasChildren() the rowCount/columnCount not checking for the parent validity might be a problem but it's just a guess.
          Stack trace and a lot of red bull are your friends :)

          "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
          1

          • Login

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