Название: Вложеные лейауты в делегатах и некоректный размер QComboBox,QLineEdit
Отправлено: Fregloin от Май 21, 2013, 18:01
Привет, такая проблема. В делегате в createEditor нужно создать в ячейке горизонтальный лейаут, в котором будет три виджета, 2 кнопки и 1 произволный. Лейаут должен быть таким [ <--- expanding -- QWidget ---expanding -->][ QToolButton ][ QToolButton ] Дело в том, что все виджеты которые я использую кроме QComboBox,QLineEdit рисуются нормально по размерам, а вот эти в упор не хотят растягиваться. Уже и SizePolicy ставил и Stretch. Ничего не помогает. Привожу код class OBJECTINSPECTORSHARED_EXPORT QPropertyEditWidget : public QWidget { Q_OBJECT
QToolButton * feditButton; QToolButton * fresetButton; QWidget * fwidget; QWidget * fcontainer; QHBoxLayout * flayout;
protected:
void resizeEvent(QResizeEvent *event);
public: explicit QPropertyEditWidget(QWidget *parent = 0); QWidget * widget() const;
void setEditable(bool Value = true); void setResatable(bool Value = true);
signals:
void editButtonClicked(); void resetButtonClicked(); public slots:
void setWidget(QWidget * Widget); };
#include <QResizeEvent> #include "qpropertyeditwidget.h"
QPropertyEditWidget::QPropertyEditWidget(QWidget *parent) : QWidget(parent) { fwidget = NULL;
flayout = new QHBoxLayout(this); flayout->setContentsMargins(0,0,0,0); flayout->setSpacing(1);
fcontainer = new QWidget(this); fcontainer->setAutoFillBackground(true);
feditButton = new QToolButton(this); feditButton->setIcon(QIcon(":/icons/pencil")); feditButton->setMaximumSize(26,26); feditButton->setMinimumSize(10,10); feditButton->setVisible(false);
fresetButton = new QToolButton(this); fresetButton->setText("*"); fresetButton->setMaximumSize(10,26); fresetButton->setMinimumSize(5,10); fresetButton->setVisible(false);
flayout->addWidget(fcontainer,1); flayout->addWidget(feditButton); flayout->addWidget(fresetButton);
setFocusProxy(feditButton); setLayout(flayout); connect(feditButton,SIGNAL(clicked()),this,SIGNAL(editButtonClicked())); connect(fresetButton,SIGNAL(clicked()),this,SIGNAL(resetButtonClicked())); }
QWidget *QPropertyEditWidget::widget() const { return fwidget; }
void QPropertyEditWidget::setEditable(bool Value) { feditButton->setVisible(Value); updateGeometry(); }
void QPropertyEditWidget::setResatable(bool Value) { fresetButton->setVisible(Value); updateGeometry(); }
void QPropertyEditWidget::setWidget(QWidget *Widget) { if(fwidget!=Widget) { if(fwidget) { fwidget->setParent(NULL); } fwidget = Widget; if(fwidget) { fwidget->setParent(fcontainer); updateGeometry(); } } }
//Это для отладки, так работает (не это же костыли... + не учитываются размеры 2х кнопок) void QPropertyEditWidget::resizeEvent(QResizeEvent * event) { if(fwidget) fwidget->setGeometry(0,0,event->size().width(),event->size().height()); }
А вот как создаю в делегате QWidget *CObjectInspectorDelegate::createEditor(QWidget *parent, const QStyleOptionViewItem &option, const QModelIndex &index) const { Q_UNUSED(option) ... if(currentProperty.isEnumType()) { QPropertyEditWidget * enumEditWidget = new QPropertyEditWidget(parent); enumEditWidget->setResatable(currentProperty.isResettable()); QMetaEnum currentEnumerator = currentProperty.enumerator(); QComboBox * comboBox = new QComboBox(); //comboBox->setSizePolicy(QSizePolicy::Expanding,QSizePolicy::Expanding); comboBox->setSizeAdjustPolicy(QComboBox::AdjustToContents); for(int i=0;i<currentEnumerator.keyCount();i++) { comboBox->addItem(currentEnumerator.key(i)); } connect(comboBox,SIGNAL(currentIndexChanged(QString)),this,SLOT(setStringValue(QString))); connect(enumEditWidget,SIGNAL(resetButtonClicked()),this,SLOT(resetProperty())); enumEditWidget->setWidget(comboBox); return enumEditWidget; }
Вот что получаем в результате ...
Название: Re: Вложеные лейауты в делегатах и некоректный размер QComboBox,QLineEdit
Отправлено: Fregloin от Май 21, 2013, 18:13
Однако ошибся, все виджеты так рисуются с неправильными размерами (QSpinBox например)... Я подозреваю что то недоделал с лейаутом, но не пойму что конкретно.
Название: Re: Вложеные лейауты в делегатах и некоректный размер QComboBox,QLineEdit
Отправлено: GreatSnake от Май 21, 2013, 18:19
Не видно что такое CObjectInspectorDelegate? Скорее всего у него отсутствует updateEditorGeometry().
Название: Re: Вложеные лейауты в делегатах и некоректный размер QComboBox,QLineEdit
Отправлено: Fregloin от Май 22, 2013, 12:08
updateEditorGeometry есть, в нем просто задается виджету размер. не помогло.
Название: Re: Вложеные лейауты в делегатах и некоректный размер QComboBox,QLineEdit
Отправлено: GreatSnake от Май 22, 2013, 12:21
QPropertyEditWidget::setWidget(QWidget *Widget) на самом деле не помещает Widget в лэйаут.
Название: Re: Вложеные лейауты в делегатах и некоректный размер QComboBox,QLineEdit
Отправлено: Fregloin от Май 22, 2013, 16:47
Вот выкладваю исходники PropertyEditor class OBJECTINSPECTORSHARED_EXPORT QPropertyEditWidget : public QWidget { Q_OBJECT
QToolButton * feditButton; QToolButton * fresetButton; QWidget * fwidget; QWidget * fcontainer; QHBoxLayout * flayout;
protected:
void resizeEvent(QResizeEvent *event); void recalculate();
public: explicit QPropertyEditWidget(QWidget *parent = 0); QWidget * widget() const;
void setEditable(bool Value = true); void setResatable(bool Value = true);
signals:
void editButtonClicked(); void resetButtonClicked(); public slots:
void setWidget(QWidget * Widget); };
#include <QResizeEvent> #include "qpropertyeditwidget.h"
QPropertyEditWidget::QPropertyEditWidget(QWidget *parent) : QWidget(parent) { fwidget = NULL;
flayout = new QHBoxLayout(this); flayout->setContentsMargins(0,0,0,0); flayout->setSpacing(1);
fcontainer = new QWidget(this); fcontainer->setAutoFillBackground(true);
feditButton = new QToolButton(this); feditButton->setIcon(QIcon(":/icons/pencil")); feditButton->setMaximumSize(26,26); feditButton->setMinimumSize(10,10); feditButton->setVisible(false);
fresetButton = new QToolButton(this); fresetButton->setText("*"); fresetButton->setMaximumSize(10,26); fresetButton->setMinimumSize(5,10); fresetButton->setVisible(false);
flayout->addWidget(fcontainer,1); flayout->addWidget(feditButton); flayout->addWidget(fresetButton);
setFocusProxy(feditButton); setLayout(flayout); connect(feditButton,SIGNAL(clicked()),this,SIGNAL(editButtonClicked())); connect(fresetButton,SIGNAL(clicked()),this,SIGNAL(resetButtonClicked()));
recalculate(); }
QWidget *QPropertyEditWidget::widget() const { return fwidget; }
void QPropertyEditWidget::setEditable(bool Value) { feditButton->setVisible(Value); recalculate(); }
void QPropertyEditWidget::setResatable(bool Value) { fresetButton->setVisible(Value); recalculate(); }
void QPropertyEditWidget::setWidget(QWidget *Widget) { if(fwidget!=Widget) { if(fwidget) { fwidget->setParent(NULL); } fwidget = Widget; if(fwidget) { fwidget->setParent(fcontainer); recalculate(); } } }
void QPropertyEditWidget::resizeEvent(QResizeEvent * event) { Q_UNUSED(event)
recalculate(); }
void QPropertyEditWidget::recalculate() { if(fwidget) { int w = width(); if(fresetButton->isVisibleTo(this)) w-=fresetButton->width(); if(feditButton->isVisibleTo(this)) w-=feditButton->width(); fwidget->resize(w,height()); } }
С принудительной recalculate() все заработало как надо, но почему дочерний виджет fwidget не изменяет свои размеры согласно размерам fcontainer я так и не понял. Задавал разные sizePolicy как для fwidget так и для fconatiner - эффекта не было.
Название: Re: Вложеные лейауты в делегатах и некоректный размер QComboBox,QLineEdit
Отправлено: Fregloin от Май 22, 2013, 17:58
странно QComboBox все равно проглючивает сначала, пока не вызывается первый resize(). А вот другие виджеты нормально подгоняют свои размеры.
Название: Re: Вложеные лейауты в делегатах и некоректный размер QComboBox,QLineEdit
Отправлено: Fregloin от Май 22, 2013, 18:04
еще заметил, что комбобокс при первом показе сначала растягивается как надо, но сразу же меняет свой под размер содержимого (хотя я это ему явно запретил делать)... кто подскажет как побороть эту гадость?
Название: Re: Вложеные лейауты в делегатах и некоректный размер QComboBox,QLineEdit
Отправлено: GreatSnake от Май 22, 2013, 18:14
QPropertyEditWidget::setWidget(QWidget *Widget) на самом деле не помещает Widget в лэйаут.
Ещё раз повторяю - Widget не помещается в лэйаут установленный в QPropertyEditWidget, поэтому при изменении геометрии QPropertyEditWidget-а его геометрия не учитывается. Зачем делать всякие recalculate() и вызывать его в resizeEvent(), когда достаточно было сделать QPropertyEditWidget::layout()->insertWidget( 0, Widget )??? PS: может имеет смысл сначала освоить Управление компоновкой (http://www.doc.crossplatform.ru/qt/4.7.x/layout.html)?
Название: Re: Вложеные лейауты в делегатах и некоректный размер QComboBox,QLineEdit
Отправлено: Fregloin от Май 23, 2013, 09:13
Ваш совет не помог. Зато помогло следующее QComboBox * comboBox = new QComboBox(); comboBox->setSizePolicy(QSizePolicy::Expanding,QSizePolicy::Expanding); comboBox->setSizeAdjustPolicy(QComboBox::AdjustToContentsOnFirstShow);
Дальше как по коду ...
Название: Re: Вложеные лейауты в делегатах и некоректный размер QComboBox,QLineEdit
Отправлено: GreatSnake от Май 23, 2013, 10:08
Ваш совет не помог. Зато помогло следующее QComboBox * comboBox = new QComboBox(); comboBox->setSizePolicy(QSizePolicy::Expanding,QSizePolicy::Expanding); comboBox->setSizeAdjustPolicy(QComboBox::AdjustToContentsOnFirstShow);
Что-то слабо верится, т.к. QSizePolicy используется только в случае помещения виджета в лэйаут, чего у тебя не наблюдается.
|