Hi, I've made a search and found lots of answer but I still can't get it to work. I'm toying with the scroll area in which I want to add widget to it dynamically and I want the scroll area to ensure the las widget is always visible.
I use a widget in which I use a QVBoxLayout and then set this widget in the scroll area. I can see my stuff but it always scrolls to the next to last one when I use ensureWidgetVisible. I traced this method and the size hint returned seems ok. Here's my test code:
#include <QApplication>
#include <QtGui>
#include "MainWidget.h"
int main( int argc, char* argv[] )
{
// Put your own widget here.
MainWidget* w = new MainWidget();
w->show();
return app.exec();
}
#include <QApplication>
#include <QtGui>
#include "MainWidget.h"
int main( int argc, char* argv[] )
{
QApplication app( argc, argv );
// Put your own widget here.
MainWidget* w = new MainWidget();
w->show();
return app.exec();
}
To copy to clipboard, switch view to plain text mode
#pragma once
#include <QtGui>
{
Q_OBJECT
public:
public slots:
void OnNewElement();
protected slots:
void ScrollToEnd();
protected:
};
#pragma once
#include <QtGui>
class MainWidget : public QWidget
{
Q_OBJECT
public:
MainWidget( QWidget* parent = 0 );
public slots:
void OnNewElement();
protected slots:
void ScrollToEnd();
protected:
QScrollArea* mScrollArea;
QWidget* mInternalWidget;
QVBoxLayout* mInternalLayout;
QWidget* mLastChild;
};
To copy to clipboard, switch view to plain text mode
#include "MainWidget.h"
{
setLayout( layout );
layout->addWidget( mScrollArea );
mInternalWidget
= new QWidget(mScrollArea
);
mInternalWidget->setLayout(mInternalLayout);
for (int i=0; i<20; ++i)
{
element
= new QWidget( mInternalWidget
);
element->setFixedSize( 200,20 );
element->setAutoFillBackground( true );
element->setPalette(p);
mInternalLayout->addWidget( element );
}
mScrollArea->setWidget( mInternalWidget );
mScrollArea->setWidgetResizable(true);
mScrollArea->verticalScrollBar()->setSingleStep( 20 );
connect( b, SIGNAL(clicked()), this, SLOT(OnNewElement()) );
layout->addWidget( b );
}
void MainWidget::OnNewElement()
{
static int count = 0;
element->setFixedSize( 100, 20 );
element->setAutoFillBackground( true );
element->setPalette(p);
mInternalLayout->addWidget( element );
mLastChild = element;
QTimer::singleShot( 5,
this,
SLOT(ScrollToEnd
()) );
}
void MainWidget::ScrollToEnd()
{
//mScrollArea->verticalScrollBar()->setValue( mScrollArea->verticalScrollBar()->maximum() );
mScrollArea->ensureWidgetVisible( mLastChild );
}
#include "MainWidget.h"
MainWidget::MainWidget( QWidget* parent ) : QWidget(parent)
{
QHBoxLayout* layout = new QHBoxLayout(this);
setLayout( layout );
mScrollArea = new QScrollArea(this);
layout->addWidget( mScrollArea );
mInternalWidget = new QWidget(mScrollArea);
mInternalLayout = new QVBoxLayout(mInternalWidget);
mInternalWidget->setLayout(mInternalLayout);
QWidget* element = NULL;
for (int i=0; i<20; ++i)
{
QString name = QString("Base Element %0").arg(i);
element = new QWidget( mInternalWidget );
element->setFixedSize( 200,20 );
element->setAutoFillBackground( true );
QPalette p = element->palette();
p.setColor( QPalette::Window, QColor(255,0,255) );
element->setPalette(p);
mInternalLayout->addWidget( element );
}
mScrollArea->setWidget( mInternalWidget );
mScrollArea->setWidgetResizable(true);
mScrollArea->verticalScrollBar()->setSingleStep( 20 );
QPushButton* b = new QPushButton( "Add new element" );
connect( b, SIGNAL(clicked()), this, SLOT(OnNewElement()) );
layout->addWidget( b );
}
void MainWidget::OnNewElement()
{
static int count = 0;
QString name = QString("New Element %0").arg(count++);
QLabel* element = new QLabel( name );
element->setFixedSize( 100, 20 );
element->setAutoFillBackground( true );
QPalette p = element->palette();
p.setColor( QPalette::Window, QColor(255,0,0) );
element->setPalette(p);
mInternalLayout->addWidget( element );
mLastChild = element;
QTimer::singleShot( 5, this, SLOT(ScrollToEnd()) );
}
void MainWidget::ScrollToEnd()
{
//mScrollArea->verticalScrollBar()->setValue( mScrollArea->verticalScrollBar()->maximum() );
mScrollArea->ensureWidgetVisible( mLastChild );
}
To copy to clipboard, switch view to plain text mode
Calling ensureWidgetVisible from the OnNewElement slot does not work and I suspected that is was because the layout had not been calculated yet so I tried a singleShot timer to do the scroll. It works for the first 100 or so elements but after that, it scrolls to the next to last element again.
I know we're on the 24th but you know the drill, coders almost always work
Bookmarks