2011-08-01 78 views
3

我有一個非常簡單的QListWidget對象,我想構建一個文件夾列表。 當我將項目添加到我的名單這裏是我做的:Qt QListWidgetItem多行

void LessCC::on_addFolderButton_clicked() 
{ 
    QString dirName = QFileDialog::getExistingDirectory(this, tr("Choose Directory"), QDir::homePath(), QFileDialog::ShowDirsOnly); 
    QListWidgetItem* newItem = new QListWidgetItem(QIcon(":/resources/icons/folder.png"), dirName, 0, 0); 
    this->ui->folderListWidget->addItem(newItem); 
} 

這是工作,但我希望我的項目有多條線路或信息的列(具有不同的風格)。

我聽說QStyledItemDelegate 我真的不明白它是如何工作的,因爲所有其他解決方案我發現,似乎對於這樣簡單(?)事情非常複雜。

這是只有的解決方案,或者有更簡單的東西,我沒有看到?

希望有人能幫助我。

回答

10

如果沒有確切地看到你想要的清單項目是什麼樣子,但建議「最佳」解決方案有點困難,但我們會試一試。

Qt線程here上有一個很棒的帖子,最後給出了他們使用的所有代碼來創建一個類似於他們在頂部顯示的列表的代碼。

基本上,每個項目都有一個大圖標,右側有一個標題和說明文字,每個都有不同的風格。

創建一個自定義委託聽起來很可怕,但它基本上只是爲列表提供一個自定義的小部件。它的工作原理就像一個模板。您可以定義您希望列表項目的外觀,並使用列表中的數據繪製它。你只能從QAbstractItemDelegate繼承。

#include <QPainter> 
#include <QAbstractItemDelegate> 

class ListDelegate : public QAbstractItemDelegate 
{ 
    public: 
     ListDelegate(QObject *parent = 0); 

     void paint (QPainter * painter, const QStyleOptionViewItem & option, const QModelIndex & index) const; 
     QSize sizeHint (const QStyleOptionViewItem & option, const QModelIndex & index) const; 

     virtual ~ListDelegate(); 
}; 

最大的工作是編寫繪圖函數。我將在這裏展示基礎知識,但您可以參考上面的鏈接獲取更長的示例。

ListDelegate::ListDelegate(QObject *parent) 
: QAbstractItemDelegate(parent) 
{ 

} 

void ListDelegate::paint (QPainter * painter, const QStyleOptionViewItem & option, const QModelIndex & index) const 
{ 
     QRect r = option.rect; 

     QPen fontPen(QColor::fromRgb(51,51,51), 1, Qt::SolidLine); 

     if(option.state & QStyle::State_Selected) 
      { 
      painter->setBrush(Qt::cyan); 
      painter->drawRect(r); 

     } 
      else 
      { 
      //BACKGROUND ALTERNATING COLORS 
      painter->setBrush((index.row() % 2) ? Qt::white : QColor(252,252,252)); 
      painter->drawRect(r); 
     } 

      painter->setPen(fontPen); 

     //GET TITLE, DESCRIPTION AND ICON 
     QIcon ic = QIcon(qvariant_cast<QPixmap>(index.data(Qt::DecorationRole))); 
     QString title = index.data(Qt::DisplayRole).toString(); 
     QString description = index.data(Qt::UserRole).toString(); 

     int imageSpace = 10; 
     if (!ic.isNull()) 
      { 
      //ICON 
      r = option.rect.adjusted(5, 10, -10, -10); 
      ic.paint(painter, r, Qt::AlignVCenter|Qt::AlignLeft); 
      imageSpace = 55; 
     } 

     //TITLE 
     r = option.rect.adjusted(imageSpace, 0, -10, -30); 
     painter->setFont(QFont("Lucida Grande", 6, QFont::Normal)); 
     painter->drawText(r.left(), r.top(), r.width(), r.height(), Qt::AlignBottom|Qt::AlignLeft, title, &r); 

     //DESCRIPTION 
     r = option.rect.adjusted(imageSpace, 30, -10, 0); 
     painter->setFont(QFont("Lucida Grande", 5, QFont::Normal)); 
     painter->drawText(r.left(), r.top(), r.width(), r.height(), Qt::AlignLeft, description, &r); 

} 

QSize ListDelegate::sizeHint (const QStyleOptionViewItem & option, const QModelIndex & index) const 
{ 
    return QSize(200, 60); // very dumb value 
} 

ListDelegate::~ListDelegate() 
{ 

} 

因此,您可以在此代碼中看到我們從列表中獲取三位數據。圖標,標題和說明。然後我們正在顯示繪製圖標,並繪製兩個文本字符串我們喜歡。但重要的是獲取數據本身。我們基本上要求清單使用傳遞給我們的「索引」向我們提供數據。

QIcon ic = QIcon(qvariant_cast<QPixmap>(index.data(Qt::DecorationRole))); 
QString title = index.data(Qt::DisplayRole).toString(); 
QString description = index.data(Qt::UserRole + 1).toString(); 

你會注意到,每一點信息都是使用不同的「角色」來檢索的。通常,列表只有一個顯示的內容 - 可以通過DisplayRole訪問。圖標存儲在DecorationRole中。但是如果你想存儲更多的東西,那麼你就開始使用UserRole。您可以使用UserRole,UserRole +1,UserRole +2等存儲一整套東西......

那麼您如何將所有這些信息存儲在每個項目中。容易...

QListWidgetItem *item = new QListWidgetItem(); 
item->setData(Qt::DisplayRole, "Title"); 
item->setData(Qt::UserRole, "Description"); 
myListWidget->addItem(item); 

最後,你如何讓列表顯示使用你的幻想新委託的項目?

myListWidget->setItemDelegate(new ListDelegate(myListWidget)); 

希望能澄清一些事情。

+0

今晚我會嘗試一下,非常感謝你的時間和你的迴應的清晰度。 – wnkz

+0

再次感謝您的回覆。我已經嘗試過了,但是我仍然遇到了一個問題,C++相關的'未定義符號',也許你可以看看[github](https://github.com/wnkz/LessCC)上的代碼嗎? – wnkz

+0

什麼是錯誤? – Liz