2011-03-03 145 views
4

問題:我想在視圖中顯示一個簡單的QStringListModel。但是,我希望視圖中的每個項目都是我創建的自定義QWidget。我不明白爲什麼這是一個很難的問題!我已經在互聯網上尋找解決方案,儘管我在這裏和那裏發現了點點滴滴,但沒有一個好的解決方案可以滿足我的所有需求。在Qt視圖中使用QWidget

設立我的模型/視圖的基本代碼:

 

QStringList strings; 
// add some strings to the model 

QStringListModel* model = new QStringListModel(strings); 
QListView* view = new QListView; 

view->setModel(model); 

 

我已經在這樣做無濟於事嘗試過各種嘗試。

嘗試#1

我試着子類新QItemDelegate對象。在這個對象中,我重寫了創建編輯器的方法。我遵循了設置該代表的所有步驟。問題是,當模型填充視圖時,當我需要抓取Qt :: EditRole中的每個項目時,它會抓取模型中的每個項目在Qt :: DisplayRole中。

嘗試#2

我嘗試的另一種方法是子類而QListView,並重寫則setModel方法調用setIndexWidget對於模型中的每個項目。我的代碼看起來是這樣的:

 

void CustomListView::setModel(QAbstractItemModel* model) 
{ 
    QListView::setModel(model); 

    for (int i = 0; i rowCount(); ++i) 
    { 
     QModelIndex index = model->index(i, 0); 

     CustomWidget* widget = new CustomWidget; 
     setIndexWidget(index, widget); 
    } 
} 
 

這個工作,只要在列表視圖中添加我CustomWidget對象的每一行。爲了確保常規模型數據不會在我的CustomWidget對象下方顯示,我也重寫了CustomListView :: paintEvent(QPaintEvent * event),不做任何事情。再次,這工作。

但現在我的主要問題是,當列表顯示時,雖然我的CustomWidgets正確顯示,但列表的背景是純白色。我試着在CustomListView上調用setAutoFillBackground(false),但是什麼也沒做。我希望我的列表視圖具有透明背景。

對此問題的任何反饋意見將大大大大讚賞。我花了很多時間試圖讓這個工作!謝謝!

+1

的塗料代碼因此,關於嘗試#2,我修復了背景問題。在我的CustomListView構造函數中,我調用了viewport() - > setAutoFillBackground(false)。我仍然喜歡這些方法或其他可能適用於這個問題的想法。 – Chris 2011-03-03 19:04:44

+0

我認爲你應該堅持代表。你也應該發佈你的setEditorData()和setModelData()函數的源代碼。 – zkunov 2011-03-03 19:43:38

+0

不幸的是,我不能讓我的列表中的所有項目都處於EditMode中,並使用委託中的createEditor()返回的QWidget。似乎一次只能有一個項目處於該模式。 – Chris 2011-03-03 21:14:53

回答

0

我想我在QStandardItemModel中呈現自定義數據的問題類似。我所做的解決它是創建一個自定義的QStyledItemDelegate。 在createEditor方法,你可以測試:

if(qVariantCanConvert<YourObject>(index.data(Qt::YourRole))) 

然後創建您的編輯器,實際上是你想要的自定義部件。並用您的模型中的數據設置其值。 要定製我的小部件,我使用了像CustomWidget.setStylesheet(「background:blue」);

在委託的繪製方法中,如果您想要使用相同的窗口小部件,您完全可以像編輯器一樣進行繪製。

CustomWidget renderer; 
renderer.setText(index.data(Qt::DisplayRole).toString()); 
renderer.resize(option.rect.size()); 
painter->save(); 
painter->translate(option.rect.topLeft()); 
renderer.render(painter); 
painter->restore(); 

你必須自己處理openPersistentEditor和closePersistentEditor。

希望它會有所幫助。

0

我的建議是堅持使用自定義繪畫的代表。

請參閱Star Delegate Example像這樣,您可以按照自己想要的方式繪製(請參見下文),然後在獲得焦點時使用createEditor進行編輯。

void StarDelegate::paint(QPainter *painter, const QStyleOptionViewItem &option, 
          const QModelIndex &index) const 
{ 
    if (qVariantCanConvert<StarRating>(index.data())) { 
     StarRating starRating = qVariantValue<StarRating>(index.data()); 

     if (option.state & QStyle::State_Selected) 
      painter->fillRect(option.rect, option.palette.highlight()); 

     starRating.paint(painter, option.rect, option.palette, 
          StarRating::ReadOnly); 
    } else { 
     QStyledItemDelegate::paint(painter, option, index); 
    } 
} 

漁獲或欺騙是,你可以畫你的小部件,而無需創建一個編輯器實例或使用drawControl()具有編輯模式你的widget。請參閱this question.