Skip to content
  • Categories
  • Recent
  • Tags
  • Popular
  • Users
  • Groups
  • Search
  • Get Qt Extensions
  • Unsolved
Collapse
Brand Logo
  1. Home
  2. Qt Development
  3. General and Desktop
  4. Photoshop layer like QTreeWidget Qt6 C++ - Help needed.

Photoshop layer like QTreeWidget Qt6 C++ - Help needed.

Scheduled Pinned Locked Moved Unsolved General and Desktop
c++ qt6qtreewidgetqtreeviewdelegate
5 Posts 2 Posters 581 Views
  • Oldest to Newest
  • Newest to Oldest
  • Most Votes
Reply
  • Reply as topic
Log in to reply
This topic has been deleted. Only users with topic management privileges can see it.
  • S Offline
    S Offline
    StudentScripter
    wrote on last edited by
    #1

    Hello,

    I wanted to create a photoshop layer like system, but as im still learning im kinda struggeling. I first tried using a delegate but as i was stuck i switched to declaring the controls in the item directly.

    What i want:
    One layer should consist of [Icon, LineEdit, Checkbox]. Each layer should have a height of 40px, should highlight on hover over and should be groupable (be able to be put as child widget of another, just like with layers in photoshop). Here is an picture of how such layers should look like: LAyerView.PNG

    So far i created a custom QWidget subclass which i set for my QTreeWidgetItem to achieve this layout. However hovering does not work good and the custom controls get lost once dragging my custom widget below another QTreeWidgetItem (grouping).

    Here is my cutomwidget.cpp:

    #include "ViewLayerCustomItem.h"
    
    
    #include <QHBoxLayout>
    #include <QLabel>
    #include <QLineEdit>
    #include <QCheckBox>
    #include <QPixmap>
    #include <QPalette>
    #include <QStyle>
    #include <QApplication>
    
    ViewLayerCustomItem::ViewLayerCustomItem(QWidget *parent)
        : QWidget(parent)
    {
    
    
    // Erstellen Sie ein Layout für das benutzerdefinierte Widget.
    QHBoxLayout* layout = new QHBoxLayout();
    
    
    QLabel* iconLabel = new QLabel();
    iconLabel->setPixmap(QPixmap("://resource/quick.png").scaled(32, 32, Qt::KeepAspectRatio));
    layout->addWidget(iconLabel);
    
    
    QLineEdit* lineEdit = new QLineEdit();
    layout->addWidget(lineEdit);
    lineEdit->setReadOnly(false);
    lineEdit->setFrame(false);
    lineEdit->setPlaceholderText("<Empty>");
    
    
    QCheckBox* checkBox = new QCheckBox("");
    layout->addWidget(checkBox);
    
    
    setLayout(layout);
    
    }
    
    
    void ViewLayerCustomItem::enterEvent(QEnterEvent *event)
    {
        QString hoverStyle = "background-color: #E6F7FF; color: #000000;";
            
        setStyleSheet(hoverStyle);
    }
    
    void ViewLayerCustomItem::leaveEvent(QEvent *event)
    {
    
        setStyleSheet("");
    }
    
    

    treewidget.cpp:

    #include "ViewLayerList.h"
    #include <QHBoxLayout>
    #include <QCheckBox>
    #include <QLabel>
    #include <QMouseEvent>
    #include "SignalManager.h"
    #include <QHeaderView>
    #include <QPushButton>
    #include "ViewLayerCustomItem.h"
    
    
    ViewLayerList::ViewLayerList(CustomGraphicsScene *scene, QWidget *parent)
        : QTreeWidget{parent}, scene_durchgereicht(scene)
    {
    
     
    this->setHeaderHidden(true);
    this->setRootIsDecorated(true);
    
    
    
    
    this->setFocusPolicy(Qt::NoFocus);
    
    
    
    QTreeWidgetItem* item = new QTreeWidgetItem(this);
    
    
    
    
    ViewLayerCustomItem *customWidget = new ViewLayerCustomItem();
    
    this->setItemWidget(item, 0, customWidget);
    
    
    this->addTopLevelItem(item);
    
    
    
    
    
    
    QTreeWidgetItem *item2 = new QTreeWidgetItem(this);
    this->addTopLevelItem(item2);
    
    
    
    this->setDragDropMode(QAbstractItemView::InternalMove);
    this->setSelectionMode(QAbstractItemView::ExtendedSelection);
    this->setDragEnabled(true);
    this->setAcceptDrops(true);
    this->setDropIndicatorShown(true);
    
    }
    

    Any help is appreciated so much. Have been struggeling with this for so many days on my own now, but guess im just to noobie still. :)

    1 Reply Last reply
    0
    • SGaistS Offline
      SGaistS Offline
      SGaist
      Lifetime Qt Champion
      wrote on last edited by
      #2

      Hi and welcome to devnet,

      You should rather check QStyledItemDelegate. This allows you to render exactly what you want. You can also implement custom interaction such as clicking on the checkbox. Bonus: you already have support for the drag and drop part though you will have to implement the grouping part yourself.

      Interested in AI ? www.idiap.ch
      Please read the Qt Code of Conduct - https://forum.qt.io/topic/113070/qt-code-of-conduct

      S 1 Reply Last reply
      1
      • SGaistS SGaist

        Hi and welcome to devnet,

        You should rather check QStyledItemDelegate. This allows you to render exactly what you want. You can also implement custom interaction such as clicking on the checkbox. Bonus: you already have support for the drag and drop part though you will have to implement the grouping part yourself.

        S Offline
        S Offline
        StudentScripter
        wrote on last edited by StudentScripter
        #3

        @SGaist Thank you very much. <3 Really appreciate that. Actually i tried QStyledItemDelegate but than got stuck cause of the highlighting and grouping part.

        Here is what my text delegate code looked like:

        delegate.cpp:

        #include "ViewLayerItemDelegate.h"
        #include <QStyledItemDelegate>
        #include <QPainter>
        #include <QApplication>
        
        
        ViewLayerItemDelegate::ViewLayerItemDelegate(QObject *parent)
            : QStyledItemDelegate{parent}
        {
        
        }
        
        
        
        
        QWidget *ViewLayerItemDelegate::createEditor(QWidget *parent, const QStyleOptionViewItem &option, const QModelIndex &index) const
        {
            qDebug() << "Editor created";
            
            LineEditCheckBoxWidget *editor = new LineEditCheckBoxWidget(parent);
            return editor;
        }
        
        
        
        
        void ViewLayerItemDelegate::setEditorData(QWidget *editor, const QModelIndex &index) const
        {
        
            
            LineEditCheckBoxWidget *widget = static_cast<LineEditCheckBoxWidget *>(editor);
        
            // Setzen Sie die Werte der SpinBox und CheckBox basierend auf den Modellwerten
            QString lineEditvalue = index.model()->data(index, Qt::EditRole).toString();
            bool checkBoxValue = index.model()->data(index, Qt::CheckStateRole).toBool();
        
            widget->lineEdit->setText(lineEditvalue);
            widget->checkBox->setChecked(checkBoxValue);
        }
        
        
        
        
        void ViewLayerItemDelegate::setModelData(QWidget *editor, QAbstractItemModel *model, const QModelIndex &index) const
        {
            
            
            LineEditCheckBoxWidget *widget = static_cast<LineEditCheckBoxWidget *>(editor);
        
         
            QString lineEditvalue = widget->lineEdit->text();
            bool checkBoxValue = widget->checkBox->isChecked();
        
            model->setData(index, lineEditvalue, Qt::EditRole);
            model->setData(index, checkBoxValue ? Qt::Checked : Qt::Unchecked, Qt::CheckStateRole);
        }
        
        
        
        
        void ViewLayerItemDelegate::updateEditorGeometry(QWidget *editor, const QStyleOptionViewItem &option, const QModelIndex &index) const
        {
            editor->setGeometry(option.rect);
        }
        
        
        
        
        QSize ViewLayerItemDelegate::sizeHint(const QStyleOptionViewItem &option, const QModelIndex &index) const
        {
            
            QSize size = QStyledItemDelegate::sizeHint(option, index);
                size.setHeight(40); // Setzen Sie hier die gewünschte Höhe
            return size;
        }
        
        
        
        
        
        
        void ViewLayerItemDelegate::paint(QPainter *painter, const QStyleOptionViewItem &option, const QModelIndex &index) const
        {
        
            
            
           LineEditCheckBoxWidget widget;
            
           
            QString lineEditvalue = index.model()->data(index, Qt::EditRole).toString();
            bool checkBoxValue = index.model()->data(index, Qt::CheckStateRole).toBool();
        
            widget.lineEdit->setText(lineEditvalue);
            widget.checkBox->setChecked(checkBoxValue);
        
            widget.resize(option.rect.size());  
        
            
            QPixmap pixmap(widget.size());
            widget.render(&pixmap);
            painter->drawPixmap(option.rect, pixmap);
        }
        
        

        and here is my delegate.h:

        #ifndef VIEWLAYERITEMDELEGATE_H
        #define VIEWLAYERITEMDELEGATE_H
        
        #include <QStyledItemDelegate>
        #include <QModelIndex>
        #include <QObject>
        #include <QSize>
        #include <QLineEdit>
        #include <QStandardItemModel>
        #include <QCheckBox>
        #include <QFormLayout>
        
        
        
        // Definieren Sie das benutzerdefinierte Widget
        class LineEditCheckBoxWidget : public QWidget {
            Q_OBJECT
        public:
            QLineEdit *lineEdit;
            QCheckBox *checkBox;
        
            LineEditCheckBoxWidget(QWidget *parent = nullptr) : QWidget(parent) {
                QHBoxLayout *layout = new QHBoxLayout(this);
                layout->setContentsMargins(10,0,20,0);
                layout->setSpacing(0);
                lineEdit = new QLineEdit(this);
                checkBox = new QCheckBox(this);
                layout->addWidget(lineEdit);
                layout->addStretch(1);
                layout->addWidget(checkBox);
            }
            
        };
        
        
        
        
        
        class ViewLayerItemDelegate : public QStyledItemDelegate
        {
            Q_OBJECT
        public:
            explicit ViewLayerItemDelegate(QObject *parent = nullptr);
            
            
            
            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;
            
            QSize sizeHint(const QStyleOptionViewItem &option, const QModelIndex &index) const override;
            void paint(QPainter *painter, const QStyleOptionViewItem &option, const QModelIndex &index) const override;
            
        
        
        };
           
        
        #endif // VIEWLAYERITEMDELEGATE_H
        
        

        ´

        and thats how i called it in my treeview subclass:

        /*
        mydelegate = new ViewLayerItemDelegate(this);
        
        model = new QStandardItemModel(10,1,this);
        
        
        for(int row = 0; row < 10; ++row)
        {
            for(int col = 0; col < 1; ++col)
            {
                QModelIndex index = model->index(row, col, QModelIndex());
                model->setData(index, 0);
            }
        
        }
        
        this->setModel(model);
        this->setItemDelegate(mydelegate);
        */
        

        How to go about the highlighting on hover over? How to go about the grouping I have actually no good glue.

        1 Reply Last reply
        0
        • S Offline
          S Offline
          StudentScripter
          wrote on last edited by StudentScripter
          #4

          Any hints on how to get the highlighting working? I guess i somehow have to do this from my treeview.

          EDIT: i found this post, similar to what i want but i just can't get i working for my case. Please can anyone with a little more knowledge help me here:
          evileg - highlighting QTableView

          SGaistS 1 Reply Last reply
          0
          • S StudentScripter

            Any hints on how to get the highlighting working? I guess i somehow have to do this from my treeview.

            EDIT: i found this post, similar to what i want but i just can't get i working for my case. Please can anyone with a little more knowledge help me here:
            evileg - highlighting QTableView

            SGaistS Offline
            SGaistS Offline
            SGaist
            Lifetime Qt Champion
            wrote on last edited by
            #5

            @StudentScripter For the grouping you have to use an adequate data structure.

            As for hovering, IIRC, you have to have mouse tracking enabled on the view.

            Interested in AI ? www.idiap.ch
            Please read the Qt Code of Conduct - https://forum.qt.io/topic/113070/qt-code-of-conduct

            1 Reply Last reply
            0

            • Login

            • Login or register to search.
            • First post
              Last post
            0
            • Categories
            • Recent
            • Tags
            • Popular
            • Users
            • Groups
            • Search
            • Get Qt Extensions
            • Unsolved