我的设置如下:
Main Window
|- QHBoxLayout
|- Some Widgets
|- QScrollArea
| |- QHBoxLayout
| |- QGridLayout
| |- Widgets dynamically loaded in at runtime
| |- QVBoxLayout
|- Some Widgets
在我添加小部件后,我希望滚动区域完全向下滚动。 我是这样做的:
this->ui->gridLayout_table->addWidget(/*Widget*/); // this works perfectly nice
this->ui->gridLayout_table->addWidget(/*Widget*/); // this also works perfectly nice
this->ui->scrollArea->verticalScrollBar()->setValue(this->ui->scrollArea->verticalScrollBar()->maximum());
在最后一个命令中,它滚动到最大值减去新添加的小部件的高度。在滚动之前有没有办法刷新更改?
提前致谢 卢卡斯
答案 0 :(得分:2)
rangeChanged
方法的Python版本:
scroll_area = QtGui.QScrollArea()
scroll_bar = scroll_area.verticalScrollBar()
scroll_bar.rangeChanged.connect(lambda: scroll_bar.setValue(scroll_bar.maximum()))
通过将rangeChanged
方法连接到scrollldown,可以确保每次范围发生变化时滚动条都会向下滚动到最大值。
答案 1 :(得分:1)
我遇到了同样的问题。我找到了一个解决方法,也可能对你有用。
在将小部件添加到滚动区域后立即使用scrollBar->setValue(scrollBar->maximum());
时,使用pb_AdjustScrollBar
不起作用。滚动条的最大值尚未更新。
但是,如果您有一个按钮,用户必须单击以将滚动条的位置调整到最大值,它才会起作用。似乎滚动区域仅异步(通过信号)通知其滚动条。所以我只是在我的小部件中添加了一个隐藏按钮animateClick(int)
,并在将小部件添加到滚动区域后使用clicked(bool)
方法模拟了一次点击。收到AdjustScrollBar
按钮的信号scrollBar
后,我会触发scrollBarPtr->triggerAction(QAbstractSlider::SliderToMaximum);
以使用最大位置:
animateClick
注意:scrollBar
超时必须设置为100ms(默认值)。将超时设置得更短会导致{{1}}不更新到其实际最大值。不过我猜100ms对用户交互来说足够快。
我仍然很想知道如何以更智能的方式解决这个问题。
答案 2 :(得分:1)
我找到了路。添加小部件后:
view.requestFocusFromTouch();
答案 3 :(得分:1)
一种解决方法是使用垂直滚动条的rangeChanged(int,int)信号。
#include <QWidget>
#include <QBoxLayout>
#include <QScrollArea>
#include <QScrollBar>
class myClass
{
Q_OBJECT
public:
myClass();
private:
QScrollArea *scrollArea;
int scrollBarMax = 0;
private slots:
void scrollToBottom(int min, int max);
};
myClass::myClass()
{
QVBoxLayout *myLayout = new QVBoxLayout;
QWidget *myWidget = new QWidget;
myWidget->setLayout(myLayout);
scrollArea = new QScrollArea;
scrollArea->setWidget(myWidget);
scrollArea->setWidgetResizeable(true);
QObject::connect(scrollArea->verticalScrollBar(), SIGNAL(rangeChanged(int,int)), this, SLOT(scrollToBottom(int,int)));
}
void myClass::scrollToBottom(int min, int max)
{
(void) min;
if (max > scrollBarMax) scrollArea->verticalScrollBar()->setValue(max);
scrollBarMax = max;
}
答案 4 :(得分:0)
#include <QtGui>
class TestWidget : public QWidget
{
Q_OBJECT
public:
TestWidget(QWidget * parent = 0);
private slots:
void addButton();
private:
QScrollArea * scrollArea;
QWidget * contents;
QVBoxLayout * contentsLayout;
};
TestWidget::TestWidget(QWidget * parent)
: QWidget(parent)
{
QVBoxLayout * layout = new QVBoxLayout(this);
scrollArea = new QScrollArea(this);
layout->addWidget(scrollArea);
contents = new QWidget(this);
scrollArea->setWidget(contents);
contents->resize(300,400);
scrollArea->setWidgetResizable(true);
contentsLayout = new QVBoxLayout(contents);
for (int i = 0; i < 10; ++i)
{
QPushButton * button = new QPushButton(QString("button %1").arg(i), this);
connect(button, SIGNAL(clicked()), this, SLOT(addButton()));
contentsLayout->addWidget(button);
}
}
void TestWidget::addButton()
{
QPushButton * button = new QPushButton("button", this);
connect(button, SIGNAL(clicked()), this, SLOT(addButton()));
contentsLayout->addWidget(button);
QScrollBar * scrollBar = scrollArea->verticalScrollBar();
scrollBar->setValue(scrollBar->maximum());
}
int main(int argc, char * argv[])
{
QApplication app(argc, argv);
TestWidget widget;
widget.show();
app.setQuitOnLastWindowClosed(true);
return app.exec();
}
#include "main.moc"
问题发生在Qt 4.8和5.2(需要对示例进行微小修改)。
答案 5 :(得分:0)
有同样的问题,这是手册说的:
"In such cases, setting the layout's size constraint property to one which provides
constraints on the minimum and/or maximum size of the layout (e.g.,
QLayout::SetMinAndMaxSize) will cause the size of the scroll area to be updated
whenever the contents of the layout changes."
在我的情况下,QScrollArea的内容大小是通过QScrollArea的小部件的setMinimumSize
方法更改的,所以我只添加了ui->scroll_area->widget()->layout()->setSizeConstraint(QLayout::SetMinAndMaxSize);
,它开始工作正常。
重要:调整QScrollArea的小部件的大小之后,应在自定义事件处理程序内更改QScrollBar的值。简单的例子:
bool MyCustomClassWithScrollArea::event(QEvent * event)
{
switch (event->type())
{
case MyCustomScrollToEndEvent::ScrollToEndEventType:
{
ui->scroll_area->verticalScrollBar()->setValue( ui->scroll_area->verticalScrollBar()->maximum() ); //scrolls to the end
return true;
}
}
return QWidget::event(event);
}