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. QStyledItemDelegate highlighting Indentation space on focus?
QtWS25 Last Chance

QStyledItemDelegate highlighting Indentation space on focus?

Scheduled Pinned Locked Moved Solved General and Desktop
qt c++delegatehelpproblemqtreeview
19 Posts 5 Posters 2.1k 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

    So i created my QStyledItemDelegate and actually highlighting the delegate does work, but the identation space of my QTreeView stays white. I want the identationspace to get highlighted too.

    Here is how it looks like right now: febae6c7-5d1c-4ead-acc5-fb2bb0a8a9fa-image.png

    Ps: it would be even better if the identation space would be gone if there is no item grouped below, but still the whole entry should be highlighted blue.

    Here is my code for the delegate, please help me:
    .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);
        if (option.state & QStyle::State_Selected) {
            //editor->setStyleSheet("background-color: lightblue;");
        }
    
       // Verbinden Sie das textChanged() Signal des LineEdits mit Ihrem Slot
        connect(editor->lineEdit, &QLineEdit::textChanged, this, &ViewLayerItemDelegate::onLineEditTextChanged);
    
    
    
        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);
        
        
    
    
        widget->lineEdit->setFocus(Qt::MouseFocusReason); // Editor aktivieren
        widget->lineEdit->setStyleSheet("");
        widget->iconLabel->setAttribute(Qt::WA_TranslucentBackground);
        widget->setStyleSheet("background: white");
            
    }
    
    
    
    
    void ViewLayerItemDelegate::setModelData(QWidget *editor, QAbstractItemModel *model, const QModelIndex &index) const
    {
        
        
        LineEditCheckBoxWidget *widget = static_cast<LineEditCheckBoxWidget *>(editor);
    
        
    
        // Speichern Sie die Werte der SpinBox und CheckBox im Modell
        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);
        
        qDebug() << "Model data set";
    }
    
    
    
    
    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
    {
        QStyleOptionViewItem opt = option;
        initStyleOption(&opt, index);
    
        LineEditCheckBoxWidget widget;
    
        // 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);
    
        // Laden Sie das Icon und setzen Sie es auf das QLabel
        QPixmap iconPixmap("://resource/quick.png"); // Ersetzen Sie dies durch den Pfad zu Ihrer Icon-Datei
        QPixmap scaledPixmap = iconPixmap.scaled(32, 32, Qt::KeepAspectRatio, Qt::SmoothTransformation);
        widget.iconLabel->setPixmap(scaledPixmap);
    
       
    
        // Passen Sie das Aussehen des Widgets basierend auf der QStyleOptionViewItem an
        if (opt.state & QStyle::State_Selected) {
        
            widget.setStyleSheet("background-color: lightblue;");
            
        }else{
        qDebug() << "Test"; 
        widget.setStyleSheet("background-color: white");
        }
    
        widget.resize(option.rect.size()); // Stellen Sie sicher, dass die Größe des Widgets der Größe des Elements entspricht
    
        // Rendern Sie das Widget in den Painter
        QPixmap pixmap(widget.size());
        widget.render(&pixmap);
    
        // Zeichnen Sie das Pixmap mit dem QPainter
        painter->drawPixmap(option.rect.topLeft(), pixmap);
    }
    
    
    
    
    // Slot-Implementierung
    void ViewLayerItemDelegate::onLineEditTextChanged(const QString &text)
    {
        // Hier können Sie die gewünschte Aktion ausführen, wenn der Text im LineEdit bearbeitet wird
        qDebug() << "LineEdit text changed to:" << text;
    }
    
    
    
    
    
    
    
    
    
    void LineEditCheckBoxWidget::mousePressEvent(QMouseEvent *event)
    {
        qDebug() << "Test clicked";
    
        QWidget::mousePressEvent(event);
    }
    
    

    and here delegate.h:

    #ifndef VIEWLAYERITEMDELEGATE_H
    #define VIEWLAYERITEMDELEGATE_H
    
    #include <QStyledItemDelegate>
    #include <QModelIndex>
    #include <QObject>
    #include <QSize>
    #include <QLineEdit>
    #include <QStandardItemModel>
    #include <QCheckBox>
    #include <QFormLayout>
    #include <QLabel>
    #include <QPushButton>
    
    
    
    
    // Definieren Sie das benutzerdefinierte Widget
    class LineEditCheckBoxWidget : public QWidget {
        Q_OBJECT
    public:
        QLineEdit *lineEdit;
        QCheckBox *checkBox;
        QLabel *iconLabel;
    
    
        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);
            iconLabel = new QLabel(this);
    
    
            // Laden Sie das Icon und setzen Sie es auf das QLabel
            QPixmap iconPixmap("://resource/quick.png"); // Ersetzen Sie dies durch den Pfad zu Ihrer Icon-Datei
            QPixmap scaledPixmap = iconPixmap.scaled(32, 32, Qt::KeepAspectRatio, Qt::SmoothTransformation);
            iconLabel->setPixmap(scaledPixmap);
    
    
    
            layout->addWidget(iconLabel);
            layout->addSpacing(10);
            layout->addWidget(lineEdit);
            layout->addStretch(1);
            layout->addWidget(checkBox);
    
            // Zugriff auf das QLineEdit-Widget und setzen Sie den Hintergrund transparent
            lineEdit->setStyleSheet("background: transparent;");
            lineEdit->setFrame(false);
            lineEdit->setPlaceholderText("<Empty>");
    
            checkBox->setStyleSheet("background: transparent");
        }
        
        // QWidget interface
    protected:
        void mousePressEvent(QMouseEvent *event) override;
        
    signals:
    
    };
    
    
    
    
    
    
    
    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;
        
        
        
    public slots:
        
        void onLineEditTextChanged(const QString &text);
    
    
    signals:
        
        
        
        
        
        
    
    };
       
    
    #endif // VIEWLAYERITEMDELEGATE_H
    
    

    Thanks for helping, really really appreciate that. <3

    Christian EhrlicherC Chris KawaC qwasder85Q 3 Replies Last reply
    0
    • S StudentScripter

      So i created my QStyledItemDelegate and actually highlighting the delegate does work, but the identation space of my QTreeView stays white. I want the identationspace to get highlighted too.

      Here is how it looks like right now: febae6c7-5d1c-4ead-acc5-fb2bb0a8a9fa-image.png

      Ps: it would be even better if the identation space would be gone if there is no item grouped below, but still the whole entry should be highlighted blue.

      Here is my code for the delegate, please help me:
      .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);
          if (option.state & QStyle::State_Selected) {
              //editor->setStyleSheet("background-color: lightblue;");
          }
      
         // Verbinden Sie das textChanged() Signal des LineEdits mit Ihrem Slot
          connect(editor->lineEdit, &QLineEdit::textChanged, this, &ViewLayerItemDelegate::onLineEditTextChanged);
      
      
      
          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);
          
          
      
      
          widget->lineEdit->setFocus(Qt::MouseFocusReason); // Editor aktivieren
          widget->lineEdit->setStyleSheet("");
          widget->iconLabel->setAttribute(Qt::WA_TranslucentBackground);
          widget->setStyleSheet("background: white");
              
      }
      
      
      
      
      void ViewLayerItemDelegate::setModelData(QWidget *editor, QAbstractItemModel *model, const QModelIndex &index) const
      {
          
          
          LineEditCheckBoxWidget *widget = static_cast<LineEditCheckBoxWidget *>(editor);
      
          
      
          // Speichern Sie die Werte der SpinBox und CheckBox im Modell
          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);
          
          qDebug() << "Model data set";
      }
      
      
      
      
      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
      {
          QStyleOptionViewItem opt = option;
          initStyleOption(&opt, index);
      
          LineEditCheckBoxWidget widget;
      
          // 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);
      
          // Laden Sie das Icon und setzen Sie es auf das QLabel
          QPixmap iconPixmap("://resource/quick.png"); // Ersetzen Sie dies durch den Pfad zu Ihrer Icon-Datei
          QPixmap scaledPixmap = iconPixmap.scaled(32, 32, Qt::KeepAspectRatio, Qt::SmoothTransformation);
          widget.iconLabel->setPixmap(scaledPixmap);
      
         
      
          // Passen Sie das Aussehen des Widgets basierend auf der QStyleOptionViewItem an
          if (opt.state & QStyle::State_Selected) {
          
              widget.setStyleSheet("background-color: lightblue;");
              
          }else{
          qDebug() << "Test"; 
          widget.setStyleSheet("background-color: white");
          }
      
          widget.resize(option.rect.size()); // Stellen Sie sicher, dass die Größe des Widgets der Größe des Elements entspricht
      
          // Rendern Sie das Widget in den Painter
          QPixmap pixmap(widget.size());
          widget.render(&pixmap);
      
          // Zeichnen Sie das Pixmap mit dem QPainter
          painter->drawPixmap(option.rect.topLeft(), pixmap);
      }
      
      
      
      
      // Slot-Implementierung
      void ViewLayerItemDelegate::onLineEditTextChanged(const QString &text)
      {
          // Hier können Sie die gewünschte Aktion ausführen, wenn der Text im LineEdit bearbeitet wird
          qDebug() << "LineEdit text changed to:" << text;
      }
      
      
      
      
      
      
      
      
      
      void LineEditCheckBoxWidget::mousePressEvent(QMouseEvent *event)
      {
          qDebug() << "Test clicked";
      
          QWidget::mousePressEvent(event);
      }
      
      

      and here delegate.h:

      #ifndef VIEWLAYERITEMDELEGATE_H
      #define VIEWLAYERITEMDELEGATE_H
      
      #include <QStyledItemDelegate>
      #include <QModelIndex>
      #include <QObject>
      #include <QSize>
      #include <QLineEdit>
      #include <QStandardItemModel>
      #include <QCheckBox>
      #include <QFormLayout>
      #include <QLabel>
      #include <QPushButton>
      
      
      
      
      // Definieren Sie das benutzerdefinierte Widget
      class LineEditCheckBoxWidget : public QWidget {
          Q_OBJECT
      public:
          QLineEdit *lineEdit;
          QCheckBox *checkBox;
          QLabel *iconLabel;
      
      
          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);
              iconLabel = new QLabel(this);
      
      
              // Laden Sie das Icon und setzen Sie es auf das QLabel
              QPixmap iconPixmap("://resource/quick.png"); // Ersetzen Sie dies durch den Pfad zu Ihrer Icon-Datei
              QPixmap scaledPixmap = iconPixmap.scaled(32, 32, Qt::KeepAspectRatio, Qt::SmoothTransformation);
              iconLabel->setPixmap(scaledPixmap);
      
      
      
              layout->addWidget(iconLabel);
              layout->addSpacing(10);
              layout->addWidget(lineEdit);
              layout->addStretch(1);
              layout->addWidget(checkBox);
      
              // Zugriff auf das QLineEdit-Widget und setzen Sie den Hintergrund transparent
              lineEdit->setStyleSheet("background: transparent;");
              lineEdit->setFrame(false);
              lineEdit->setPlaceholderText("<Empty>");
      
              checkBox->setStyleSheet("background: transparent");
          }
          
          // QWidget interface
      protected:
          void mousePressEvent(QMouseEvent *event) override;
          
      signals:
      
      };
      
      
      
      
      
      
      
      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;
          
          
          
      public slots:
          
          void onLineEditTextChanged(const QString &text);
      
      
      signals:
          
          
          
          
          
          
      
      };
         
      
      #endif // VIEWLAYERITEMDELEGATE_H
      
      

      Thanks for helping, really really appreciate that. <3

      Christian EhrlicherC Offline
      Christian EhrlicherC Offline
      Christian Ehrlicher
      Lifetime Qt Champion
      wrote on last edited by
      #2

      This is not possible without creating an own (proxy)style and re-implement drawPrimitive() for PE_IndicatorBranch

      Qt Online Installer direct download: https://download.qt.io/official_releases/online_installers/
      Visit the Qt Academy at https://academy.qt.io/catalog

      1 Reply Last reply
      0
      • S StudentScripter

        So i created my QStyledItemDelegate and actually highlighting the delegate does work, but the identation space of my QTreeView stays white. I want the identationspace to get highlighted too.

        Here is how it looks like right now: febae6c7-5d1c-4ead-acc5-fb2bb0a8a9fa-image.png

        Ps: it would be even better if the identation space would be gone if there is no item grouped below, but still the whole entry should be highlighted blue.

        Here is my code for the delegate, please help me:
        .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);
            if (option.state & QStyle::State_Selected) {
                //editor->setStyleSheet("background-color: lightblue;");
            }
        
           // Verbinden Sie das textChanged() Signal des LineEdits mit Ihrem Slot
            connect(editor->lineEdit, &QLineEdit::textChanged, this, &ViewLayerItemDelegate::onLineEditTextChanged);
        
        
        
            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);
            
            
        
        
            widget->lineEdit->setFocus(Qt::MouseFocusReason); // Editor aktivieren
            widget->lineEdit->setStyleSheet("");
            widget->iconLabel->setAttribute(Qt::WA_TranslucentBackground);
            widget->setStyleSheet("background: white");
                
        }
        
        
        
        
        void ViewLayerItemDelegate::setModelData(QWidget *editor, QAbstractItemModel *model, const QModelIndex &index) const
        {
            
            
            LineEditCheckBoxWidget *widget = static_cast<LineEditCheckBoxWidget *>(editor);
        
            
        
            // Speichern Sie die Werte der SpinBox und CheckBox im Modell
            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);
            
            qDebug() << "Model data set";
        }
        
        
        
        
        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
        {
            QStyleOptionViewItem opt = option;
            initStyleOption(&opt, index);
        
            LineEditCheckBoxWidget widget;
        
            // 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);
        
            // Laden Sie das Icon und setzen Sie es auf das QLabel
            QPixmap iconPixmap("://resource/quick.png"); // Ersetzen Sie dies durch den Pfad zu Ihrer Icon-Datei
            QPixmap scaledPixmap = iconPixmap.scaled(32, 32, Qt::KeepAspectRatio, Qt::SmoothTransformation);
            widget.iconLabel->setPixmap(scaledPixmap);
        
           
        
            // Passen Sie das Aussehen des Widgets basierend auf der QStyleOptionViewItem an
            if (opt.state & QStyle::State_Selected) {
            
                widget.setStyleSheet("background-color: lightblue;");
                
            }else{
            qDebug() << "Test"; 
            widget.setStyleSheet("background-color: white");
            }
        
            widget.resize(option.rect.size()); // Stellen Sie sicher, dass die Größe des Widgets der Größe des Elements entspricht
        
            // Rendern Sie das Widget in den Painter
            QPixmap pixmap(widget.size());
            widget.render(&pixmap);
        
            // Zeichnen Sie das Pixmap mit dem QPainter
            painter->drawPixmap(option.rect.topLeft(), pixmap);
        }
        
        
        
        
        // Slot-Implementierung
        void ViewLayerItemDelegate::onLineEditTextChanged(const QString &text)
        {
            // Hier können Sie die gewünschte Aktion ausführen, wenn der Text im LineEdit bearbeitet wird
            qDebug() << "LineEdit text changed to:" << text;
        }
        
        
        
        
        
        
        
        
        
        void LineEditCheckBoxWidget::mousePressEvent(QMouseEvent *event)
        {
            qDebug() << "Test clicked";
        
            QWidget::mousePressEvent(event);
        }
        
        

        and here delegate.h:

        #ifndef VIEWLAYERITEMDELEGATE_H
        #define VIEWLAYERITEMDELEGATE_H
        
        #include <QStyledItemDelegate>
        #include <QModelIndex>
        #include <QObject>
        #include <QSize>
        #include <QLineEdit>
        #include <QStandardItemModel>
        #include <QCheckBox>
        #include <QFormLayout>
        #include <QLabel>
        #include <QPushButton>
        
        
        
        
        // Definieren Sie das benutzerdefinierte Widget
        class LineEditCheckBoxWidget : public QWidget {
            Q_OBJECT
        public:
            QLineEdit *lineEdit;
            QCheckBox *checkBox;
            QLabel *iconLabel;
        
        
            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);
                iconLabel = new QLabel(this);
        
        
                // Laden Sie das Icon und setzen Sie es auf das QLabel
                QPixmap iconPixmap("://resource/quick.png"); // Ersetzen Sie dies durch den Pfad zu Ihrer Icon-Datei
                QPixmap scaledPixmap = iconPixmap.scaled(32, 32, Qt::KeepAspectRatio, Qt::SmoothTransformation);
                iconLabel->setPixmap(scaledPixmap);
        
        
        
                layout->addWidget(iconLabel);
                layout->addSpacing(10);
                layout->addWidget(lineEdit);
                layout->addStretch(1);
                layout->addWidget(checkBox);
        
                // Zugriff auf das QLineEdit-Widget und setzen Sie den Hintergrund transparent
                lineEdit->setStyleSheet("background: transparent;");
                lineEdit->setFrame(false);
                lineEdit->setPlaceholderText("<Empty>");
        
                checkBox->setStyleSheet("background: transparent");
            }
            
            // QWidget interface
        protected:
            void mousePressEvent(QMouseEvent *event) override;
            
        signals:
        
        };
        
        
        
        
        
        
        
        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;
            
            
            
        public slots:
            
            void onLineEditTextChanged(const QString &text);
        
        
        signals:
            
            
            
            
            
            
        
        };
           
        
        #endif // VIEWLAYERITEMDELEGATE_H
        
        

        Thanks for helping, really really appreciate that. <3

        Chris KawaC Online
        Chris KawaC Online
        Chris Kawa
        Lifetime Qt Champion
        wrote on last edited by Chris Kawa
        #3

        The delegate only paints items. The branch and indentation areas are not part of an item, so item delegate doesn't cover them. Depending on your needs you can have an item highlighted or an entire row. If you want entire row highlighted you need to let the view handle it.

        You can override QTreeView::drawBranches and QTreeView::drawRow to paint the entire row, not just the item area.

        S 1 Reply Last reply
        1
        • Chris KawaC Chris Kawa

          The delegate only paints items. The branch and indentation areas are not part of an item, so item delegate doesn't cover them. Depending on your needs you can have an item highlighted or an entire row. If you want entire row highlighted you need to let the view handle it.

          You can override QTreeView::drawBranches and QTreeView::drawRow to paint the entire row, not just the item area.

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

          @Chris-Kawa Thank you, i tried this approach but im getting quite wierd looking results when i group items below each other, like that:

          The group "headder" is selected:
          6fbb80af-11ab-4e0e-b829-aadf8dcae04e-image.png

          The grouped object is selected:
          837a6e50-3578-4a89-9bdc-176b97e82089-image.png

          Here is my code:

          #include "ViewLayerList.h"
          #include <QHBoxLayout>
          #include <QCheckBox>
          #include <QLabel>
          #include "ViewLayerLineEdit.h"
          #include <QMouseEvent>
          #include "resizablepixmapitem.h"
          #include "SignalManager.h"
          #include <QHeaderView>
          #include <QPushButton>
          #include "ViewLayerCustomItem.h"
          
          
          
          
          
          ViewLayerList::ViewLayerList(CustomGraphicsScene *scene, QWidget *parent)
              : QTreeView{parent}, scene_durchgereicht(scene)
          {
              setHeaderHidden(true);
              setRootIsDecorated(true);
          
          
          
          
          
          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, "");
                
                 
              }
          
          }
          
          
          this->setModel(model);
          this->setItemDelegate(mydelegate);
          
          
          
           //QModelIndex index = model->index(0, 0);
           // this->openPersistentEditor(index);
          
          
          
          this->setDragDropMode(QAbstractItemView::InternalMove);
          this->setSelectionMode(QAbstractItemView::ExtendedSelection);
          this->setDragEnabled(true);
          this->setAcceptDrops(true);
          this->setDropIndicatorShown(true);
          
          
          
          }
          
          
          
          
          
          
          
          void ViewLayerList::drawRow(QPainter *painter, const QStyleOptionViewItem &options, const QModelIndex &index) const
          {
             
          
          
              QModelIndexList selectedIndexes = selectionModel()->selectedIndexes();
          
              for (const QModelIndex& selectedIndex : selectedIndexes) {
                  if (selectedIndex.row() == index.row()) {
                 
                      QRect indentRect = visualRect(index);
                      indentRect.setRight(options.rect.left());
                      painter->fillRect(indentRect, QColor(173, 216, 230)); 
                      break; 
                  }
              }
             
              
               QTreeView::drawRow(painter, options, index); 
          }
          
          
          

          Thanks for helping me thus far, hope you can give me another hint. :)
          Best regards

          Chris KawaC 1 Reply Last reply
          0
          • S StudentScripter

            @Chris-Kawa Thank you, i tried this approach but im getting quite wierd looking results when i group items below each other, like that:

            The group "headder" is selected:
            6fbb80af-11ab-4e0e-b829-aadf8dcae04e-image.png

            The grouped object is selected:
            837a6e50-3578-4a89-9bdc-176b97e82089-image.png

            Here is my code:

            #include "ViewLayerList.h"
            #include <QHBoxLayout>
            #include <QCheckBox>
            #include <QLabel>
            #include "ViewLayerLineEdit.h"
            #include <QMouseEvent>
            #include "resizablepixmapitem.h"
            #include "SignalManager.h"
            #include <QHeaderView>
            #include <QPushButton>
            #include "ViewLayerCustomItem.h"
            
            
            
            
            
            ViewLayerList::ViewLayerList(CustomGraphicsScene *scene, QWidget *parent)
                : QTreeView{parent}, scene_durchgereicht(scene)
            {
                setHeaderHidden(true);
                setRootIsDecorated(true);
            
            
            
            
            
            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, "");
                  
                   
                }
            
            }
            
            
            this->setModel(model);
            this->setItemDelegate(mydelegate);
            
            
            
             //QModelIndex index = model->index(0, 0);
             // this->openPersistentEditor(index);
            
            
            
            this->setDragDropMode(QAbstractItemView::InternalMove);
            this->setSelectionMode(QAbstractItemView::ExtendedSelection);
            this->setDragEnabled(true);
            this->setAcceptDrops(true);
            this->setDropIndicatorShown(true);
            
            
            
            }
            
            
            
            
            
            
            
            void ViewLayerList::drawRow(QPainter *painter, const QStyleOptionViewItem &options, const QModelIndex &index) const
            {
               
            
            
                QModelIndexList selectedIndexes = selectionModel()->selectedIndexes();
            
                for (const QModelIndex& selectedIndex : selectedIndexes) {
                    if (selectedIndex.row() == index.row()) {
                   
                        QRect indentRect = visualRect(index);
                        indentRect.setRight(options.rect.left());
                        painter->fillRect(indentRect, QColor(173, 216, 230)); 
                        break; 
                    }
                }
               
                
                 QTreeView::drawRow(painter, options, index); 
            }
            
            
            

            Thanks for helping me thus far, hope you can give me another hint. :)
            Best regards

            Chris KawaC Online
            Chris KawaC Online
            Chris Kawa
            Lifetime Qt Champion
            wrote on last edited by Chris Kawa
            #5

            @StudentScripter This condition is wrong:

            if (selectedIndex.row() == index.row())
            

            Note that the first top level item has row == 0 and every first child of any item also has row == 0 ans so on, so that's why you see multiple items colored. You don't need to retrieve the entire list of selected items and loop over them. That's wasteful. It's enough to check if the index you're given is selected:

            void ViewLayerList::drawRow(QPainter *painter, const QStyleOptionViewItem &options, const QModelIndex &index) const
            {
                if (selectionModel()->isSelected(index)) {
                   ...
            

            Also instead of having the delegate color selected item and the view color the remainder of the space you can just remove selection painting from the delegate and let the view paint it for entire row. You wouldn't have to get the visualRect and do the painting twice in parts. A lot of unnecessary calculations omitted.

            S 1 Reply Last reply
            1
            • Chris KawaC Chris Kawa

              @StudentScripter This condition is wrong:

              if (selectedIndex.row() == index.row())
              

              Note that the first top level item has row == 0 and every first child of any item also has row == 0 ans so on, so that's why you see multiple items colored. You don't need to retrieve the entire list of selected items and loop over them. That's wasteful. It's enough to check if the index you're given is selected:

              void ViewLayerList::drawRow(QPainter *painter, const QStyleOptionViewItem &options, const QModelIndex &index) const
              {
                  if (selectionModel()->isSelected(index)) {
                     ...
              

              Also instead of having the delegate color selected item and the view color the remainder of the space you can just remove selection painting from the delegate and let the view paint it for entire row. You wouldn't have to get the visualRect and do the painting twice in parts. A lot of unnecessary calculations omitted.

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

              @Chris-Kawa said in QStyledItemDelegate highlighting Indentation space on focus?:

              First of all: Thank you very much, made me instantly happy this morning when i saw that i received an answer. :)

              I improved the if statement and it works perfectly fine, however i don't get the second part of your answer.
              I tried removing this part from my delegates paint method:

              /*
                  // Passen Sie das Aussehen des Widgets basierend auf der QStyleOptionViewItem an
                  if (opt.state & QStyle::State_Selected) {
                  
                      widget.setStyleSheet("background-color: lightblue;");
                      
                  }else{
              
                  widget.setStyleSheet("background-color: white");
                  }
              */
              

              However this way my delegate only appears with a grayish background (i want it to be white) and does not get the selected blueish color.

              Here is a picture visualizing what i mean:
              f8bb9f43-18cd-4b40-bb70-943fe7b29f9a-image.png

              My draw row statement looks like this now:

              void ViewLayerList::drawRow(QPainter *painter, const QStyleOptionViewItem &options, const QModelIndex &index) const
              {
                 
                  if (selectionModel()->isSelected(index)) {
                  
                  // Zeichnen Sie den Einzugsbereich (Indentation) mit Ihrer gewünschten Farbe
                          QRect indentRect = visualRect(index);
                          indentRect.setRight(options.rect.left()); 
                          painter->fillRect(indentRect, QColor(173, 216, 230));
                  }
              
              
                  
                   QTreeView::drawRow(painter, options, index); // Rufen Sie die Basisimplementierung auf, um die Standardzeichnung durchzuführen
              }
              
              

              Note: i also tried leaving out:

                       indentRect.setRight(options.rect.left()); 
              

              but this did not work.

              1 Reply Last reply
              0
              • S StudentScripter

                So i created my QStyledItemDelegate and actually highlighting the delegate does work, but the identation space of my QTreeView stays white. I want the identationspace to get highlighted too.

                Here is how it looks like right now: febae6c7-5d1c-4ead-acc5-fb2bb0a8a9fa-image.png

                Ps: it would be even better if the identation space would be gone if there is no item grouped below, but still the whole entry should be highlighted blue.

                Here is my code for the delegate, please help me:
                .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);
                    if (option.state & QStyle::State_Selected) {
                        //editor->setStyleSheet("background-color: lightblue;");
                    }
                
                   // Verbinden Sie das textChanged() Signal des LineEdits mit Ihrem Slot
                    connect(editor->lineEdit, &QLineEdit::textChanged, this, &ViewLayerItemDelegate::onLineEditTextChanged);
                
                
                
                    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);
                    
                    
                
                
                    widget->lineEdit->setFocus(Qt::MouseFocusReason); // Editor aktivieren
                    widget->lineEdit->setStyleSheet("");
                    widget->iconLabel->setAttribute(Qt::WA_TranslucentBackground);
                    widget->setStyleSheet("background: white");
                        
                }
                
                
                
                
                void ViewLayerItemDelegate::setModelData(QWidget *editor, QAbstractItemModel *model, const QModelIndex &index) const
                {
                    
                    
                    LineEditCheckBoxWidget *widget = static_cast<LineEditCheckBoxWidget *>(editor);
                
                    
                
                    // Speichern Sie die Werte der SpinBox und CheckBox im Modell
                    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);
                    
                    qDebug() << "Model data set";
                }
                
                
                
                
                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
                {
                    QStyleOptionViewItem opt = option;
                    initStyleOption(&opt, index);
                
                    LineEditCheckBoxWidget widget;
                
                    // 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);
                
                    // Laden Sie das Icon und setzen Sie es auf das QLabel
                    QPixmap iconPixmap("://resource/quick.png"); // Ersetzen Sie dies durch den Pfad zu Ihrer Icon-Datei
                    QPixmap scaledPixmap = iconPixmap.scaled(32, 32, Qt::KeepAspectRatio, Qt::SmoothTransformation);
                    widget.iconLabel->setPixmap(scaledPixmap);
                
                   
                
                    // Passen Sie das Aussehen des Widgets basierend auf der QStyleOptionViewItem an
                    if (opt.state & QStyle::State_Selected) {
                    
                        widget.setStyleSheet("background-color: lightblue;");
                        
                    }else{
                    qDebug() << "Test"; 
                    widget.setStyleSheet("background-color: white");
                    }
                
                    widget.resize(option.rect.size()); // Stellen Sie sicher, dass die Größe des Widgets der Größe des Elements entspricht
                
                    // Rendern Sie das Widget in den Painter
                    QPixmap pixmap(widget.size());
                    widget.render(&pixmap);
                
                    // Zeichnen Sie das Pixmap mit dem QPainter
                    painter->drawPixmap(option.rect.topLeft(), pixmap);
                }
                
                
                
                
                // Slot-Implementierung
                void ViewLayerItemDelegate::onLineEditTextChanged(const QString &text)
                {
                    // Hier können Sie die gewünschte Aktion ausführen, wenn der Text im LineEdit bearbeitet wird
                    qDebug() << "LineEdit text changed to:" << text;
                }
                
                
                
                
                
                
                
                
                
                void LineEditCheckBoxWidget::mousePressEvent(QMouseEvent *event)
                {
                    qDebug() << "Test clicked";
                
                    QWidget::mousePressEvent(event);
                }
                
                

                and here delegate.h:

                #ifndef VIEWLAYERITEMDELEGATE_H
                #define VIEWLAYERITEMDELEGATE_H
                
                #include <QStyledItemDelegate>
                #include <QModelIndex>
                #include <QObject>
                #include <QSize>
                #include <QLineEdit>
                #include <QStandardItemModel>
                #include <QCheckBox>
                #include <QFormLayout>
                #include <QLabel>
                #include <QPushButton>
                
                
                
                
                // Definieren Sie das benutzerdefinierte Widget
                class LineEditCheckBoxWidget : public QWidget {
                    Q_OBJECT
                public:
                    QLineEdit *lineEdit;
                    QCheckBox *checkBox;
                    QLabel *iconLabel;
                
                
                    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);
                        iconLabel = new QLabel(this);
                
                
                        // Laden Sie das Icon und setzen Sie es auf das QLabel
                        QPixmap iconPixmap("://resource/quick.png"); // Ersetzen Sie dies durch den Pfad zu Ihrer Icon-Datei
                        QPixmap scaledPixmap = iconPixmap.scaled(32, 32, Qt::KeepAspectRatio, Qt::SmoothTransformation);
                        iconLabel->setPixmap(scaledPixmap);
                
                
                
                        layout->addWidget(iconLabel);
                        layout->addSpacing(10);
                        layout->addWidget(lineEdit);
                        layout->addStretch(1);
                        layout->addWidget(checkBox);
                
                        // Zugriff auf das QLineEdit-Widget und setzen Sie den Hintergrund transparent
                        lineEdit->setStyleSheet("background: transparent;");
                        lineEdit->setFrame(false);
                        lineEdit->setPlaceholderText("<Empty>");
                
                        checkBox->setStyleSheet("background: transparent");
                    }
                    
                    // QWidget interface
                protected:
                    void mousePressEvent(QMouseEvent *event) override;
                    
                signals:
                
                };
                
                
                
                
                
                
                
                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;
                    
                    
                    
                public slots:
                    
                    void onLineEditTextChanged(const QString &text);
                
                
                signals:
                    
                    
                    
                    
                    
                    
                
                };
                   
                
                #endif // VIEWLAYERITEMDELEGATE_H
                
                

                Thanks for helping, really really appreciate that. <3

                qwasder85Q Offline
                qwasder85Q Offline
                qwasder85
                wrote on last edited by qwasder85
                #7

                @StudentScripter Have you tried a simple stylesheet such as this:

                QTreeView::item:selected
                {
                    background-color: red;
                }
                
                QTreeView::branch:selected
                {
                    background-color: red;
                }
                

                No need to handle the painting manually.

                S 1 Reply Last reply
                0
                • qwasder85Q qwasder85

                  @StudentScripter Have you tried a simple stylesheet such as this:

                  QTreeView::item:selected
                  {
                      background-color: red;
                  }
                  
                  QTreeView::branch:selected
                  {
                      background-color: red;
                  }
                  

                  No need to handle the painting manually.

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

                  @qwasder85 Yes thank you, i tried it but you have to know that i have implemented a paint methode for my delegate in order to display the controls as pixmap, even when the editor is not open:

                  delegate.cpp:

                  void ViewLayerItemDelegate::paint(QPainter *painter, const QStyleOptionViewItem &option, const QModelIndex &index) const
                  {
                      QStyleOptionViewItem opt = option;
                      initStyleOption(&opt, index);
                  
                      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);
                  
                  
                      QPixmap iconPixmap("://resource/quick.png"); // Ersetzen Sie dies durch den Pfad zu Ihrer Icon-Datei
                      QPixmap scaledPixmap = iconPixmap.scaled(32, 32, Qt::KeepAspectRatio, Qt::SmoothTransformation);
                      widget.iconLabel->setPixmap(scaledPixmap);
                  
                     
                  
                      if (opt.state & QStyle::State_Selected) {
                      
                      widget.setStyleSheet("background-color: lightblue;");
                          
                      }else{
                  
                      widget.setStyleSheet("background-color: white");
                      }
                  
                      widget.resize(option.rect.size()); 
                  
                  
                      QPixmap pixmap(widget.size());
                      widget.render(&pixmap);
                  
                      painter->drawPixmap(option.rect.topLeft(), pixmap);
                  }
                  
                  

                  implementing a stylesheet for branch highlighting in the treeview like this:

                  QTreeView.cpp

                  
                  ViewLayerList::ViewLayerList(CustomGraphicsScene *scene, QWidget *parent)
                      : QTreeView{parent}, scene_durchgereicht(scene)
                  {
                  
                   // Setzen Sie das Stylesheet für den ausgewählten Zweig hier
                      setStyleSheet("QTreeView::item:selected { background-color: yellow; }");
                  }
                  

                  (i also tried branch, row .... isn't cutting it) always ends up looking like:
                  5d4e95c2-c4fa-4f55-9f1f-a45a8b1bc58d-image.png

                  vs. this with my delegate code: (so it looks like it should look like) but as @Chris-Kawa mentioned, thats not a good way to do it, so im looking for a better way instead of painting the highlight twice, once in my delegate and once in my QTreeView
                  66ea05a2-eead-4a97-ab47-9926a3b3d181-image.png

                  Chris KawaC 1 Reply Last reply
                  0
                  • S StudentScripter

                    @qwasder85 Yes thank you, i tried it but you have to know that i have implemented a paint methode for my delegate in order to display the controls as pixmap, even when the editor is not open:

                    delegate.cpp:

                    void ViewLayerItemDelegate::paint(QPainter *painter, const QStyleOptionViewItem &option, const QModelIndex &index) const
                    {
                        QStyleOptionViewItem opt = option;
                        initStyleOption(&opt, index);
                    
                        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);
                    
                    
                        QPixmap iconPixmap("://resource/quick.png"); // Ersetzen Sie dies durch den Pfad zu Ihrer Icon-Datei
                        QPixmap scaledPixmap = iconPixmap.scaled(32, 32, Qt::KeepAspectRatio, Qt::SmoothTransformation);
                        widget.iconLabel->setPixmap(scaledPixmap);
                    
                       
                    
                        if (opt.state & QStyle::State_Selected) {
                        
                        widget.setStyleSheet("background-color: lightblue;");
                            
                        }else{
                    
                        widget.setStyleSheet("background-color: white");
                        }
                    
                        widget.resize(option.rect.size()); 
                    
                    
                        QPixmap pixmap(widget.size());
                        widget.render(&pixmap);
                    
                        painter->drawPixmap(option.rect.topLeft(), pixmap);
                    }
                    
                    

                    implementing a stylesheet for branch highlighting in the treeview like this:

                    QTreeView.cpp

                    
                    ViewLayerList::ViewLayerList(CustomGraphicsScene *scene, QWidget *parent)
                        : QTreeView{parent}, scene_durchgereicht(scene)
                    {
                    
                     // Setzen Sie das Stylesheet für den ausgewählten Zweig hier
                        setStyleSheet("QTreeView::item:selected { background-color: yellow; }");
                    }
                    

                    (i also tried branch, row .... isn't cutting it) always ends up looking like:
                    5d4e95c2-c4fa-4f55-9f1f-a45a8b1bc58d-image.png

                    vs. this with my delegate code: (so it looks like it should look like) but as @Chris-Kawa mentioned, thats not a good way to do it, so im looking for a better way instead of painting the highlight twice, once in my delegate and once in my QTreeView
                    66ea05a2-eead-4a97-ab47-9926a3b3d181-image.png

                    Chris KawaC Online
                    Chris KawaC Online
                    Chris Kawa
                    Lifetime Qt Champion
                    wrote on last edited by
                    #9

                    @StudentScripter For painting the selection I simply meant this, without adjusting the area at all:

                    if (selectionModel()->isSelected(index)) {
                       painter->fillRect(options.rect, QColor(173, 216, 230));
                    }
                    

                    The widget (or the picture of it) in the item is displayed "above" the row, so it covers whatever the view painted for the row. If you'd like to go with the approach that only view paints selection then make sure that the widget (and the picture of it) has transparent background, so the underlying row is visible.

                    S 1 Reply Last reply
                    1
                    • Chris KawaC Chris Kawa

                      @StudentScripter For painting the selection I simply meant this, without adjusting the area at all:

                      if (selectionModel()->isSelected(index)) {
                         painter->fillRect(options.rect, QColor(173, 216, 230));
                      }
                      

                      The widget (or the picture of it) in the item is displayed "above" the row, so it covers whatever the view painted for the row. If you'd like to go with the approach that only view paints selection then make sure that the widget (and the picture of it) has transparent background, so the underlying row is visible.

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

                      @Chris-Kawa Yes thank you very much, i have done this now. Sadly and i don't know why, suddenly the intendation space isn't painted highlighted anymore:

                      69fd9d57-0953-423b-bd21-0bc3195f3162-image.png

                      void ViewLayerList::drawRow(QPainter *painter, const QStyleOptionViewItem &options, const QModelIndex &index) const
                      {
                         
                          if (selectionModel()->isSelected(index)) {
                          
                          // Zeichnen Sie den Einzugsbereich (Indentation) mit Ihrer gewünschten Farbe
                                  QRect indentRect = visualRect(index);
                                  painter->fillRect(indentRect, QColor(173, 216, 230)); // "lightblue" Hervorhebungsfarbe*/
                                  
                             
                                  
                              
                          }
                      
                          
                           QTreeView::drawRow(painter, options, index); // Rufen Sie die Basisimplementierung auf, um die Standardzeichnung durchzuführen
                      }
                      
                      

                      it only works when adding the stylesheet solution to the treeview constructor, but i guess thats not what you meant:
                      d18bde15-6933-492c-94db-c7d1549a60d2-image.png

                      
                      ViewLayerList::ViewLayerList(CustomGraphicsScene *scene, QWidget *parent)
                          : QTreeView{parent}, scene_durchgereicht(scene)
                      {
                      
                      // Setzen Sie das Stylesheet für den ausgewählten Zweig hier
                          setStyleSheet("QTreeView::item:selected { background-color: lightblue; }");
                      
                      Chris KawaC 1 Reply Last reply
                      0
                      • S StudentScripter

                        @Chris-Kawa Yes thank you very much, i have done this now. Sadly and i don't know why, suddenly the intendation space isn't painted highlighted anymore:

                        69fd9d57-0953-423b-bd21-0bc3195f3162-image.png

                        void ViewLayerList::drawRow(QPainter *painter, const QStyleOptionViewItem &options, const QModelIndex &index) const
                        {
                           
                            if (selectionModel()->isSelected(index)) {
                            
                            // Zeichnen Sie den Einzugsbereich (Indentation) mit Ihrer gewünschten Farbe
                                    QRect indentRect = visualRect(index);
                                    painter->fillRect(indentRect, QColor(173, 216, 230)); // "lightblue" Hervorhebungsfarbe*/
                                    
                               
                                    
                                
                            }
                        
                            
                             QTreeView::drawRow(painter, options, index); // Rufen Sie die Basisimplementierung auf, um die Standardzeichnung durchzuführen
                        }
                        
                        

                        it only works when adding the stylesheet solution to the treeview constructor, but i guess thats not what you meant:
                        d18bde15-6933-492c-94db-c7d1549a60d2-image.png

                        
                        ViewLayerList::ViewLayerList(CustomGraphicsScene *scene, QWidget *parent)
                            : QTreeView{parent}, scene_durchgereicht(scene)
                        {
                        
                        // Setzen Sie das Stylesheet für den ausgewählten Zweig hier
                            setStyleSheet("QTreeView::item:selected { background-color: lightblue; }");
                        
                        Chris KawaC Online
                        Chris KawaC Online
                        Chris Kawa
                        Lifetime Qt Champion
                        wrote on last edited by
                        #11

                        @StudentScripter You're painting the wrong rectangle. Look at the code you posted and the one I did.

                        S 1 Reply Last reply
                        0
                        • Chris KawaC Chris Kawa

                          @StudentScripter You're painting the wrong rectangle. Look at the code you posted and the one I did.

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

                          @Chris-Kawa Well, what a pitty, i indeed missed this. 😅 Thanks for your patience with me.

                          May can i bother you again with another question related to this widget:
                          I know about the setEditTriggers() but still when i set:

                          setEditTriggers(QAbstractItemView::AllEditTriggers);
                          

                          cc121d67-2642-4c81-99ea-903f2190f42d-image.png
                          Like it is now i have to doubleclick to create the editor and click a third time again to focus the line edit, thats pretty user unfriendly and wierd.

                          Instead i want to double click onto the position where my lineedit is to select and focus/write into it.
                          Also with the checkbox i would like to click on it and it should be ticked instantly on the first click. I guess i have to implement this logic somehow myself into QTreeView mousePressEvent, but i have no good idea on how to do that? Maybe with openpersitentEditor and than somehow set focus to the widget depending on what is under the clicked mouse position?

                          Also can't say it often enough thanks for your help and the help of the others. I really doubt i would have gotten this far without. :D Also have to admit this photoeditor clone is my first big project that i set myself, of course only with basic features, but i really want to tweak them to be useful in a real world scenario.

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

                            No, check the editorEvent function.

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

                            S 2 Replies Last reply
                            0
                            • SGaistS SGaist

                              No, check the editorEvent function.

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

                              @SGaist thanks that seems the right direction, however i cant get the mouse position to be into the checkbox. Visually it looks like i click into the check box but my debug says its not clicking into the checkbox. I tried mapping to global in order to align both positions but i had no luck with this:

                              
                              
                              bool ViewLayerItemDelegate::editorEvent(QEvent *event, QAbstractItemModel *model, const QStyleOptionViewItem &option, const QModelIndex &index)
                              {
                                  if(event->type() == QEvent::MouseButtonPress)
                                  {
                                      QMouseEvent *mouseEvent = static_cast<QMouseEvent*>(event);
                                      
                                      QWidget *parentWidget = qobject_cast<QWidget*>(parent());
                                      if(parentWidget)
                                      {
                                          
                                          QWidget *editor = createEditor(parentWidget, option, index);
                                         
                                              LineEditCheckBoxWidget *widget = qobject_cast<LineEditCheckBoxWidget*>(editor);
                                              if(widget)
                                              {   
                                             
                                                  
                                              QPoint mousePosition = widget->checkBox->mapFromGlobal(mouseEvent->globalPos());
                                              QRect checkboxGeometry = widget->checkBox->geometry();
                                              QRect globalCheckboxGeometry;
                                              globalCheckboxGeometry.setTopLeft(widget->checkBox->mapToGlobal(checkboxGeometry.topLeft()));
                                              globalCheckboxGeometry.setBottomRight(widget->checkBox->mapToGlobal(checkboxGeometry.bottomRight()));
                              
                              
                                                 qDebug() << "Checkboxdata: " << globalCheckboxGeometry;
                              
                                                 qDebug() << "MousePostion: " << mousePosition;
                              
                              
                                                  /*
                                                   //IGNORE: later i want to check here if the positon 
                                                   //is the same in order to perform further actions
                                                  bool checked = widget->checkBox->isChecked();
                                                  widget->checkBox->setChecked(!checked);
                                                  setModelData(editor, model, index);
                                                  return true; 
                                                  */
                                              }
                                      }
                              
                                    
                                 
                                  }
                                  
                                  return QStyledItemDelegate::editorEvent(event, model, option, index);
                              }
                              
                              

                              I get for example:
                              Checkboxdata: QRect(1095,302 100x30)
                              MousePostion: QPoint(215,21)

                              1 Reply Last reply
                              0
                              • SGaistS SGaist

                                No, check the editorEvent function.

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

                                @SGaist Bumping this up. Guess you are busy but may you have a second the next days or so to may answer my last question. Sorry for the interuption. :)

                                Chris KawaC 1 Reply Last reply
                                0
                                • S StudentScripter

                                  @SGaist Bumping this up. Guess you are busy but may you have a second the next days or so to may answer my last question. Sorry for the interuption. :)

                                  Chris KawaC Online
                                  Chris KawaC Online
                                  Chris Kawa
                                  Lifetime Qt Champion
                                  wrote on last edited by
                                  #16

                                  @StudentScripter There's multiple problems in your code.

                                  First this is wrong: QWidget *parentWidget = qobject_cast<QWidget*>(parent());.
                                  A delegate can be shared between multiple views and there's no requirement that any of those views was a parent of that delegate. There's also no requirement that the parent of the delegate is a QWidget or that the delegate even has any parent. In case of sharing delegate between views the parent might not even be the widget the event occurred in.
                                  The proper way to retrieve the widget the event happened in is through option.widget parameter.

                                  Next, you should not call createEditor. This is a callback method that the view calls when editing of an item is requested via view->edit(index). The way you have it you create a new widget every time an item is clicked. you never show or delete that widget, but you do give it a parent, so after 1000 clicks you have 1000 instances of that widget created, invisible and living until you the view is destroyed.

                                  The event gives you press position in view's viewport coordinates. To convert it to item's coordinates you can get the item coords in the viewport and do the math e.g.

                                  if(event->type() == QEvent::MouseButtonPress)
                                  {
                                      QMouseEvent* mouseEvt = static_cast<QMouseEvent*>(event);
                                      
                                      if ( const QTreeView* view = qobject_cast<const QTreeView*>(option.widget))
                                      {
                                          const QRect itemRect = view->visualRect(index);
                                          QPointF itemPos = mouseEvt->position() - itemRect.topLeft(); // press position in item's coords
                                  

                                  You should not create and destroy a widget every time you want to paint or check a position in it. That's an enormous overhead that defeats the whole point of delegates.

                                  Calculate where your checkbox is without instantiating a widget. For example you can assume it's always in a right aligned square of your item, so you can calculate its position from the item dimensions.

                                  When painting the item you also shouldn't instantiate a widget and take a screenshot of it like you're doing now. Use style()->drawControl(...) to draw a picture of a checkbox or line edit without actually instantiating them. That's the idea of delegates - provide a lightweight proxy for the items and only instantiating an actual widget when editing of an item starts.

                                  When painting an item don't load any resources e.g. QPixmap iconPixmap("://resource/quick.png"); in the paint event. That is reading from disk and can stall and make your app unresponsive if you have many items or slow disk access. Load the image once e.g. in the delegate's constructor and store it in a class member. Also if you're doing any transformation on it, like scaled(...) do it once on load and store and reuse the result. Keep in mind that the paining is called every time a user moves a mouse over an item, so it's potentially hundreds of events a second. Painting should be as speedy as possible.

                                  Don't use stylesheets to draw a colored rectangle. It's like shooting a fly with a canon. Just use a QPainter and paint a rectangle.

                                  S 3 Replies Last reply
                                  3
                                  • Chris KawaC Chris Kawa

                                    @StudentScripter There's multiple problems in your code.

                                    First this is wrong: QWidget *parentWidget = qobject_cast<QWidget*>(parent());.
                                    A delegate can be shared between multiple views and there's no requirement that any of those views was a parent of that delegate. There's also no requirement that the parent of the delegate is a QWidget or that the delegate even has any parent. In case of sharing delegate between views the parent might not even be the widget the event occurred in.
                                    The proper way to retrieve the widget the event happened in is through option.widget parameter.

                                    Next, you should not call createEditor. This is a callback method that the view calls when editing of an item is requested via view->edit(index). The way you have it you create a new widget every time an item is clicked. you never show or delete that widget, but you do give it a parent, so after 1000 clicks you have 1000 instances of that widget created, invisible and living until you the view is destroyed.

                                    The event gives you press position in view's viewport coordinates. To convert it to item's coordinates you can get the item coords in the viewport and do the math e.g.

                                    if(event->type() == QEvent::MouseButtonPress)
                                    {
                                        QMouseEvent* mouseEvt = static_cast<QMouseEvent*>(event);
                                        
                                        if ( const QTreeView* view = qobject_cast<const QTreeView*>(option.widget))
                                        {
                                            const QRect itemRect = view->visualRect(index);
                                            QPointF itemPos = mouseEvt->position() - itemRect.topLeft(); // press position in item's coords
                                    

                                    You should not create and destroy a widget every time you want to paint or check a position in it. That's an enormous overhead that defeats the whole point of delegates.

                                    Calculate where your checkbox is without instantiating a widget. For example you can assume it's always in a right aligned square of your item, so you can calculate its position from the item dimensions.

                                    When painting the item you also shouldn't instantiate a widget and take a screenshot of it like you're doing now. Use style()->drawControl(...) to draw a picture of a checkbox or line edit without actually instantiating them. That's the idea of delegates - provide a lightweight proxy for the items and only instantiating an actual widget when editing of an item starts.

                                    When painting an item don't load any resources e.g. QPixmap iconPixmap("://resource/quick.png"); in the paint event. That is reading from disk and can stall and make your app unresponsive if you have many items or slow disk access. Load the image once e.g. in the delegate's constructor and store it in a class member. Also if you're doing any transformation on it, like scaled(...) do it once on load and store and reuse the result. Keep in mind that the paining is called every time a user moves a mouse over an item, so it's potentially hundreds of events a second. Painting should be as speedy as possible.

                                    Don't use stylesheets to draw a colored rectangle. It's like shooting a fly with a canon. Just use a QPainter and paint a rectangle.

                                    S Offline
                                    S Offline
                                    StudentScripter
                                    wrote on last edited by StudentScripter
                                    #17
                                    This post is deleted!
                                    1 Reply Last reply
                                    0
                                    • Chris KawaC Chris Kawa

                                      @StudentScripter There's multiple problems in your code.

                                      First this is wrong: QWidget *parentWidget = qobject_cast<QWidget*>(parent());.
                                      A delegate can be shared between multiple views and there's no requirement that any of those views was a parent of that delegate. There's also no requirement that the parent of the delegate is a QWidget or that the delegate even has any parent. In case of sharing delegate between views the parent might not even be the widget the event occurred in.
                                      The proper way to retrieve the widget the event happened in is through option.widget parameter.

                                      Next, you should not call createEditor. This is a callback method that the view calls when editing of an item is requested via view->edit(index). The way you have it you create a new widget every time an item is clicked. you never show or delete that widget, but you do give it a parent, so after 1000 clicks you have 1000 instances of that widget created, invisible and living until you the view is destroyed.

                                      The event gives you press position in view's viewport coordinates. To convert it to item's coordinates you can get the item coords in the viewport and do the math e.g.

                                      if(event->type() == QEvent::MouseButtonPress)
                                      {
                                          QMouseEvent* mouseEvt = static_cast<QMouseEvent*>(event);
                                          
                                          if ( const QTreeView* view = qobject_cast<const QTreeView*>(option.widget))
                                          {
                                              const QRect itemRect = view->visualRect(index);
                                              QPointF itemPos = mouseEvt->position() - itemRect.topLeft(); // press position in item's coords
                                      

                                      You should not create and destroy a widget every time you want to paint or check a position in it. That's an enormous overhead that defeats the whole point of delegates.

                                      Calculate where your checkbox is without instantiating a widget. For example you can assume it's always in a right aligned square of your item, so you can calculate its position from the item dimensions.

                                      When painting the item you also shouldn't instantiate a widget and take a screenshot of it like you're doing now. Use style()->drawControl(...) to draw a picture of a checkbox or line edit without actually instantiating them. That's the idea of delegates - provide a lightweight proxy for the items and only instantiating an actual widget when editing of an item starts.

                                      When painting an item don't load any resources e.g. QPixmap iconPixmap("://resource/quick.png"); in the paint event. That is reading from disk and can stall and make your app unresponsive if you have many items or slow disk access. Load the image once e.g. in the delegate's constructor and store it in a class member. Also if you're doing any transformation on it, like scaled(...) do it once on load and store and reuse the result. Keep in mind that the paining is called every time a user moves a mouse over an item, so it's potentially hundreds of events a second. Painting should be as speedy as possible.

                                      Don't use stylesheets to draw a colored rectangle. It's like shooting a fly with a canon. Just use a QPainter and paint a rectangle.

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

                                      @Chris-Kawa thank you very much. That definitely helped a lot. :)

                                      I have done the manual positioning now, so all delegates line up with the actual widget. :)

                                      
                                      void ViewLayerItemDelegate::paint(QPainter *painter, const QStyleOptionViewItem &option, const QModelIndex &index) const
                                      {
                                          
                                          
                                          QStyleOptionViewItem opt = option;
                                          initStyleOption(&opt, index);
                                      
                                      
                                          // Überprüfen Sie, ob der aktuelle Index bearbeitet wird
                                              if (index == currentlyEditedIndex) {
                                                 
                                                  return;
                                              }
                                      
                                      
                                      
                                          // 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();
                                      
                                          // Laden Sie das Icon und skalieren Sie es
                                          QPixmap iconPixmap("://resource/quick.png"); // Ersetzen Sie dies durch den Pfad zu Ihrer Icon-Datei
                                          QPixmap scaledPixmap = iconPixmap.scaled(32, 32, Qt::KeepAspectRatio, Qt::SmoothTransformation);
                                          
                                          // Berechnen Sie die Position für das Icon
                                          int centerY = option.rect.top() + option.rect.height() / 2;
                                          int iconY = centerY - scaledPixmap.height() / 2;
                                          QPoint iconPos = QPoint(option.rect.left() + 10, iconY);
                                          
                                          // Zeichnen Sie das Pixmap mit dem QPainter
                                          painter->drawPixmap(iconPos, scaledPixmap);
                                      
                                      
                                          // Berechnen Sie die Position und Größe für das LineEdit
                                          QRect lineEditRect = option.rect;
                                          lineEditRect.setLeft(iconPos.x() + scaledPixmap.width() + 10); // Adjust as needed
                                          lineEditRect.setRight(option.rect.right() - 10); // Adjust as needed
                                      
                                          // Erstellen Sie ein QStyleOptionFrame für das LineEdit
                                          QStyleOptionFrame lineEditOption;
                                          lineEditOption.lineWidth = 1; // Setzen Sie die Liniendicke auf 1
                                          lineEditOption.rect = lineEditRect;
                                      
                                          // Zeichnen Sie das LineEdit
                                          QApplication::style()->drawControl(QStyle::CE_ShapedFrame, &lineEditOption, painter);
                                      
                                          // Zeichnen Sie den Text des LineEdits
                                          painter->drawText(lineEditOption.rect.adjusted(2,0,0,0), Qt::AlignLeft | Qt::AlignVCenter, lineEditvalue);
                                      
                                          // Berechnen Sie die Position und Größe für die CheckBox
                                          QRect checkBoxRect = option.rect;
                                          checkBoxRect.setLeft(lineEditRect.right() - 22); // Adjust as needed
                                          checkBoxRect.setRight(option.rect.right() - 10); // Adjust as needed
                                      
                                          // Erstellen Sie ein QStyleOptionButton für die CheckBox
                                          QStyleOptionButton checkBoxOption;
                                          checkBoxOption.state = checkBoxValue ? QStyle::State_On : QStyle::State_Off;
                                          checkBoxOption.rect = checkBoxRect;
                                      
                                          // Zeichnen Sie die CheckBox
                                          QApplication::style()->drawControl(QStyle::CE_CheckBox, &checkBoxOption, painter);
                                      }
                                      
                                      1 Reply Last reply
                                      0
                                      • Chris KawaC Chris Kawa

                                        @StudentScripter There's multiple problems in your code.

                                        First this is wrong: QWidget *parentWidget = qobject_cast<QWidget*>(parent());.
                                        A delegate can be shared between multiple views and there's no requirement that any of those views was a parent of that delegate. There's also no requirement that the parent of the delegate is a QWidget or that the delegate even has any parent. In case of sharing delegate between views the parent might not even be the widget the event occurred in.
                                        The proper way to retrieve the widget the event happened in is through option.widget parameter.

                                        Next, you should not call createEditor. This is a callback method that the view calls when editing of an item is requested via view->edit(index). The way you have it you create a new widget every time an item is clicked. you never show or delete that widget, but you do give it a parent, so after 1000 clicks you have 1000 instances of that widget created, invisible and living until you the view is destroyed.

                                        The event gives you press position in view's viewport coordinates. To convert it to item's coordinates you can get the item coords in the viewport and do the math e.g.

                                        if(event->type() == QEvent::MouseButtonPress)
                                        {
                                            QMouseEvent* mouseEvt = static_cast<QMouseEvent*>(event);
                                            
                                            if ( const QTreeView* view = qobject_cast<const QTreeView*>(option.widget))
                                            {
                                                const QRect itemRect = view->visualRect(index);
                                                QPointF itemPos = mouseEvt->position() - itemRect.topLeft(); // press position in item's coords
                                        

                                        You should not create and destroy a widget every time you want to paint or check a position in it. That's an enormous overhead that defeats the whole point of delegates.

                                        Calculate where your checkbox is without instantiating a widget. For example you can assume it's always in a right aligned square of your item, so you can calculate its position from the item dimensions.

                                        When painting the item you also shouldn't instantiate a widget and take a screenshot of it like you're doing now. Use style()->drawControl(...) to draw a picture of a checkbox or line edit without actually instantiating them. That's the idea of delegates - provide a lightweight proxy for the items and only instantiating an actual widget when editing of an item starts.

                                        When painting an item don't load any resources e.g. QPixmap iconPixmap("://resource/quick.png"); in the paint event. That is reading from disk and can stall and make your app unresponsive if you have many items or slow disk access. Load the image once e.g. in the delegate's constructor and store it in a class member. Also if you're doing any transformation on it, like scaled(...) do it once on load and store and reuse the result. Keep in mind that the paining is called every time a user moves a mouse over an item, so it's potentially hundreds of events a second. Painting should be as speedy as possible.

                                        Don't use stylesheets to draw a colored rectangle. It's like shooting a fly with a canon. Just use a QPainter and paint a rectangle.

                                        S Offline
                                        S Offline
                                        StudentScripter
                                        wrote on last edited by StudentScripter
                                        #19
                                        This post is deleted!
                                        1 Reply Last reply
                                        0
                                        • S StudentScripter has marked this topic as solved on

                                        • Login

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