Qt itemChanged 信号与 QTreeView 模型仅适用于第一级项目

Met*_*ir3 4 c++ qt qtreeview qstandarditem

我不知道我的qt代码是否做错了什么。我只需要在itemChanged每次项目数据更改时发出该信号。我使用以下代码来制作模型:

QStandardItemModel* model = new QStandardItemModel;
QStandardItem *parentItem = model->invisibleRootItem();
QList<QStandardItem*> itemList1;
QList<QStandardItem*> itemList2;
QList<QStandardItem*> itemList3;
QStandardItem* item1;
QStandardItem* item2;
QStandardItem* item3;

for (int i = 0; i < 3; ++i)
{
    item1 = new QStandardItem;
    item1->setText("item1-" + QString::number(i));

    for (int i = 0; i < 3; ++i)
    {
        item2 = new QStandardItem;
        item2->setText("item2-" + QString::number(i));

        for (int i = 0; i < 3; ++i)
        {
            item3 = new QStandardItem;
            item3->setText("item3-" + QString::number(i));
            itemList3 << item3;
        }
        item2->appendRows(itemList3);
        itemList3.clear();
        itemList2 << item2;
    }
    item1->appendRows(itemList2);
    itemList2.clear();
    itemList1 << item1;
}
parentItem->appendRows(itemList1);
itemList1.clear();

ui.treeView->setModel(model);

QObject::connect(model, SIGNAL(itemChanged(QStandardItem*)), this, SLOT(onChanged(QStandardItem*)));
Run Code Online (Sandbox Code Playgroud)

我想要,onChanged每次更改项目时都会调用它 - 例如,编辑项目文本或单击复选框。但在每种情况下,我itemChanged只在“item1-...”级别项目(第一级别项目)上触发信号,而不是在 item2/3 级别项目上触发信号。为什么?我怎样才能使它正确?

PS:与 QTreeWidget 相同的代码工作得很好,但我在我的应用程序中使用了多线程,我需要划分模型和视图。QTreeWidget 项不能在非 gui 线程中创建,qtreewidget 不能使用自创建模型。这就是我必须将 QTreeView 与 QStandardItem 一起使用的原因。

Kar*_*oop 5

我刚刚调试了一下情况,你没有得到信号的原因如下: 当item的数据发生变化时,你在Qt源中有这个:

void QStandardItem::setData(...)
{
   /* ... */
   if (d->model)
       d->model->d_func()->itemChanged(this);
}
Run Code Online (Sandbox Code Playgroud)

另一方面,将子项添加到父项时,您有

bool QStandardItemPrivate::insertRows(int row, const QList<QStandardItem*> &items)
{
   /* ... */
   for (int i = 0; i < items.count(); ++i) {
     /* ... */
       item->d_func()->model = model;
   }
}
Run Code Online (Sandbox Code Playgroud)

所以这意味着,items 需要一个指向模型的指针来通知模型有关更改的信息,并且子项的模型在插入时设置为父项。现在您首先将子项添加到父项,然后将父项添加到其父项,隐形根作为级别 1 项的父项。由于隐形根有模型,1级项目发送信号,但其他项目没有。

一个简单的更改即可解决此问题:只需先将项目添加到其父项,然后附加子项,如下所示:

for (int i = 0; i < 3; ++i)
{
    item1 = new QStandardItem;
    item1->setText("item1-" + QString::number(i));
    parentItem->appendRow(item1);

    for (int i = 0; i < 3; ++i)
    {
        item2 = new QStandardItem;
        item2->setText("item2-" + QString::number(i));
        item1->appendRow(item2);

        for (int i = 0; i < 3; ++i)
        {
            item3 = new QStandardItem;
            item3->setText("item3-" + QString::number(i));
            item2->appendRow(item3);
        }
    }
}
Run Code Online (Sandbox Code Playgroud)