2016-01-27 62 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應用。

相關問題