Russian Qt Forum
Сентябрь 30, 2024, 16:31 *
Добро пожаловать, Гость. Пожалуйста, войдите или зарегистрируйтесь.
Вам не пришло письмо с кодом активации?

Войти
 
  Начало   Форум  WIKI (Вики)FAQ Помощь Поиск Войти Регистрация  

Страниц: [1]   Вниз
  Печать  
Автор Тема: QScrollArea, динамический виджет  (Прочитано 11420 раз)
Alex Custov
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 2063


Просмотр профиля
« : Июль 28, 2008, 16:29 »

Имеется вот такой код.. Есть gridlayout с кнопкой "Add" и scrollarea. При нажатии на кнопку Add в scrollarea должна добавляться другая кнопка, однако ничего не происходит. Поправьте где не прав:

Код:
#include <QApplication>
#include <QGridLayout>
#include <QPushButton>
#include <QHBoxLayout>
#include <QResizeEvent>
#include <QDebug>
#include <QScrollArea>

class ScrollArea : public QScrollArea
{
    Q_OBJECT

    public:
        ScrollArea(QWidget *p) : QScrollArea(p)
        {}

    protected:
        void resizeEvent(QResizeEvent *event)
        {
            qDebug() << event->size();
            QScrollArea::resizeEvent(event);
        }
};

class MyWidget : public QWidget
{
    Q_OBJECT

    public:
        QGridLayout *l;
        ScrollArea  *s;
        QHBoxLayout *layout;

        MyWidget() : QWidget()
        {
            move(0, 0);
            resize(400, 100);

            l = new QGridLayout(this);

            QPushButton *b = new QPushButton("Add", this);
            connect(b, SIGNAL(clicked()), this, SLOT(slotC()));

            s = new ScrollArea(this);

            l->addWidget(b, 0, 0, Qt::AlignCenter);
            l->addWidget(s, 1, 0);

            s->setWidget(new QWidget);

            layout = new QHBoxLayout(s->widget());
            s->widget()->setLayout(layout);
            layout->setDirection(QBoxLayout::LeftToRight);
        }

    private slots:
        void slotC()
        {
            QWidget *w = new QPushButton("b1", s->widget());
            w->setFixedWidth(50);
            w->show();
        }

};

int main(int argc, char ** argv)
{
    QApplication app(argc, argv);

    MyWidget *w = new MyWidget;

    w->show();

    return app.exec();
}

#include "main.moc"

P.S. Qt 4.3.3.
P.P.S. Непонятно, куда делся метод QLayout::setAutoAdd() ?
Записан
spirit
Гость
« Ответ #1 : Июль 28, 2008, 16:51 »

похоже на баг http://trolltech.com/developer/task-tracker/index_html?id=103525&method=entry
Записан
Alex Custov
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 2063


Просмотр профиля
« Ответ #2 : Июль 28, 2008, 17:13 »

Пример очень упрощённый, на самом деле добавляться будет много виджетов, и не только кнопки. И многие - уже после создания интерфейса. Мда, придёться постоянно делать setWidget().

По поводу бага - блин, ну что такое. Столько версий пофиксить не могут. На Qt писать становиться что-то не прикольно Грустный

Ещё вопрос - в Qt3 был слот

Код:
virtual void resizeContents(int w, int h);

чтобы можно было следить за размерами содержимого. Теперь его нет. Получается, надо наследовать QWidget и отслеживать resizeEvent(), и этот кастомный виджет передавать в QScrollArea::setWidget() ?

Блин, ну зачем так всё усложнять? Раньше как-то попроще было.
Записан
spirit
Гость
« Ответ #3 : Июль 28, 2008, 17:26 »

можно сделать вот такой воркт-эраунд
Код:
#include <QApplication>
#include <QGridLayout>
#include <QPushButton>
#include <QHBoxLayout>
#include <QResizeEvent>
#include <QDebug>
#include <QScrollArea>

