2012-05-08 155 views
1

这不是第一次,我想它的行为类似下面的滚动区域(想象一个日志或聊天窗口,但过于复杂,用一个简单的QTextBrowser):QScrollArea:自动滚动到新添加的窗口小部件

  • 我想添加多个小部件,这些小部件出现在另一个下方(例如放在QVBoxLayout中时)
  • 此布局中的每个小部件应具有固定大小或宽度高度(如简单标签)
  • 滚动区域应自动滚动到最近添加的一个
  • (optiona L),当有剩余空间(尚未启用滚动条),其内容应当与底部

使用QScrollArea:

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

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

使用而QListView:

由于我的项目是太复杂了,他们需要QWidgets。他们不能有重点,不能选择,所以基于项目的解决方案似乎只是“错误的方式”。而且,这个解决方案听起来太“重”了。

我只是不能相信没有简单的方法,所以我觉得我还没有看到它呢!

回答

1

QListView应该没问题。你声称你的物品是静态的,没有与他们的互动:没有焦点,没有选择。这似乎是QWidget是这样的项目矫枉过正。你只需要具有固定大小的东西并且可以绘制自己。这正是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); 
} 
+0

我需要一个QWidget,因为我将绘制的内容是HTML代码,所以我想使用QLabel。在未来它可能比这更复杂,我正在寻找一个基于QWidget的解决方案。如果有一种方法可以将QWidget包含在委托中,这将是一个可行的解决方案,但我无法想象它必须如此复杂。 – leemes

+0

您不应该使用QWidget绘制静态项目代理。这是毫无意义的,恕我直言,糟糕的设计。您可以从任何小部件中重新使用样式化的绘制代码,而无需使用小部件本身。 –

+0

我想要一个通用的解决方案,它允许我使用任何*小部件,而不仅仅是Qt的样式化小部件。所以我正在寻找某种代理项目/委托/任何东西,就像有一个QGraphicsWidget将小部件用作图形项目一样。如果QListViews没有这样的解决方案,我需要通过修复我的更新问题来使用QLayout方式。 – leemes