2011-03-03 5 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에서 모델의 각 항목을 가져 오는 것입니다.

내가 시도하는 또 다른 방법은 QListView를 서브 클래스 및 모델의 각 항목에 대한 setIndexWidget를 호출로 setModel 메소드를 오버라이드 (override)하는 것이었다 2

시도 번호. 내 코드는 다음과 같이 보입니다.

 

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

+0

나는 당신이 대의원들에게 충실해야한다고 생각합니다. 또한 setEditorData() 및 setModelData() 함수의 소스를 게시해야합니다. – zkunov

+0

불행히도 목록의 모든 항목을 EditMode에두고 위임자의 createEditor()에서 반환 한 QWidget을 사용할 수는 없습니다. 한 번에 하나의 항목 만 해당 모드에있을 수 있습니다. – Chris

답변

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()를 사용하여 편집 모드에 위젯을하지 않고 위젯을 그릴 수 있다는 것입니다 속임수. this question.