2016-01-27 63 views
2

我正在Qt Designer窗体上用QTreeWidget开发Qt应用程序。用户可以按添加新项目按钮,新项目将以默认名称出现,之后用户必须输入项目名称。QTreeWidget捕获项目编辑完成后没有文本更改

所以这是我的代码:

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

首先我遵循@AlexanderVX的建议和catched事件。在用户以任何方式完成编辑之后,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 
    }); 

    ... 
} 
+0

甚至更​​好。当然,陷害一个事件只会显示“为什么?”但这并不总是回答“如何?” – AlexanderVX

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应用。

相关问题