Custom Widget in QListView/QTreeView expands whole width
-
Hello.
I have tried to implement custom model based on
QStandadItemModelto store pointers to custom widgets and display this widgets inQListViewandQTreeView. The example code could be found on GitHub.This works almost perfectly except two things:
- In QListView I'd like to represent static view of widget. So I have tried to use
Qt::DecorationRolebut it not use my style defined in QSS file. Code snippet:setIconSize(QSize(200, 200)); ... auto w = new Widget; ... m_model->setData(index, QIcon(w->grab()), Qt::DecorationRole); - In QTreeView I'd like to represent the real widget. But it expands the whole width of QTreeView widget. Code snippet:
void TreeWidget::dataChanged(const QModelIndex &topLeft, ... auto expr = m_model->data(topLeft).value<Widget*>(); setIndexWidget(topLeft, expr);
To prevent expanding I have tried to set some size policy and size hint:
Widget::Widget(QString text, QWidget *parent) : QFrame(parent) { ... setBaseSize(sizeHint()); setSizeIncrement(QSize(1, 1)); setSizePolicy(QSizePolicy::Fixed, QSizePolicy::Fixed); } QSize Widget::sizeHint() const { return QSize(80, 80); }Any advice and suggestions will be greatly appreciated. Thank you very much.
- In QListView I'd like to represent static view of widget. So I have tried to use
-
Hello.
I have tried to implement custom model based on
QStandadItemModelto store pointers to custom widgets and display this widgets inQListViewandQTreeView. The example code could be found on GitHub.This works almost perfectly except two things:
- In QListView I'd like to represent static view of widget. So I have tried to use
Qt::DecorationRolebut it not use my style defined in QSS file. Code snippet:setIconSize(QSize(200, 200)); ... auto w = new Widget; ... m_model->setData(index, QIcon(w->grab()), Qt::DecorationRole); - In QTreeView I'd like to represent the real widget. But it expands the whole width of QTreeView widget. Code snippet:
void TreeWidget::dataChanged(const QModelIndex &topLeft, ... auto expr = m_model->data(topLeft).value<Widget*>(); setIndexWidget(topLeft, expr);
To prevent expanding I have tried to set some size policy and size hint:
Widget::Widget(QString text, QWidget *parent) : QFrame(parent) { ... setBaseSize(sizeHint()); setSizeIncrement(QSize(1, 1)); setSizePolicy(QSizePolicy::Fixed, QSizePolicy::Fixed); } QSize Widget::sizeHint() const { return QSize(80, 80); }Any advice and suggestions will be greatly appreciated. Thank you very much.
I have found first part of solution.
Based on star delegate example I've added my own delegate like this:
QWidget *Delegate::createEditor(QWidget *parent, const QStyleOptionViewItem &option, const QModelIndex &index) const { Q_UNUSED(parent); Q_UNUSED(option); Q_UNUSED(index); return nullptr; } void Delegate::paint(QPainter *painter, const QStyleOptionViewItem &option, const QModelIndex &index) const { if (index.data().canConvert<Widget*>()) { auto w = qvariant_cast<Widget*>(index.data()); w->paint(painter, option.rect); } else QStyledItemDelegate::paint(painter, option, index); } QSize Delegate::sizeHint(const QStyleOptionViewItem &option, const QModelIndex &index) const { if (index.data().canConvert<Widget*>()) return qvariant_cast<Widget*>(index.data())->sizeHint(); else return QStyledItemDelegate::sizeHint(option, index); }The implementation of `Widget::paint`` method is:
void Widget::paint(QPainter *painter, const QRect &rect) { painter->save(); painter->translate(rect.x(), rect.y()); render(painter); painter->restore(); } - In QListView I'd like to represent static view of widget. So I have tried to use
-
I have updated my delegate to show widget in parent view.
To achieve this I have changed the implementation of
Delegate::paint()method like this:if (!index.data().canConvert<Widget*>()) return; QAbstractItemView *p = dynamic_cast<QAbstractItemView*>(parent()); if (p) { auto w = qvariant_cast<Widget*>(index.data()); w->setParent(p); w->paint(painter, option.rect, m_enabled); } else qDebug() << "FATAL: Delegate's parent is not a QAbstractItemView subclass:" << parent();I have also changed
Widget::paint()like this:void Widget::paint(QPainter *painter, const QRect &rect, bool enabled) { painter->save(); move(rect.topLeft()); setEnabled(enabled); show(); painter->restore(); }But I have one more issue with this code. I can't move widgets between views by pressing on them. I have to press an area next to widget to start dragging. How to avoid this?