2013-11-15 104 views
4

我根據動態數據添加到QTableView中

http://harmattan-dev.nokia.com/docs/library/html/qt4/itemviews-addressbook.html

class MyModel : public QAbstractTableModel { 
    Q_OBJECT 
public: 
    QList<QPair<string, int> > data_; 
.... 

怎麼行動態添加到模型編寫一個簡單的TableView? data_.insert(..)不會改變的觀點,目前我寫一個函數來添加新行:

void my_append_data(const string& first, int second) { 
    int row = rowCount(QModelIndex()); 
    insertRow(row); // insert a empty row 
    // fill the row 
    setData(createIndex(row, 0), QVariant::fromValue<string>(first), Qt::EditRole); 
    setData(createIndex(row, 1), QVariant::fromValue<int>(second), Qt::EditRole); 
} 
// usage 
model.my_append_data("11111", 111); 
model.my_append_data("22222", 222); 

這似乎效率不高的原因使用setData調用兩次當追加一排,因爲這裏有兩種專欄,未來可能會有更多專欄。

任何更好的方式來追加行?

謝謝。

回答

6

我不知道爲什麼你認爲它效率低下。但是你可以簡化它

我可能會寫你的功能就是這樣,這將使它更未來的反變爲列數和類型的證明:

void my_append_data(const QVariantList &data) { 
    insertRow(rowCount(QModelIndex())); 

    foreach(const QVariant &item, data) { 
     setData(createIndex(row, 0), item, Qt::EditRole); 
    } 
} 

用法:

model.my_append_data(QVariantList() << "11111" << 111); 

基本的(也是最Qt的類型)可以隱式轉換爲QVariant s,所以不需要調用QVariant::fromValue()

另外,如果您使用的是Qt,那麼您將不會正式使用QString s,而不是std::string s。

+0

這很好,謝謝克里斯。 – aj3423

+0

我不明白爲什麼這段代碼比有問題的代碼更好,我會說它更糟糕。海事組織我的答案好多了。 –

3

你的代碼很奇怪!當您繼承QAbstractTableModel並對數據進行一些操作(在您的data_上)時,您只需發出適當的信號(或者調用一些受保護的方法來執行此類信號發射),以通知視圖模型中的某些內容發生了變化!

所以你的情況應該是像這樣的:

void my_append_data(const string& first, int second) { 
    int newRow = data_.count(); 
    beginInsertRows(QModelIndex(), newRow, newRow); 
    data_.append(QPair<string, int>(first, second)); 
    endInsertRows(); 
} 

如果模型的其他部分都正確寫入它應該很好地工作。

用其他答案編寫的代碼只是使用API​​來設計視圖來使用模型。這造成不必要的開銷。

+0

我有一個問題,假設 - 1.我有一個調用MyModelClass派生QAbstrackTableModel。 2.我的視圖數據源被創建,修改,添加,刪除MyModelClass之外。 MyModelClass只包含這個數據源的指針/引用。 3.現在,我如何在dataSource和View之間保持同步? 'data_.append(QPair (first,second)); ' 我不能這樣做,導致修改發生在另一個類 – sami1592

+0

模型是一個代理對象的實際數據。因此,如果數據由某些外部代碼修改,則此代碼應提供一些通知機制,您應該使用該通知機制來發送數據模型的更新。這取決於你的問題的細節。 –