首页 文章

QScrollArea:自动滚动到新添加的小部件

提问于
浏览
1

这不是我第一次想要一个行为如下的滚动区域(想象一下日志或聊天窗口,但是使用简单的QTextBrowser太复杂了):

  • 我想添加多个小部件,它们一个在另一个之下(就像放在QVBoxLayout中一样)

  • 此布局中的每个小部件应具有固定大小或高度宽度(如简单标签)

  • 滚动区域应自动滚动到最近添加的滚动区域

  • (可选)当剩余空间(尚未启用滚动条)时,内容应与底部对齐

Using QScrollArea:

我过去的尝试是使用QScrollArea在里面使用QVBoxLayout . 但这似乎并不像我想象的那么简单:每当我向布局添加一个小部件时,布局都不会立即调整滚动区域内容小部件的大小,从而导致内容的延迟调整 . 在短时间内,布局中包含的窗口小部件将调整大小,以使总大小等于添加操作之前的总大小,从而导致每个窗口小部件的大小过小 . 此外,滚动到新添加的窗口小部件是不可能的,直到布局将其大小更正为窗口小部件的新总大小,因此即使是QTimer :: singleShot(0,...)也没有帮助 . 即使超时为20左右,在某些情况下布局也需要更多时间来调整大小 . 这不是确定性的,因此远离一个好的解决方案 .

为了获得底部对齐行为,我最初在布局中放置了一个spacer项 . 只要没有剩余空间并且启用了滚动,它就不需要任何空间 .

Using QListView:

由于我的项目太复杂,它们需要是QWidgets . 他们无法拥有焦点,无法选择,因此基于项目的解决方案似乎只是“错误的方式” . 此外,这个解决方案听起来太“沉重” .

我简直无法相信没有简单的方法,所以我想我还没有看到它!

1 回答

  • 1

    QListView 应该没问题 . 你声称你的物品是静态的,那么's no interaction with them: no focus, no selection. It'似乎对这些物品来说太过分了 . 您只需要具有固定大小并可以绘制自己的东西 . 这正是Qt模型 - 视图系统中的代表所要求的 . 只需为您的项目实现一个或多个 QAbstractItemDelegate ,并为它们将要呈现的数据提供模型的实现 . QAbstractItemView 已经 QAbstractScrollArea 了!

    如果你想在一个委托中绘制HTML,那很容易做到 - 再次,QWidget对于静态显示来说是一种过度杀伤!有一个非常食物的原因,为什么使用QWidget很难“ - API引导您找到正确的解决方案 . 假设你的模型包含每个项目的html,这里是你如何绘制它 . 当然,您可以使用sizeHint,并且应该缓存文本文档,理想情况下将其存储在我认为的模型中 .

    void MyDelegate::paint(QPainter* p, const QStyleOptionViewItem & opt, const QModelIndex & index) const
    {
       QTextDocument doc;
       doc.setHtml(index.data().toString());
       doc.drawContents(p, QRect(QPoint(0,0), sizeHint(opt, index)));
    }
    
    QSize MyDelegate::sizeHint(const QStyleOptionViewItem &, const QModelIndex &) const
    {
       return QSize(100, 200);
    }
    

相关问题