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

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

Страниц: [1]   Вниз
  Печать  
Автор Тема: Вложеные лейауты в делегатах и некоректный размер QComboBox,QLineEdit  (Прочитано 6062 раз)
Fregloin
Супер
******
Offline Offline

Сообщений: 1025


Просмотр профиля
« : Май 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;
            }

Вот что получаем в результате ...
Записан
Fregloin
Супер
******
Offline Offline

Сообщений: 1025


Просмотр профиля
« Ответ #1 : Май 21, 2013, 18:13 »

Однако ошибся, все виджеты так рисуются с неправильными размерами (QSpinBox например)...
Я подозреваю что то недоделал с лейаутом, но не пойму что конкретно.
Записан
GreatSnake
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 2921



Просмотр профиля
« Ответ #2 : Май 21, 2013, 18:19 »

Не видно что такое CObjectInspectorDelegate?
Скорее всего у него отсутствует updateEditorGeometry().
« Последнее редактирование: Май 21, 2013, 18:21 от GreatSnake » Записан

Qt 5.11/4.8.7 (X11/Win)
Fregloin
Супер
******
Offline Offline

Сообщений: 1025


Просмотр профиля
« Ответ #3 : Май 22, 2013, 12:08 »

updateEditorGeometry есть, в нем просто задается виджету размер. не помогло.
Записан
GreatSnake
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 2921



Просмотр профиля
« Ответ #4 : Май 22, 2013, 12:21 »

QPropertyEditWidget::setWidget(QWidget *Widget) на самом деле не помещает Widget в лэйаут.
Записан

Qt 5.11/4.8.7 (X11/Win)
Fregloin
Супер
******
Offline Offline

Сообщений: 1025


Просмотр профиля
« Ответ #5 : Май 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 - эффекта не было.
Записан
Fregloin
Супер
******
Offline Offline

Сообщений: 1025


Просмотр профиля
« Ответ #6 : Май 22, 2013, 17:58 »

странно QComboBox все равно проглючивает сначала, пока не вызывается первый resize(). А вот другие виджеты нормально подгоняют свои размеры.
Записан
Fregloin
Супер
******
Offline Offline

Сообщений: 1025


Просмотр профиля
« Ответ #7 : Май 22, 2013, 18:04 »

еще заметил, что комбобокс при первом показе сначала растягивается как надо, но сразу же меняет свой под размер содержимого (хотя я это ему явно запретил делать)...
кто подскажет как побороть эту гадость?
Записан
GreatSnake
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 2921



Просмотр профиля
« Ответ #8 : Май 22, 2013, 18:14 »

QPropertyEditWidget::setWidget(QWidget *Widget) на самом деле не помещает Widget в лэйаут.
Ещё раз повторяю - Widget не помещается в лэйаут установленный в QPropertyEditWidget, поэтому при изменении геометрии QPropertyEditWidget-а его геометрия не учитывается.
Зачем делать всякие recalculate() и вызывать его в resizeEvent(), когда достаточно было сделать  QPropertyEditWidget::layout()->insertWidget( 0, Widget )Непонимающий

PS: может имеет смысл сначала освоить Управление компоновкой?
« Последнее редактирование: Май 22, 2013, 18:30 от GreatSnake » Записан

Qt 5.11/4.8.7 (X11/Win)
Fregloin
Супер
******
Offline Offline

Сообщений: 1025


Просмотр профиля
« Ответ #9 : Май 23, 2013, 09:13 »

Ваш совет не помог.

Зато помогло следующее
Код:
QComboBox   *   comboBox = new QComboBox();
comboBox->setSizePolicy(QSizePolicy::Expanding,QSizePolicy::Expanding);
comboBox->setSizeAdjustPolicy(QComboBox::AdjustToContentsOnFirstShow);

Дальше как по коду ...




Записан
GreatSnake
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 2921



Просмотр профиля
« Ответ #10 : Май 23, 2013, 10:08 »

Ваш совет не помог.

Зато помогло следующее
Код:
QComboBox   *   comboBox = new QComboBox();
comboBox->setSizePolicy(QSizePolicy::Expanding,QSizePolicy::Expanding);
comboBox->setSizeAdjustPolicy(QComboBox::AdjustToContentsOnFirstShow);

Что-то слабо верится, т.к. QSizePolicy используется только в случае помещения виджета в лэйаут, чего у тебя не наблюдается.
Записан

Qt 5.11/4.8.7 (X11/Win)
Страниц: [1]   Вверх
  Печать  
 
Перейти в:  


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