2014-09-01 361 views
0

如果项目数量小于给定数量N,我想要基于QAbstractListModelQListView的高度适合内容。如果有多于N个项目,应该只显示N个项目。我在网上阅读了很多好奇的技巧,但其中大部分看起来像黑客。我想这与sizeHint()有关,但在模型视图方法中,没有ItemWidget可以覆盖sizeHint()。什么是实现这种行为的正确方法?调整QListView的高度以适应内容

此外,这与父应用程序的大小策略有什么关系?这是第二个约束:内容不应尝试使用它们在父窗口小部件中的空间,但父窗口小部件应调整大小以适合QListView。我不能使用QCompleter1QListView height according to contents

+0

不要使用'QListView',使用小部件和垂直布局。 – 2014-09-02 08:02:14

+0

我尝试过,但实现起来很乱。由于'UpdatesEnabled()'不能很好地工作(我在某处读取了布局中的变化,例如addwidget()),并且结合最小尺寸策略,这导致我闪烁,因为我基于此更新在用户输入。 – ManuelSchneid3r 2014-09-03 10:31:33

回答

1

sizeHint()必须在QListView(分别是它的子类)中重写。所提到的特殊行为可以在那里实施。例如像这样:

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()。

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设置高度。这应该为父窗口小部件的大小提示提供正确的行为。

+0

谢谢你的回答。我同时找到了解决方案。也许它对你有用。 – ManuelSchneid3r 2014-09-01 22:52:24