QTreeView set row size for a specific row



  • Hi all,
    I have a standard QTreeView. In one row I have own widget inserted via QTreeView::setIndexWidget. This widget is composed of QComboBox and a widget dependent on the option selected in the combobox. There are two choices in the combobox, the first one displays QLineEdit whereas the second one shows QTableView. QLineEdit is the default option. When I change the value in the combobox to QTableView, only the table header is shown and the rest is hidden. Is there any possibility to emit some signal or call a method to make QTreeView to resize the row with my widget, so that QTableView would be completely visible?

    Thanks.



  • just don't use setIndexWidget

    Use this template delegate and use QTreeView->setItemDelegateForRow



  • Thx very much @VRonin, I will try and inform about result.



  • @VRonin , it works great but look at attached gif. The cell is resized correctly when I change to "Table" but when change back to "Expression" it remains expanded. I would to have it shrinked back to the original size. Is there any solution to that?0_1521122415121_qt_delegate.gif



  • Interesting, it should actually shrink already.
    Could you post a minimal example so I can debug it?



  • @VRonin
    My project is a little bit bigger. I am not able to provide you a small working example. However, I post a code of the delegate and information about other classes included in the code

    DataTypeEditWidgetFactory - used for creating an object of DataTypeEditWidget which is the widget with the combo box, line edit and two tables from the previous animated gif.
    TextItemWidget - in comparison with QWidget it features extra two functions setText(QString) and text() which are used for setting the content of the widget. They do not have any effect in the case of DataTypeEditWidget which inherits from TextItemWidget.

    Just look at the code if there is something strange. I will try to fix it on my own since I understand you are not fully able to reproduce my environment.

    #ifndef ECFPARAMETERTREEDELEGATE_H
    #define ECFPARAMETERTREEDELEGATE_H
    
    #include <QItemDelegate>
    #include <QHash>
    
    #include "textitemwidgetfactory.h"
    
    class ECFParameterTreeDelegate: public QItemDelegate
    {
        Q_OBJECT
    
    public:
        static const int EditorRole = Qt::UserRole + 1;
    
        ECFParameterTreeDelegate(QObject* parent = nullptr);
        ~ECFParameterTreeDelegate();
    
        void registerEditor(int editorId, TextItemWidgetFactory *factory);
    
        void paint(QPainter *painter, const QStyleOptionViewItem &option, const QModelIndex &index) const override;
        QSize sizeHint(const QStyleOptionViewItem &option, const QModelIndex &index) const override;
    
    protected:
        QWidget* createEditor(QWidget *parent, const QStyleOptionViewItem &option, const QModelIndex &index) const override;
        void setEditorData(QWidget * editor, const QModelIndex & index) const override;
        void setModelData(QWidget * editor, QAbstractItemModel * model, const QModelIndex & index) const override;
        void updateEditorGeometry(QWidget * editor, const QStyleOptionViewItem & option, const QModelIndex & index) const override;
    
    private:
        QString m_defaultText;
        QHash<int, TextItemWidgetFactory*> m_editors;
    
    private slots:
        void onFinished(QWidget* widget);
    
    };
    
    #endif // ECFPARAMETERTREEDELEGATE_H
    
    #include "ecfparametertreedelegate.h"
    
    #include <QPainter>
    #include <QDebug>
    
    #include "textitemwidget.h"
    
    ECFParameterTreeDelegate::ECFParameterTreeDelegate(QObject *parent)
        : QItemDelegate(parent)
    {
    
    }
    
    ECFParameterTreeDelegate::~ECFParameterTreeDelegate()
    {
        for (auto it = m_editors.begin(); it != m_editors.end(); ++it)
        {
            delete (*it);
        }
    
        this->m_editors.clear();
    }
    
    void ECFParameterTreeDelegate::registerEditor(int editorId, TextItemWidgetFactory *factory)
    {
        this->m_editors[editorId] = factory;
    }
    
    void ECFParameterTreeDelegate::paint(QPainter *painter, const QStyleOptionViewItem &option, const QModelIndex &index) const
    {
        bool ok;
        int editorIndex = index.data(EditorRole).toInt(&ok);
        if (ok
            && this->m_editors[editorIndex] != nullptr
            && dynamic_cast<DataTypeEditWidgetFactory*>(this->m_editors[editorIndex]))
        {
            TextItemWidget *editor = this->m_editors[editorIndex]->create();
            editor->hide();
            editor->resize(option.rect.size());
            QPixmap pixmap(option.rect.size());
            editor->render(&pixmap);
            painter->drawPixmap(option.rect, pixmap);
            delete editor;
        }
        else
        {
            QItemDelegate::paint(painter, option, index);
        }
    }
    
    QSize ECFParameterTreeDelegate::sizeHint(const QStyleOptionViewItem &option, const QModelIndex &index) const
    {
        bool ok;
        int editorIndex = index.data(EditorRole).toInt(&ok);
        if (ok
            && this->m_editors[editorIndex] != nullptr
            && dynamic_cast<DataTypeEditWidgetFactory*>(this->m_editors[editorIndex]))
        {
            TextItemWidget *editor = this->m_editors[editorIndex]->create();
            editor->hide();
            QSize hint = editor->sizeHint();
            delete editor;
    
            qInfo() << "SizeHint" << hint.width() << hint.height();
    
            return hint;
        }
        else
        {
            return QItemDelegate::sizeHint(option, index);
        }
    }
    
    QWidget* ECFParameterTreeDelegate::createEditor(QWidget *parent,
                                        const QStyleOptionViewItem &option,
                                        const QModelIndex &index) const
    {
        int editorIndex = index.data(EditorRole).toInt();
        TextItemWidget *editor = this->m_editors[editorIndex]->create(parent);
        connect(editor, SIGNAL(finished(QWidget*)), this, SLOT(onFinished(QWidget*)));
    
        return editor;
    }
    
    
    void ECFParameterTreeDelegate::setEditorData(QWidget *editor, const QModelIndex &index) const
    {
        QString value = index.model()->data(index, Qt::EditRole).toString();
        TextItemWidget *widget = static_cast<TextItemWidget*>(editor);
        widget->setText(value);
    }
    
    
    void ECFParameterTreeDelegate::setModelData(QWidget *editor, QAbstractItemModel *model, const QModelIndex &index) const
    {
        TextItemWidget *widget = static_cast<TextItemWidget*>(editor);
        QString value = widget->text();
        model->setData(index, value);
    }
    
    
    void ECFParameterTreeDelegate::updateEditorGeometry(QWidget *editor, const QStyleOptionViewItem &option, const QModelIndex &index) const
    {
        editor->setGeometry(option.rect);
    }
    
    void ECFParameterTreeDelegate::onFinished(QWidget *widget)
    {
        this->commitData(widget);
    }
    


  • Finally solved! :-) The DataTypeWidget was not returning a different value via the text() method when the option in the combo box changed.

    Thank you @VRonin one more time. Have a nice day.

    0_1521199779678_qt_delegate_solved.gif


Log in to reply
 

Looks like your connection to Qt Forum was lost, please wait while we try to reconnect.