2014-09-01 176 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