调整QListView的高度以适合内容

时间:2014-09-01 22:11:49

标签: c++ qt qlistview qsizepolicy

我希望基于QListView的{​​{1}}的高度适合内容,如果项目的数量小于给定的数量N.如果有超过N个项目,它应该仅显示N个项目。我在网上看了很多好奇的提示,但大多数都看起来像黑客。我想这与QAbstractListModel有关,但在模型视图方法中没有ItemWidget,我可以在其中覆盖sizeHint()。实现这种行为的正确方法是什么?

此外,这与父应用的大小政策有何关联?这是第二个约束:内容不应该尝试使用它们在父窗口小部件中的空间,但是父窗口小部件应该调整大小以适合sizeHint()

这与[this]不重复,因为我无法使用QListView1 QListView height according to contents

3 个答案:

答案 0 :(得分:1)

必须在QListView(分别是它的子类)中重写

sizeHint()。所提到的特殊行为可以在那里实现。比如这样:

QSize ProposalListView::sizeHint() const
{
    if (model()->rowCount() == 0) return QSize(width(), 0);
    int nToShow = _nItemsToShow < model()->rowCount() ? _nItemsToShow : model()->rowCount();
    return QSize(width(), nToShow*sizeHintForRow(0));
}

这要求项目委托的大小提示是合理的。就我而言:

inline QSize sizeHint ( const QStyleOptionViewItem&, const QModelIndex& ) const  override { return QSize(200, 48); }

现在我只需在更改模型后调用updateGeometry()。

答案 1 :(得分:0)

没有好办法做到这一点。我使用以下代码。

部首:

class List_view_auto_height : public QObject {
  Q_OBJECT
public:
  explicit List_view_auto_height(QListView * target_list);
  void set_max_auto_height(int value);
  void set_min_height(int value);

private:
  QListView* list;
  QTimer timer;
  int _min_height;
  int _max_height;

  bool eventFilter(QObject* object, QEvent* event);

private slots:
  void update_height();
};

来源:

List_view_auto_height::List_view_auto_height(QListView *target_list) :
  QObject(target_list)
, list(target_list)
{
  _min_height = 0;
  _max_height = 250;
  connect(list->model(), &QAbstractItemModel::rowsInserted,
          this, &List_view_auto_height::update_height);
  connect(list->model(), &QAbstractItemModel::rowsRemoved,
          this, &List_view_auto_height::update_height);
  connect(list->model(), &QAbstractItemModel::layoutChanged,
          this, &List_view_auto_height::update_height);
  list->installEventFilter(this);
  update_height();
  connect(&timer, &QTimer::timeout, this, &List_view_auto_height::update_height);
  timer.start(500);
}

void List_view_auto_height::set_max_auto_height(int value) {
  _max_height = value;
  update_height();

}

void List_view_auto_height::set_min_height(int value) {
  _min_height = value;
  update_height();
}

bool List_view_auto_height::eventFilter(QObject *object, QEvent *event) {
  if (event->type() == QEvent::Show) {
    update_height();
  }
  return false;
}

void List_view_auto_height::update_height() {
  if (!list->isVisible()) { return; }
  int height = 0;
  if (list->model()->rowCount() > 0) {
    height = list->visualRect(list->model()->index(list->model()->rowCount() - 1, 0)).bottom() + 1;
    height -= list->visualRect(list->model()->index(0, 0)).top();
  }
  if (list->horizontalScrollBar()->isVisible()) {
    height += list->horizontalScrollBar()->height();
  }
  bool scrollbar_enabled = false;
  if (_max_height != 0 && height > _max_height) {
    height = _max_height;
    scrollbar_enabled = true;
  }
  if (height < _min_height) {
    height = _min_height;
  }
  list->setFixedHeight(height + 6);
}

用法:

new List_widget_auto_height(list);

它充满了黑客攻击,在某些情况下可能无法正常工作。随意改进它。

使用setFixedHeight设置高度。这应该为父窗口小部件的大小提示提供正确的行为。

答案 2 :(得分:0)

对于那些在QML和QtQuick控件中使用ListView的用户。 我将内容设置为属性anchors.bottomMargin。

anchors.bottomMargin: 20