You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

基于QAbstractItemModel的自定义模型无法正常工作的原因?

Qt QTreeView自定义模型显示问题分析

问题场景

我创建了一个基于QAbstractItemModel的自定义树模型,期望显示2行3列的"111"数据,但实际仅显示表头;若修改headerData函数,移除orientation == Qt::Horizontal和role == Qt::DisplayRole的判断后,界面完全无任何显示(包括表头)。

头文件(mainwindow.h)

//mainwindow.h
#ifndef MAINWINDOW_H
#define MAINWINDOW_H

#include <QAbstractItemModel>
#include <QTreeView>
#include <QVBoxLayout>
#include <QMainWindow>

namespace Ui {
class MainWindow;
}

class MyTreeModel : public QAbstractItemModel
{
    Q_OBJECT
public:
    MyTreeModel(QObject *parent=NULL);

    QModelIndex parent(const QModelIndex &index) const;
    QModelIndex index(int row, int column,const QModelIndex &parent = QModelIndex()) const;
    int rowCount(const QModelIndex &parent) const;
    int columnCount(const QModelIndex &parent = QModelIndex()) const;
    QVariant data(const QModelIndex &index, int role) const;

    QVariant headerData(int section, Qt::Orientation orientation,int role = Qt::DisplayRole) const;
};

class MainWindow : public QMainWindow
{
    Q_OBJECT
public:
    explicit MainWindow(QWidget *parent = 0);
    ~MainWindow();

    QTreeView * view;
    MyTreeModel *model;

private:
    Ui::MainWindow *ui;
    QVBoxLayout * layout;
};

#endif // MAINWINDOW_H

源文件(mainwindow.cpp)

//mainwindow.cpp
#include "mainwindow.h"
#include "ui_mainwindow.h"
#include <QMessageBox>

QModelIndex MyTreeModel::parent(const QModelIndex &index) const
{
    return QModelIndex();
}

QVariant MyTreeModel::data(const QModelIndex &index, int role) const
{
    return "111";
}

QVariant MyTreeModel::headerData(int section, Qt::Orientation orientation,
                               int role) const
{
    if (orientation == Qt::Horizontal && role == Qt::DisplayRole)
    {
        if(section==0)
            return "Column0";
        else if(section==1)
            return "Column1";
        else if(section==2)
            return "Column2";
        else
            return QVariant();
    }
    else
        return QVariant();
}

QModelIndex MyTreeModel::index(int row, int column, const QModelIndex &parent)
            const
{
    return createIndex(row, column, NULL);
}

int MyTreeModel::columnCount(const QModelIndex &parent) const
{
    return 3;
}

int MyTreeModel::rowCount(const QModelIndex &parent) const
{
    return 2;
}

MainWindow::MainWindow(QWidget *parent) :
    QMainWindow(parent),
    ui(new Ui::MainWindow)
{
    ui->setupUi(this);

    model=new MyTreeModel();
    view= new QTreeView(this);
    view->setModel(model);

    layout= new QVBoxLayout(this);
    layout->addWidget(view);
    QWidget *window = new QWidget();
    window->setLayout(layout);
    setCentralWidget(window);
}

MainWindow::~MainWindow()
{
    delete ui;
}

问题原因及解决方案

1. 仅显示表头、无数据内容的原因

data函数未对请求的**角色(role)**做过滤,直接返回字符串"111"。Qt视图会针对多种角色请求数据(如Qt::SizeHintRole、Qt::TextAlignmentRole等),如果所有角色都返回字符串,视图无法正确解析数据,导致内容不渲染。

修复方案:仅在role == Qt::DisplayRole(文本显示角色)时返回数据,其他角色返回空QVariant:

QVariant MyTreeModel::data(const QModelIndex &index, int role) const
{
    if (role == Qt::DisplayRole) {
        return "111";
    }
    return QVariant();
}

2. 修改headerData后无任何显示的原因

修改后的headerData函数移除了orientation和role的判断:

  • 视图会向垂直表头(Qt::Vertical)和其他非显示角色请求数据,此时返回字符串会干扰视图的布局逻辑。
  • 非Qt::DisplayRole角色返回非空值,会导致视图无法识别有效表头数据,最终隐藏表头甚至影响整个视图渲染。

修复方案:必须保留orientation == Qt::Horizontal和role == Qt::DisplayRole的判断,确保仅在水平表头的显示角色请求时返回文本:

QVariant MyTreeModel::headerData(int section, Qt::Orientation orientation,
                               int role) const
{
    if (orientation == Qt::Horizontal && role == Qt::DisplayRole)
    {
        if(section==0)
            return "Column0";
        else if(section==1)
            return "Column1";
        else if(section==2)
            return "Column2";
        else
            return QVariant();
    }
    else
        return QVariant();
}

额外提示

当前parent函数始终返回空QModelIndex,意味着所有行都是顶层根节点。如果需要实现树形层级结构,需正确实现parent函数,返回对应节点的父索引。

内容的提问来源于stack exchange,提问作者William

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.21 10:34:50