воскресенье, 17 января 2010 г.

Некоторые особенности QScrollArea

Столкнулся с таким интересным виджетом как QScrollArea. С помощью него можно отображать прокручивающееся содержимое, допустим, картинку или текст, или список виджетов.

Для того, чтобы вовнутрь QScrollArea добавить другой виджет нужно сделать примерно следующее:
// Заранее созданная в setupUi() scrollArea
QLabel *l1 = new QLabel("label1"); 
scrollArea->setWidget(l1);
Метод QScrollArea::setWidget устанавливает наш лейбл l1 в качестве дочернего для scrollArea.

А что, если мы хотим добавить пару лейблов вместо одного.

Вот такой код уже работать правильно не будет - появится только последний лейбл:
QLabel *l1 = new QLabel("label1");
QLabel *l2 = new QLabel("label2"); 
scrollArea->setWidget(l1); 
scrollArea->setWidget(l2);

Для того, чтобы получить два лейбла, нужно использовать слои:
QLabel *l1 = new QLabel("label1"); 
QLabel *l2 = new QLabel("label2");
QVBoxLayout *labelLayout= new QVBoxLayout(scrollArea);
labelLayout->addWidget(l1);
labelLayout->addWidget(l2);
Теперь лейблы будут размещены один под другим.
Либо просто назначить лейблы дочерними по отношению к QScrollArea
QLabel *l1 = new QLabel(scrollArea);
QLabel *l2 = new QLabel(scrollArea);
l1->setText("label1");
l2->setText("label2");
Можно сделать еще и следующим образом:
QLabel *l1 = new QLabel("label1");
QLabel *l2 = new QLabel("label2");
QLabel *l3 = new QLabel("label3");
QVBoxLayout *layout = new QVBoxLayout(scrollArea);
layout ->addWidget(l2);
layout ->addWidget(l3);
ui->scrollArea->setWidget(l1);
Получится 2 лейбла на слое и один не на слое.
Раньше был такой баг - если написать
ui->scrollArea_2->setWidget(l1);
QVBoxLayout *l = new QVBoxLayout(scrollArea);
l->addWidget(l2);
l->addWidget(l3);
то два последних лейбла не отобразятся. Я использую версию Qt4.6, и здесь такого бага уже не наблюдается.

Интересно использование виджета, унаследованного от QScrollArea
Возможно у меня какие-то ошибки, но выяснил следующее...
Допустим имеем:
class RenderArea: public QScrollArea
{
.....
}
то для того, чтобы добавить лейблы надо написать примерно так:
RenderArea::RenderArea(QWidget * pParent) :
    QScrollArea(pParent)
{
    QLabel *l1 = new QLabel(this);
    QLabel *l2 = new QLabel(this);
    l1->setText("label1");
    l2->setText("label2");
    ..............
}
только надо еще разместить их аккуратно, чтобы не перекрывались.
Размещение с помощью setWidget делается как и раньше:
QLabel *l1 = new QLabel("Hello");
this->setWidget(l1);
Либо через слой, если больше одного размещаемого виджета
QLabel *l1 = new QLabel();
QLabel *l2 = new QLabel();
l1->setText("label1");
l2->setText("label2");
QVBoxLayout *layout = new QVBoxLayout(this);
layout ->addWidget(l1);
layout ->addWidget(l2);
и все прекрасно работает.

Очень было б интересно услышать замечания, особенно тех, кто сталкивался с подобным элементом управления и как решал поставленную задачу.