2011-08-01 3 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

목록 항목을 원하는대로 표시하지 않고 "최상의"솔루션을 제안하는 것은 약간 어렵지만 Google에서 시도해 보겠습니다.

사실 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() 
{ 

} 

이 코드에서 우리는 목록에서 3 비트의 데이터를 얻고 있습니다. 아이콘, 제목 및 설명. 그런 다음 아이콘 그리기를 표시하고 우리가 좋아하는 두 개의 텍스트 문자열을 그립니다. 그러나 중요한 부분은 데이터 자체를 가져 오는 것입니다. 우리는 기본적으로 우리에게 전달 된 "색인"을 사용하여 데이터를 제공하도록 목록에 요청하고 있습니다.

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