QTreeView 不显示模型
QTreeView not displaying model
我正在使用 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 教程,能够实现我想要的。
问题是因为他们没有通知视图您添加了新元素,为此您必须调用 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是完整代码
下面link详细说明了如何创建可编辑模型,不仅在显示的信息中,而且在行和列的创建中:
我正在使用 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 教程,能够实现我想要的。
问题是因为他们没有通知视图您添加了新元素,为此您必须调用 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是完整代码
下面link详细说明了如何创建可编辑模型,不仅在显示的信息中,而且在行和列的创建中: