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.
QtWS25 Last Chance

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

Scheduled Pinned Locked Moved Unsolved General and Desktop
c++ qt6qtreewidgetqtreeviewdelegate
5 Posts 2 Posters 579 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 26 Sept 2023, 14:06 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
    • S Offline
      S Offline
      SGaist
      Lifetime Qt Champion
      wrote on 26 Sept 2023, 17:12 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 26 Sept 2023, 18:02
      1
      • S SGaist
        26 Sept 2023, 17:12

        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 26 Sept 2023, 18:02 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 27 Sept 2023, 08:05 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

          S 1 Reply Last reply 27 Sept 2023, 19:22
          0
          • S StudentScripter
            27 Sept 2023, 08:05

            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

            S Offline
            S Offline
            SGaist
            Lifetime Qt Champion
            wrote on 27 Sept 2023, 19:22 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

            4/5

            27 Sept 2023, 08:05

            • Login

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