Название: QScrollArea, динамический виджет
Отправлено: Alex Custov от Июль 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() ?
Название: Re: QScrollArea, динамический виджет
Отправлено: spirit от Июль 28, 2008, 16:51
похоже на баг http://trolltech.com/developer/task-tracker/index_html?id=103525&method=entry (http://trolltech.com/developer/task-tracker/index_html?id=103525&method=entry)
Название: Re: QScrollArea, динамический виджет
Отправлено: Alex Custov от Июль 28, 2008, 17:13
Пример очень упрощённый, на самом деле добавляться будет много виджетов, и не только кнопки. И многие - уже после создания интерфейса. Мда, придёться постоянно делать setWidget(). По поводу бага - блин, ну что такое. Столько версий пофиксить не могут. На Qt писать становиться что-то не прикольно :( Ещё вопрос - в Qt3 был слот virtual void resizeContents(int w, int h);
чтобы можно было следить за размерами содержимого. Теперь его нет. Получается, надо наследовать QWidget и отслеживать resizeEvent(), и этот кастомный виджет передавать в QScrollArea::setWidget() ? Блин, ну зачем так всё усложнять? Раньше как-то попроще было.
Название: Re: QScrollArea, динамический виджет
Отправлено: spirit от Июль 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"
Название: Re: QScrollArea, динамический виджет
Отправлено: Hort от Июль 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); все отлично работает и добавляет динамически во время выполнения программы через тот же самый слот. единственно с чем промучался и так и не сделал - чтобы скрол ареа прокручивался к добавленному виджету, ели его не видно
Название: Re: QScrollArea, динамический виджет
Отправлено: spirit от Июль 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().
|