QTreeView无法显示模型

时间:2018-01-13 19:47:08

标签: c++ qt qt4

我正在使用Qt4,我正在尝试使用QTreeView显示模型。我拥有的模型由几个批处理组成,每个批处理都有一些元素,每个元素都有一些子元素(同一批处理元素具有相同数量的子元素,但我不认为这与问题相关)。与此类似:

+
|
+-+ Batch_0
|     +
|     |
|     +-+ Element_0
|     |     +
|     |     |
|     |     +-+ Child_0
|     |     |
|     |     +-+ Child_1
|     |     |
|     |     +-+ Child_2
|     |
|     +-+ Element_1
|     |     +
|     |     |
|     |     +-+ Child_0
|     |     |
|     |     +-+ Child_1
|     |     |
|     |     +-+ Child_2
|     |
|     +-+ Element_2
|           +
|           |
|           +-+ Child_0
|           |
|           +-+ Child_1
|           |
|           +-+ Child_2
|
+-+ Batch_1
      +
      |
      +-+ Element_0
      |     +
      |     |
      |     +-+ Child_0
      |
      +-+ Element_0
            +
            |
            +-+ Child_0

我的小部件是:

class QMainWidget : public QMainWindow
{
    Q_OBJECT

public:
    explicit QMainWidget(QWidget *parent = 0);
    ~QMainWidget();

public slots:

    void load();
    void load2();

private:

    Ui::QMainWidget *ui;

    QDataItemTree* tree_view_model_;

    int n_loaded_;
};

实施:

QMainWidget::QMainWidget(QWidget *parent) :
    QMainWindow(parent),n_loaded_(0),
    ui(new Ui::QMainWidget)
{
    // Set up Ui
    ui->setupUi(this);

    // Data tree
    tree_view_model_ = new QDataItemTree("Root");
    ui->treeView->setModel(tree_view_model_);

    // Connect load
    connect(ui->addElementsLoad_pushButton,SIGNAL(clicked()),this,SLOT(load()));
    connect(ui->addElementsLoad2_pushButton,SIGNAL(clicked()),this,SLOT(load2()));
}

QMainWidget::~QMainWidget()
{
    delete ui;
    delete tree_view_model_;
}

void QMainWidget::load()
{
    // How many elements to add
    int n_elements = QInputDialog::getInt(this,"Elements","How many elemtns?",10);

    // How many childs per element
    int n_childs_per_element = QInputDialog::getInt(this,"Elements","How many elemtns?",10);

    // Add batch to tree
    QDataItem* batch = tree_view_model_->addBatch(n_loaded_);
    for (int i = 0; i < n_elements; i++)
    {
        QDataItem* element = tree_view_model_->addBatchElement(i,batch);
        for (int j = 0; j <= n_childs_per_element; j++)
        {
            tree_view_model_->addBatchElementChild(j,element);

        }
    }
    n_loaded_++;
    ui->treeView->setModel(tree_view_model_);

}

void QMainWidget::load2()
{
    // How many elements to add
    int n_elements = QInputDialog::getInt(this,"Elements","How many elemtns?",10);

    // How many childs per element
    int n_childs_per_element = QInputDialog::getInt(this,"Elements","How many elemtns?",10);

    // Add batch to tree
    tree_view_model_ = new QDataItemTree("Root");
    QDataItem* batch = tree_view_model_->addBatch(n_loaded_);
    for (int i = 0; i < n_elements; i++)
    {
        QDataItem* element = tree_view_model_->addBatchElement(i,batch);
        for (int j = 0; j <= n_childs_per_element; j++)
        {
            tree_view_model_->addBatchElementChild(j,element);

        }
    }
    n_loaded_++;
    ui->treeView->setModel(tree_view_model_);

}

我的问题是,当我尝试向模型添加内容时,只有在我使用函数load2()而不是load()时才会显示它。这两个函数之间的唯一区别是在load2()中我每次调用时都会创建一个新模型,而不是将元素添加到已经设置为树视图模型的模型中(请参阅代码,避免对其进行注释)内存泄漏,我已经知道了)。我不能每次都创建一个新模型,因为我想在现有模型中添加东西,而不是创建一个新模型。

可以找到我想要做的简化版here

我已阅读this教程,以便能够实现我想要的内容。

提前谢谢。

1 个答案:

答案 0 :(得分:1)

问题是因为他们没有通知视图您已添加新元素,因此您必须致电beginInsertRows()endInsertRows(),但为此您需要获取相关的QModelIndex使用QDataItem,为此,我实现了以下方法:

QModelIndex QDataItemTree::indexFromItem(QDataItem *item){
    if(item == rootItem || item == NULL)
        return QModelIndex();
    QDataItem *parent = item->parentItem();

    QList<QDataItem *> parents;

    while (parent && parent!=rootItem) {
        parents<<parent;
        parent = parent->parentItem();
    }
    QModelIndex ix;
    parent = rootItem;
    /*for(auto ch: parents){
        ix = index(ch->row(), 0, ix);
    }*/

    for(int i=0; i < parents.count(); i++){
        ix = index(parents[i]->row(), 0, ix);
    }
    ix = index(ix.row(), 0, ix);
    return ix;
}

然后在添加项目时使用此方法:

QDataItem* QDataItemTree::addBatch(int number)
{
    QString name = "Batch_"+QString::number(number);
    QList<QVariant> d;
    d<<name;
    QDataItem* batch = new QDataItem(d,rootItem);
    beginInsertRows(indexFromItem(rootItem), rootItem->childCount(), rootItem->childCount());
    rootItem->appendChild(batch);
    endInsertRows();
    return batch;
}

QDataItem* QDataItemTree::addBatchElement(int number, QDataItem* parent)
{
    QString name = "Element_"+QString::number(number);
    QList<QVariant> d;
    d<<name;
    QDataItem* element = new QDataItem(d,parent);
    beginInsertRows(indexFromItem(parent), parent->childCount(), parent->childCount());
    parent->appendChild(element);
    endInsertRows();
    return element;
}

QDataItem* QDataItemTree::addBatchElementChild(int number, QDataItem* parent)
{
    QString name = "Child_"+QString::number(number);
    QList<QVariant> d;
    d<<name;
    QDataItem* element_child = new QDataItem(d,parent);
    beginInsertRows(indexFromItem(parent), parent->childCount(), parent->childCount());
    parent->appendChild(element_child);
    endInsertRows();
    return element_child;
}

以下link是完整的代码。

在以下链接中,详细说明了如何创建可编辑模型,不仅包括显示的信息,还包括行和列的创建: