Russian Qt Forum

Qt => Model-View (MV) => Тема начата: kirill от Март 05, 2009, 11:43



Название: QListView как в проводнике виндовс
Отправлено: kirill от Март 05, 2009, 11:43
Привет.

У меня есть QListView у него заданы свойства
Код
C++ (Qt)
  fileListView_->setViewMode(QListView::IconMode);
  fileListView_->setSpacing(10);
  fileListView_->setGridSize(QSize(64, 64));
 
  fileListView_->setFlow(QListView::LeftToRight);
  fileListView_->setWordWrap(true);
 

Выглядит он вот так:
картинка - 1.gif

Как можно видеть имена файлов кастрированы, и при выделении они не показываются.

Я хочу чтобы при выделении показывалось все имя, как это сделано в виндовс проводнике.
картинка - 2.gif


Как такое сделать?
Пытался использовать делегат таким образом:
Код
C++ (Qt)
void KIconsDelegate::paint(QPainter *painter, const QStyleOptionViewItem &option,
                        const QModelIndex &index) const
{
  QStyleOptionViewItem textOption = myOption;
  textOption.rect.setY(iconOption.rect.y() + iconOption.rect.height() - 20);
  textOption.rect.setX(myOption.rect.x() + 8);
 
  if (option.state & QStyle::State_Selected)
  {  
     textOption.rect.setHeight(128);
     painter->fillRect(textOption.rect, textOption.palette.color(cg, QPalette::Highlight));
  }
 
  QItemDelegate::paint(painter, option, index);  
}
 
//--------------------------------------------------------------------------------
 
QSize KIconsDelegate::sizeHint(const QStyleOptionViewItem &option,
                              const QModelIndex &index) const
{
  if (option.state & QStyle::State_Selected)
  {
     return QSize(64, 256);
  }
 
return QSize(64,64);
}
 

В результате использования делегата получил такую картину:
картинка - 3.gif

То есть выделение (прямоугольник) рисуется за итемами. А я хочу чтобо он их перекрывал, как в проводнике.
Если я добьюсь этого (чтобы он перекрывал низлежащие итемы), то уж текст нарисую.

Так вот как мне сделать перекрытие итемов?


Название: Re: QListView как в проводнике виндовс
Отправлено: kirill от Март 05, 2009, 13:53
Что, никто не знает?
Неужели задача такая экзотическая? Имхо каждый 3-й должен был с ней столкнуться.

Ладно, отпишу как решил, кто знает поправьте как правильно сделать (кто нибудь из группы Администраторы ;)))).

Идея такова - чтобы на клик вызывать editor в делегате.

Это чтобы эдитор создавался по 1 клику при выделении.
Код
C++ (Qt)
  fileListView_->setUniformItemSizes(true);
  fileListView_->setEditTriggers(QAbstractItemView::CurrentChanged | QAbstractItemView::SelectedClicked);
 

Это сам эдитор делегата
Код
C++ (Qt)
QWidget *KIconsDelegate::createEditor(QWidget *parent, const QStyleOptionViewItem &option,
                                 const QModelIndex &index) const
{
 QLabel * lbl = new QLabel(parent);
 lbl->setWordWrap(true);
 lbl->setText(index.data().toString());
 lbl->setMinimumHeight(128);
 lbl->setAlignment(Qt::AlignTop | Qt::AlignHCenter);
 lbl->setStyleSheet("background-color: yellow;");
 
 return lbl;
}
 
 

Вот собстна и все. Осталось сделать бэкграунд Highlight, и реализовать механизм вписывания названия файла в label.
Недостатки у этого метода есть.
1) нету фокусных примитивов на label.
2) иконки перестают "плавать" пока открыт редактор.


Название: Re: QListView как в проводнике виндовс
Отправлено: lit-uriy от Март 05, 2009, 16:11
2 Kiril, а что если при щелчке мышью изменять способ сокращения текста, т.е.
enum Qt::TextElideMode (http://doc.crossplatform.ru/qt/4.4.3/qt.html#TextElideMode-enum)
пока невыделено:
Qt::ElideRight
а когда выделено, то:
Qt::ElideNone


Название: Re: QListView как в проводнике виндовс
Отправлено: kirill от Март 06, 2009, 08:16
Юра, я не задаю elide он сам появляется при установке setGridSize().

Окончательный вариант отображения полного имени файла при наведении:

Код
C++ (Qt)
QWidget *KIconsDelegate::createEditor(QWidget *parent, const QStyleOptionViewItem & option,
                                 const QModelIndex &index) const
{
  QLabel * lbl = new QLabel(parent);
  lbl->setAlignment(Qt::AlignTop | Qt::AlignHCenter);
 
  //правильная подсветка
  QPalette p;
  QColor cl;
  cl = p.color(QPalette::Highlight);
  QString sHighlight = cl.name();
  cl = p.color(QPalette::HighlightedText);
  QString sHighlightedText = cl.name();
 
  lbl->setStyleSheet(QString("background-color: %1; color: %2").arg(sHighlight).arg(sHighlightedText));
 
  //вписать текст
  QString sText = index.data().toString();
  QFontMetrics fontMetr(qApp->font());
  QString sRes = "";
  int countLines = 0;
  while (sText.length())
  {
     QString sTemp = fontMetr.elidedText(sText, Qt::ElideRight, option.rect.width());///<  размер итема
     sRes += sTemp;
     int resLen = sTemp.length();
     //здесь узнать есть ли в конце символ elide...
     if (sRes.contains("…"))
     {
        sRes.chop(1);
        //окусить с начала
        sText = sText.mid(resLen-1);
 
        sRes += "<br>";
        countLines++;
     }
     else
        break;
 
  }
 
  lbl->setText(sRes);
  lbl->setMinimumHeight(fontMetr.height()*(countLines+1));
 
  return lbl;
}
 
 

пользуйтесь.