Russian Qt Forum
Декабрь 20, 2024, 20:43 *
Добро пожаловать, Гость. Пожалуйста, войдите или зарегистрируйтесь.
Вам не пришло письмо с кодом активации?

Войти
 
  Начало   Форум  WIKI (Вики)FAQ Помощь Поиск Войти Регистрация  

Страниц: [1]   Вниз
  Печать  
Автор Тема: Resize у QListView  (Прочитано 4815 раз)
Tapak
Гость
« : Январь 29, 2009, 01:59 »

Написал небольшой виджет (QPopup) на основе QListView с использованием QItemDelegate для самостоятельной отрисовки. Хотелось бы, чтобы ширина виджета зависела от ширины элементов. Однако sizeHint делегата на виджет никак не влияет. Есть ли выход?

Код
C++ (Qt)
struct QCountry
{
 QCountry (const QString & n, const QPixmap & i) : name (n), image (i), selected (false) {};
 QCountry() {}; // QVariant (metaType) compatible
 QCountry (const QString & n) : name (n) {}; // implicit ctor - convenient for indexOf
 bool operator == (const QCountry & c) const // indexOf comparator
 { return name.compare (c.name, Qt::CaseInsensitive) == 0;
 }
 
 QString  name;
 QPixmap  image;
 bool     selected;
};
 
typedef QList <QCountry> QCountryList;
 
class QPopup : public QListView
{
class QDelegate : public QItemDelegate
{
 public:
 QDelegate (QObject * parent) : QItemDelegate (parent) {};
 void paint (QPainter *, const QStyleOptionViewItem &, const QModelIndex &) const;
 QSize sizeHint (const QStyleOptionViewItem &, const QModelIndex &) const;
 const static int _margin = 4;
};
 
class QListModel : public QAbstractListModel
{
 public:
 QListModel (QObject * parent, QCountryList & list) : QAbstractListModel (parent),
                                                      _list (list) {};
 int rowCount (const QModelIndex & parent = QModelIndex()) const {return _list.size();}
 QVariant data (const QModelIndex & id, int /*role*/) const
 { return QVariant::fromValue (_list[id.row()]);
 }
 private:
 QCountryList & _list;
};
 
 public:
 QPopup (QCountryView * parent, QCountryList & list);
 
 private:
 bool event (QEvent *);
 QSize sizeHint() const {return QSize (140, 0);} // TEMP
};
 
...
 
QCountryView::QPopup::QPopup (QCountryView * parent, QCountryList & list) : QListView (parent)
{
 setWindowFlags (Qt::Popup);
 setSizePolicy (QSizePolicy::Fixed, QSizePolicy::Expanding);
 setModel (new QListModel (this, list));
 setItemDelegate (new QDelegate (this));
 connect (this,
          SIGNAL (clicked (const QModelIndex &)),
          parent,
          SLOT (onPopupClick (const QModelIndex &)));
}
 
void QCountryView::QPopup::QDelegate::paint (QPainter * painter,
                                            const QStyleOptionViewItem & option,
                                            const QModelIndex & index) const
{
 if(index.data().canConvert <QCountry> ())
 { QCountry country = index.data().value <QCountry> ();
   QRect rect = option.rect;
   QPoint imgPos = rect.topLeft() + QPoint (_margin, (rect.height() - country.image.height())/2);
   painter->drawPixmap (imgPos, country.image);
   rect.setLeft (rect.left() + country.image.width() + _margin * 2);
   painter->setPen (country.selected ? Qt::black : Qt::lightGray);
   painter->drawText (rect.adjusted (0, 1, 0, 0), Qt::AlignLeft, country.name);
 }
}
 
QSize QCountryView::QPopup::QDelegate::sizeHint (const QStyleOptionViewItem & option,
                                                const QModelIndex & index) const
{
 if(index.data().canConvert <QCountry> ())
 { QCountry country = index.data().value <QCountry> ();
   QFontMetrics fm (option.font);
   int height = country.image.height() + 5;
   int width = fm.width (country.name) + country.image.width() + _margin * 3;
   return QSize (width, height);
 }
 return QSize();
}
 
Записан
kirill
Гость
« Ответ #1 : Январь 29, 2009, 09:03 »

sizeHint делегата влияет на делегат-эдитор.
Попробуй QWidget::sizeHint()
или
QWidget::setSizePolicy();
Записан
lit-uriy
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 3880


Просмотр профиля WWW
« Ответ #2 : Январь 29, 2009, 09:35 »

>Однако sizeHint делегата на виджет никак не влияет.
И это правильно, ведь один из элементов может оказаться, в общем случае, много длинее других.
Можно использовать вариант, который предложил kirill.
Можно дать пользователю возможность изменять размер спискового представления, по аналогии с примером
Записан

Юра.
Tapak
Гость
« Ответ #3 : Январь 29, 2009, 13:30 »

Цитировать
Попробуй QWidget::sizeHint()
Сейчас именно так и делаю.
setCornerWidget не хотел бы использовать.

Цитировать
И это правильно, ведь один из элементов может оказаться, в общем случае, много длинее других.
Но иногда нужно именно такое поведение. Чтобы виджет подстраивался под размер элементов.
Записан
Страниц: [1]   Вверх
  Печать  
 
Перейти в:  


Страница сгенерирована за 0.145 секунд. Запросов: 23.