QTreeWidget捕获项目编辑完成,没有文本更改

时间:2016-01-27 18:02:38

标签: c++ qt qtreeview qtreewidget qtreewidgetitem

我正在Qt Designer表单上使用QTreeWidget开发一个Qt应用程序。用户可以按添加新项目按钮,新项目将以默认名称显示,之后用户必须输入项目名称。

所以这是我的代码:

void MyFormClass::on_addNewItemButton_clicked()
{
    auto newItem = new QTreeWidgetItem({ _defaultName });
    newItem->setFlags(newItem->flags() | Qt::ItemIsEditable);
    ui->tree->addTopLevelItem(newItem);
    ui->tree->editItem(newItem);
}

在MyFormClass中,我还捕获itemChanged信号,用新创建的项目及其名称进行一些操作:

void MyFormClass::on_tree_itemChanged(QTreeWidgetItem *item, int column)
{
    if (item->text(0).isEmpty()) {
        ...
    } else {
        ...
    }
}

一切正常,除非用户没有改变任何内容,只需按Enter键/左键单击某处。这种情况下QTreeWidget [可能]检查该项目是否实际没有被更改,并且没有发出正确的信号。

所以任何想法我如何创建新项目,然后允许用户立即编辑它,最后捕获任何编辑结果(即默认相同)?也许使用QTreeView会有帮助吗?

Qt 5.4.2,C ++ 11,Linux / Windows平台

奖金问题:为什么Qt设计这种方式?我的意思是,检查项目是否发生变化不是我的事吗?好的,信号叫做itemChanged,但是为什么没有editFinished信号呢?

2 个答案:

答案 0 :(得分:2)

我认为应用该方法的正确范围是QTreeWidget。因此,我们可以通过MyTreeWidget继承QTreeWidget。

 ui->tree = new MyTreeWidget(this); // or how exactly it is initialized

我们的工作领域有一百万个谜团。当事情不能正常工作时,我们可以尝试捕获罪魁祸首,因为我们希望它能够发挥作用。当我在Qt小部件中运行时表现不像我期望的那样,我追踪它的作用:

bool MyTreeWidget::event(QEvent* pEvent)
{
    qDebug() << pEvent;
    // parent class method call
    return QTreeWidget::event(pEvent);
}

然后根据特定情况记录日志,我或者尝试重载特定事件(更好更安全),或者在重载的通用事件处理程序中立即执行:

bool MyTreeWidget::event(QEvent* pEvent)
{
    // suppose this to be a 'culprit' event
    if (pEvent->type() == QEvent::WindowDeactivate)
        doTheRightThingHere(); // what expected to be done

    // parent class method call
    return QTreeWidget::event(pEvent);
}

Event Filter可以采用相同的方法。

答案 1 :(得分:2)

首先,我遵循了@AlexanderVX的建议并抓住了事件。用户以任何方式完成编辑后,QEvent :: ChildRemoved将在所有情况下出现。我写了一些代码来捕获这个事件结束处理它。

但是经过几天的研究,我已经学会了一些关于项目代表的信息,这些信息可以处理用户编辑,所以这是我的解决方案:

class MyEditingDelegate : public QItemDelegate
{
    Q_OBJECT

public:
    MyEditingDelegate(QObject *parent = nullptr) : QItemDelegate(parent) {}
    virtual void setModelData(QWidget *editor, 
                              QAbstractItemModel *model, 
                              const QModelIndex &index) const
    {
        QItemDelegate::setModelData(editor, model, index);
        if (index.column() == 0) {
            emit editingFinished(index);
        }
    }

signals:
    void editingFinished(const QModelIndex &) const;
};

class MyTreeWidget : public QTreeWidget
{
public:
    MyTreeWidget(QWidget *parent = nullptr) : QTreeWidget(parent) {}
    QTreeWidgetItem *getItemFromIndex(const QModelIndex &index) const 
    {
        return itemFromIndex(index);
    }
};

MyFormClass::MyFormClass()
{
    ...

    auto editDelegate = new MyEditingDelegate(this);
    ui->tree->setItemDelegate(editDelegate);
    connect(editDelegate, 
            &MyEditingDelegate::editingFinished, 
            [this] (const QModelIndex &index) {
        auto item = ui->tree->getItemFromIndex(index);
        onItemEditingFinished(item); // this is my handler
    });

    ...
}