class ScrollArea : public QScrollArea
{
    Q_OBJECT

    public:
        ScrollArea(QWidget *p) : QScrollArea(p)
        {}

    protected:
        void resizeEvent(QResizeEvent *event)
        {
            //qDebug() << event->size();
            QScrollArea::resizeEvent(event);
        }
};

class MyWidget : public QWidget
{
    Q_OBJECT

    public:
        QGridLayout *l;
        ScrollArea  *s;
        QHBoxLayout *layout;

        MyWidget() : QWidget()
        {
            move(0, 0);
            resize(400, 100);

            l = new QGridLayout(this);

            QPushButton *b = new QPushButton("Add", this);
            connect(b, SIGNAL(clicked()), this, SLOT(slotC()));

            s = new ScrollArea(this);

            l->addWidget(b, 0, 0, Qt::AlignCenter);
            l->addWidget(s, 1, 0);

            s->setWidget(new QWidget);

connect(this, SIGNAL(layoutChanged()), SLOT(updateLayout()), Qt::QueuedConnection);

            layout = new QHBoxLayout(s->widget());
            s->widget()->setLayout(layout);
layout->setDirection(QBoxLayout::LeftToRight);
        }

signals:
void layoutChanged();

    private slots:
        void slotC()
        {
            QWidget *w = new QPushButton("b1", s->widget());
s->widget()->layout()->addWidget(w);           
            w->show();
emit layoutChanged();
        }

void updateLayout()
{
// This is workaround when using QScrollArea::setWidget(...)
// and different widget creation order.
// For more details, please see a bug #103525 on Trolltech Task Tracker:
// http://trolltech.com/developer/task-tracker
int h = s->widget()->sizeHint().height();
int w = s->widget()->sizeHint().width();
s->widget()->resize(w, h);
}

};

int main(int argc, char ** argv)
{
    QApplication app(argc, argv);

    MyWidget *w = new MyWidget;

    w->show();

    return app.exec();
}

#include "main.moc"
Записан
Hort
Гость
« Ответ #4 : Июль 29, 2008, 23:15 »

у меня подобная ситуация - работает все отлично
Код:
answersScrollArea=new QScrollArea;
QWidget *widget=new QWidget;
answersLayout=new QVBoxLayout;
answersLayout->addStretch(1);
slotAddAnswer();
widget->setLayout(answersLayout);
answersScrollArea->setWidget(widget);
answersScrollArea->setWidgetResizable(true);
слот slotAddAnswer() добавлят виджет через
Цитировать
answersLayout->insertWidget(index, new AnswerEditor);
все отлично работает и добавляет динамически во время выполнения программы через тот же самый слот.
единственно с чем промучался и так и не сделал - чтобы скрол ареа прокручивался к добавленному виджету, ели его не видно
« Последнее редактирование: Июль 29, 2008, 23:16 от Hort » Записан
spirit
Гость
« Ответ #5 : Июль 30, 2008, 10:17 »

так-то работать будет, но в случае сабжа нет, ибо это баг.
когда меняется порядок установки виджетов.
баг номер 103525 на трекере Троллей
Цитировать
Sometimes it will make a difference to Qt when widgets are constructed/added to layouts etc. Most times it will not.

One example is this:


QScrollArea foo(...);
QWidget *w = new QWidget(...);
foo.setWidget(w);
QVBoxLayout *l = new QVBoxLayout(w);
l->addWidget(new QLineEdit);


The line edit does not show up, vs

QScrollArea foo(...);
QWidget *w = new QWidget(...);
QVBoxLayout *l = new QVBoxLayout(w);
l->addWidget(new QLineEdit);
foo.setWidget(w);

where the line edit does show. Similar things happen with QDockWidget::setWidget().
Записан
Страниц: [1]   Вверх
  Печать  
 
Перейти в:  


Страница сгенерирована за 0.098 секунд. Запросов: 23.