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. QTreeView prevent stacking indentation after certain childs.
Qt 6.11 is out! See what's new in the release blog

QTreeView prevent stacking indentation after certain childs.

Scheduled Pinned Locked Moved Unsolved General and Desktop
8 Posts 3 Posters 1.9k Views 2 Watching
  • 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 StudentScripter
    #1

    So as the title suggest i want that the treeview still supports children and the indentation of those but i want it so the indentation does not get more after a certain point of children, cause this way my items get to big for the view.

    Is there any way to do that?

    setIndentation() does only work for all items.

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

      Hi,

      Shouldn't you rather considering managing your children in a different way to show them ?

      Otherwise, you can implement a proxy model that "rearranges" your data in the way you see fit.

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

      S 1 Reply Last reply
      2
      • SGaistS SGaist

        Hi,

        Shouldn't you rather considering managing your children in a different way to show them ?

        Otherwise, you can implement a proxy model that "rearranges" your data in the way you see fit.

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

        @SGaist Thank you for the reply. What do you mean with considering a other way to manage my children?

        I for sure need a Qtreeview as my list should be hierachic, but the problem is after 3 children beeing stacked below each other the readability becomes bad. Therefore i want to implement something that after there are 3 children below each other and a 4th children gets added, the 4th children should have the same intendation as the 3rd. Is there any good source where i can lookup on how to use proxy model for a treeview?

        Here a picture to visualize the problem a little bit better:
        708d68a0-7f38-4f61-9815-9bed38067904-image.png
        the 4th item should have the same indentation as the 3rd item.

        JonBJ 1 Reply Last reply
        0
        • S StudentScripter

          @SGaist Thank you for the reply. What do you mean with considering a other way to manage my children?

          I for sure need a Qtreeview as my list should be hierachic, but the problem is after 3 children beeing stacked below each other the readability becomes bad. Therefore i want to implement something that after there are 3 children below each other and a 4th children gets added, the 4th children should have the same intendation as the 3rd. Is there any good source where i can lookup on how to use proxy model for a treeview?

          Here a picture to visualize the problem a little bit better:
          708d68a0-7f38-4f61-9815-9bed38067904-image.png
          the 4th item should have the same indentation as the 3rd item.

          JonBJ Offline
          JonBJ Offline
          JonB
          wrote on last edited by
          #4

          @StudentScripter
          Last suggestion before you go down this route.

          It does not seem to me this is a good thing to try to do. Windows Explorer/a File Manager app probably has to deal with much deeper nesting/indentation than your case. But it does not chop of after a few levels and present further items without their natural indentation in the hierarchy. I have not seen such a thing. Rather consider using scrollbars or a right-hand-side splitter the user can adjust, cf. Explorer.

          If you insist on what you want, istm you must either use a QStyledItemDelegate to draw rows the way you desire or present a model with only 3 levels of depth, whether you do that by creating a new model or make a proxy behave like that. Your 4th item needs to appear as a sibling of 3rd item and a child of 1st item.

          S 2 Replies Last reply
          0
          • JonBJ JonB

            @StudentScripter
            Last suggestion before you go down this route.

            It does not seem to me this is a good thing to try to do. Windows Explorer/a File Manager app probably has to deal with much deeper nesting/indentation than your case. But it does not chop of after a few levels and present further items without their natural indentation in the hierarchy. I have not seen such a thing. Rather consider using scrollbars or a right-hand-side splitter the user can adjust, cf. Explorer.

            If you insist on what you want, istm you must either use a QStyledItemDelegate to draw rows the way you desire or present a model with only 3 levels of depth, whether you do that by creating a new model or make a proxy behave like that. Your 4th item needs to appear as a sibling of 3rd item and a child of 1st item.

            S Offline
            S Offline
            StudentScripter
            wrote on last edited by StudentScripter
            #5
            This post is deleted!
            1 Reply Last reply
            0
            • JonBJ JonB

              @StudentScripter
              Last suggestion before you go down this route.

              It does not seem to me this is a good thing to try to do. Windows Explorer/a File Manager app probably has to deal with much deeper nesting/indentation than your case. But it does not chop of after a few levels and present further items without their natural indentation in the hierarchy. I have not seen such a thing. Rather consider using scrollbars or a right-hand-side splitter the user can adjust, cf. Explorer.

              If you insist on what you want, istm you must either use a QStyledItemDelegate to draw rows the way you desire or present a model with only 3 levels of depth, whether you do that by creating a new model or make a proxy behave like that. Your 4th item needs to appear as a sibling of 3rd item and a child of 1st item.

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

              @JonB Thanks for your response. I dont know if it is the right way to do it, basically i want to build a layer system like in photoshop or affinity photo like this:
              0d4af81e-86e6-4fe4-b37e-634bf3072254-image.png

              But i just can't get the desired result. Here is how mine looks:
              d7ad3da6-f438-463b-8de0-5a5d63105626-image.png

              Btw. im currently using a delegate for the items which looks like this:

              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);
              
                      this->setStyleSheet("background-color: transparent");
              
              
                      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-color: transparent;");
                      lineEdit->setFrame(false);
                      lineEdit->setPlaceholderText("<Empty>");
              
                      checkBox->setStyleSheet("background-color: transparent");
                      
                          //QPoint globalPos = checkBox->mapToGlobal(QPoint(0, 0));
                          //qDebug() << "Global position of checkbox on init: " << globalPos;
                          
                      
                          
                  }
                  
                  // 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;
                  bool editorEvent(QEvent *event, QAbstractItemModel *model, const QStyleOptionViewItem &option, const QModelIndex &index) override;
                  
                  
                  
                   QModelIndex currentlyEditedIndex;
                   
                   
                   void setCurrentlyEditedIndex(const QModelIndex &index);
              
                  //Speichert die Position wo geklickt wurde
                   QPointF ClickPosition;
                   
                  
                   
               public slots:
                  
                  void onLineEditTextChanged(const QString &text);
              
              
              signals:
                  
                  
                  
                  
                  
                  
                  
              
                
              };
                 
              
              #endif // VIEWLAYERITEMDELEGATE_H
              
              

              delegate.cpp:

              #include "ViewLayerItemDelegate.h"
              #include <QStyledItemDelegate>
              #include <QPainter>
              #include <QApplication>
              #include <QItemSelectionModel>
              #include <QMouseEvent>
              #include "ViewLayerList.h"
              
              #include <QTimer>
              
              
              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);
              
              
              
                 // Verbinden Sie das textChanged() Signal des LineEdits mit Ihrem Slot
                  connect(editor->lineEdit, &QLineEdit::textChanged, this, &ViewLayerItemDelegate::onLineEditTextChanged);
                  
                  
                  
                  //Ein Timer um direkt die Editierung des LineEdit zu ermöglichen
                  QTimer::singleShot(0, editor->lineEdit, SLOT(setFocus()));
              
                  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->setFocus();
              
                  widget->lineEdit->setFocus(Qt::MouseFocusReason); // Editor aktivieren
                  widget->lineEdit->setStyleSheet("");
                  widget->iconLabel->setAttribute(Qt::WA_TranslucentBackground);
                 //widget->setStyleSheet("background: white");
                 
                 
              
              
                  // Setzen Sie den bearbeiteten Index
                  const_cast<ViewLayerItemDelegate*>(this)->setCurrentlyEditedIndex(index);
               
                      
              }
              
              
              
              
              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";
                  
              
              
                  // Setzen Sie den bearbeiteten Index zurück
                  const_cast<ViewLayerItemDelegate*>(this)->setCurrentlyEditedIndex(QModelIndex());
              }
              
              
              
              
              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);
              
              
                  // Ü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);
              
                // Überprüfen Sie, ob der Text leer ist und zeichnen Sie den Platzhaltertext
                  if (lineEditvalue.isEmpty()) {
                      painter->drawText(lineEditOption.rect.adjusted(2, 0, 0, 0), Qt::AlignLeft | Qt::AlignVCenter, "<Empty>");
                  } else {
                      // 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);
              }
              
              
              
              
              
              
              bool ViewLayerItemDelegate::editorEvent(QEvent *event, QAbstractItemModel *model, const QStyleOptionViewItem &option, const QModelIndex &index)
              {
                  if(event->type() == QEvent::MouseButtonPress)
                  {
                      QMouseEvent *mouseEvent = static_cast<QMouseEvent*>(event);
                      
                      if (const QTreeView* view = qobject_cast<const QTreeView*>(option.widget))
                      {
                      
                      
                      const QRect itemRect = view->visualRect(index);
                      ClickPosition = mouseEvent->position() - itemRect.topLeft(); // press position in item's coords
                      
                      
                      //QRect itemRect = option.rect;
                      qDebug() << "Click position: " << ClickPosition;
                      qDebug() << "Item Rect: " <<itemRect;
              
              
                     
              
                      if(ClickPosition.x() >= itemRect.width()-35 && ClickPosition.x() <= itemRect.width()-20)
                      {
                      // Invert the state of the checkbox
                      bool value = index.data(Qt::CheckStateRole).toBool();
                      model->setData(index, !value, Qt::CheckStateRole);
                      }
              
              
              
              
                      
                    }
                        
                      
                      
                      
              
                      
              
                    
                 }
                  
                  
                  // Standardverhalten beibehalten für andere Ereignisse
                  return QStyledItemDelegate::editorEvent(event, model, option, index);
              }
              
              
              
              
              
              
              
              // 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";
               this->lineEdit->setStyleSheet("background: transparent;");
                 
              
                  QWidget::mousePressEvent(event);
              }
              
              
              
              
              
                  
                  
                  
              void ViewLayerItemDelegate::setCurrentlyEditedIndex(const QModelIndex &index)
              {
              currentlyEditedIndex = index;
              }
                  
              
              

              I got the truncating working now inside my delegate but still i would like to control the indentation level on a per item basis. How to exactly do that?

              JonBJ 1 Reply Last reply
              0
              • S StudentScripter

                @JonB Thanks for your response. I dont know if it is the right way to do it, basically i want to build a layer system like in photoshop or affinity photo like this:
                0d4af81e-86e6-4fe4-b37e-634bf3072254-image.png

                But i just can't get the desired result. Here is how mine looks:
                d7ad3da6-f438-463b-8de0-5a5d63105626-image.png

                Btw. im currently using a delegate for the items which looks like this:

                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);
                
                        this->setStyleSheet("background-color: transparent");
                
                
                        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-color: transparent;");
                        lineEdit->setFrame(false);
                        lineEdit->setPlaceholderText("<Empty>");
                
                        checkBox->setStyleSheet("background-color: transparent");
                        
                            //QPoint globalPos = checkBox->mapToGlobal(QPoint(0, 0));
                            //qDebug() << "Global position of checkbox on init: " << globalPos;
                            
                        
                            
                    }
                    
                    // 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;
                    bool editorEvent(QEvent *event, QAbstractItemModel *model, const QStyleOptionViewItem &option, const QModelIndex &index) override;
                    
                    
                    
                     QModelIndex currentlyEditedIndex;
                     
                     
                     void setCurrentlyEditedIndex(const QModelIndex &index);
                
                    //Speichert die Position wo geklickt wurde
                     QPointF ClickPosition;
                     
                    
                     
                 public slots:
                    
                    void onLineEditTextChanged(const QString &text);
                
                
                signals:
                    
                    
                    
                    
                    
                    
                    
                
                  
                };
                   
                
                #endif // VIEWLAYERITEMDELEGATE_H
                
                

                delegate.cpp:

                #include "ViewLayerItemDelegate.h"
                #include <QStyledItemDelegate>
                #include <QPainter>
                #include <QApplication>
                #include <QItemSelectionModel>
                #include <QMouseEvent>
                #include "ViewLayerList.h"
                
                #include <QTimer>
                
                
                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);
                
                
                
                   // Verbinden Sie das textChanged() Signal des LineEdits mit Ihrem Slot
                    connect(editor->lineEdit, &QLineEdit::textChanged, this, &ViewLayerItemDelegate::onLineEditTextChanged);
                    
                    
                    
                    //Ein Timer um direkt die Editierung des LineEdit zu ermöglichen
                    QTimer::singleShot(0, editor->lineEdit, SLOT(setFocus()));
                
                    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->setFocus();
                
                    widget->lineEdit->setFocus(Qt::MouseFocusReason); // Editor aktivieren
                    widget->lineEdit->setStyleSheet("");
                    widget->iconLabel->setAttribute(Qt::WA_TranslucentBackground);
                   //widget->setStyleSheet("background: white");
                   
                   
                
                
                    // Setzen Sie den bearbeiteten Index
                    const_cast<ViewLayerItemDelegate*>(this)->setCurrentlyEditedIndex(index);
                 
                        
                }
                
                
                
                
                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";
                    
                
                
                    // Setzen Sie den bearbeiteten Index zurück
                    const_cast<ViewLayerItemDelegate*>(this)->setCurrentlyEditedIndex(QModelIndex());
                }
                
                
                
                
                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);
                
                
                    // Ü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);
                
                  // Überprüfen Sie, ob der Text leer ist und zeichnen Sie den Platzhaltertext
                    if (lineEditvalue.isEmpty()) {
                        painter->drawText(lineEditOption.rect.adjusted(2, 0, 0, 0), Qt::AlignLeft | Qt::AlignVCenter, "<Empty>");
                    } else {
                        // 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);
                }
                
                
                
                
                
                
                bool ViewLayerItemDelegate::editorEvent(QEvent *event, QAbstractItemModel *model, const QStyleOptionViewItem &option, const QModelIndex &index)
                {
                    if(event->type() == QEvent::MouseButtonPress)
                    {
                        QMouseEvent *mouseEvent = static_cast<QMouseEvent*>(event);
                        
                        if (const QTreeView* view = qobject_cast<const QTreeView*>(option.widget))
                        {
                        
                        
                        const QRect itemRect = view->visualRect(index);
                        ClickPosition = mouseEvent->position() - itemRect.topLeft(); // press position in item's coords
                        
                        
                        //QRect itemRect = option.rect;
                        qDebug() << "Click position: " << ClickPosition;
                        qDebug() << "Item Rect: " <<itemRect;
                
                
                       
                
                        if(ClickPosition.x() >= itemRect.width()-35 && ClickPosition.x() <= itemRect.width()-20)
                        {
                        // Invert the state of the checkbox
                        bool value = index.data(Qt::CheckStateRole).toBool();
                        model->setData(index, !value, Qt::CheckStateRole);
                        }
                
                
                
                
                        
                      }
                          
                        
                        
                        
                
                        
                
                      
                   }
                    
                    
                    // Standardverhalten beibehalten für andere Ereignisse
                    return QStyledItemDelegate::editorEvent(event, model, option, index);
                }
                
                
                
                
                
                
                
                // 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";
                 this->lineEdit->setStyleSheet("background: transparent;");
                   
                
                    QWidget::mousePressEvent(event);
                }
                
                
                
                
                
                    
                    
                    
                void ViewLayerItemDelegate::setCurrentlyEditedIndex(const QModelIndex &index)
                {
                currentlyEditedIndex = index;
                }
                    
                
                

                I got the truncating working now inside my delegate but still i would like to control the indentation level on a per item basis. How to exactly do that?

                JonBJ Offline
                JonBJ Offline
                JonB
                wrote on last edited by
                #7

                @StudentScripter I don't know other than your own code in ViewLayerItemDelegate::paint().

                S 1 Reply Last reply
                0
                • JonBJ JonB

                  @StudentScripter I don't know other than your own code in ViewLayerItemDelegate::paint().

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

                  @JonB oh sorry my oversight, here is the code of my delegate:

                  delegate.cpp:

                  #include "ViewLayerItemDelegate.h"
                  #include <QStyledItemDelegate>
                  #include <QPainter>
                  #include <QApplication>
                  #include <QItemSelectionModel>
                  #include <QMouseEvent>
                  #include "ViewLayerList.h"
                  
                  #include <QTimer>
                  
                  
                  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);
                  
                  
                  
                     // Verbinden Sie das textChanged() Signal des LineEdits mit Ihrem Slot
                      connect(editor->lineEdit, &QLineEdit::textChanged, this, &ViewLayerItemDelegate::onLineEditTextChanged);
                      
                      
                      
                      //Ein Timer um direkt die Editierung des LineEdit zu ermöglichen
                      QTimer::singleShot(0, editor->lineEdit, SLOT(setFocus()));
                  
                      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->setFocus();
                  
                      widget->lineEdit->setFocus(Qt::MouseFocusReason); // Editor aktivieren
                      widget->lineEdit->setStyleSheet("background: white");
                      widget->iconLabel->setAttribute(Qt::WA_TranslucentBackground);
                     //widget->setStyleSheet("background: white");
                     
                     
                  
                  
                  
                  
                      // Setzen Sie den bearbeiteten Index
                      const_cast<ViewLayerItemDelegate*>(this)->setCurrentlyEditedIndex(index);
                   
                  
                      
                  
                      
                  
                  }
                  
                  
                  
                  
                  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";
                      
                  
                  
                      // Setzen Sie den bearbeiteten Index zurück
                      const_cast<ViewLayerItemDelegate*>(this)->setCurrentlyEditedIndex(QModelIndex());
                      
                      
                     
                  }
                  
                  
                  
                  
                  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
                          
                           // Ändern Sie die Einrückung basierend auf dem Level des Items (z.B., hier um 20 Pixel).
                          int indentationLevel = index.column(); // Hier als Beispiel die Einrückung basierend auf der Spalte.
                          size.rwidth() -= indentationLevel * 40; // Die Einrückung um 20 Pixel erhöhen.
                  
                      return size;
                  }
                  
                  
                  
                  
                  
                  
                  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-35); // 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);
                  
                    // Überprüfen Sie, ob der Text leer ist und zeichnen Sie den Platzhaltertext
                   // Zeichnen Sie den Text des LineEdits, considering truncation
                  // Überprüfen Sie, ob der Text leer ist und zeichnen Sie den Platzhaltertext
                      if (lineEditvalue.isEmpty()) {
                          painter->drawText(lineEditOption.rect.adjusted(2, 0, 0, 0), Qt::AlignLeft | Qt::AlignVCenter, "<Empty>");
                      } else {
                          // Hier wird die maximale Breite des Texts festgelegt, bevor er abgeschnitten wird
                          int maxTextWidth = lineEditRect.width();
                          
                          // Berechnen Sie die Größe des Texts
                          QFontMetrics fm(painter->font());
                          QString displayedText = fm.elidedText(lineEditvalue, Qt::ElideRight, maxTextWidth - 10);
                  
                          painter->drawText(lineEditOption.rect.adjusted(2, 0, 0, 0), Qt::AlignLeft | Qt::AlignVCenter, displayedText);
                      }
                  
                      // Berechnen Sie die Position und Größe für die CheckBox
                      QRect checkBoxRect = option.rect;
                      checkBoxRect.setLeft(lineEditRect.right() +35- 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;
                  
                  
                  
                  /* //CODE NUR ZUM VISUELLEN DEBUGGEN DER BEREICHE:
                  // Zeichnen Sie ein rotes Rechteck um das LineEdit
                  QPen redPen(Qt::red);
                  painter->setPen(redPen);
                  painter->drawRect(lineEditRect);
                  
                  
                  // Zeichnen Sie ein rotes Rechteck um das LineEdit
                  QPen bluePen(Qt::blue);
                  painter->setPen(bluePen);
                  painter->drawRect(checkBoxRect);
                  */
                      // Zeichnen Sie die CheckBox
                      QApplication::style()->drawControl(QStyle::CE_CheckBox, &checkBoxOption, painter);
                  }
                  
                  
                  
                  
                  
                  
                  bool ViewLayerItemDelegate::editorEvent(QEvent *event, QAbstractItemModel *model, const QStyleOptionViewItem &option, const QModelIndex &index)
                  {
                      if(event->type() == QEvent::MouseButtonPress)
                      {
                          QMouseEvent *mouseEvent = static_cast<QMouseEvent*>(event);
                        
                          if (const QTreeView* view = qobject_cast<const QTreeView*>(option.widget))
                          {
                          
                          
                          const QRect itemRect = view->visualRect(index);
                          ClickPosition = mouseEvent->position() - itemRect.topLeft(); // press position in item's coords
                          
                          
                          //QRect itemRect = option.rect;
                          qDebug() << "Click position: " << ClickPosition;
                          qDebug() << "Item Rect: " <<itemRect;
                  
                  
                         
                  
                          if(ClickPosition.x() >= itemRect.width()-35 && ClickPosition.x() <= itemRect.width()-20)
                          {
                          // Invert the state of the checkbox
                          bool value = index.data(Qt::CheckStateRole).toBool();
                          model->setData(index, !value, Qt::CheckStateRole);
                          }
                       
                  
                  
                  
                          
                        }
                            
                          
                          
                          
                  
                          
                  
                        
                     }
                      
                      
                      // Standardverhalten beibehalten für andere Ereignisse
                      return QStyledItemDelegate::editorEvent(event, model, option, index);
                  }
                  
                  
                  
                  
                  
                  
                  
                  // 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";
                   this->lineEdit->setStyleSheet("background: transparent;");
                     
                  
                      QWidget::mousePressEvent(event);
                  }
                  
                  
                  
                  
                  
                      
                      
                      
                  void ViewLayerItemDelegate::setCurrentlyEditedIndex(const QModelIndex &index)
                  {
                  currentlyEditedIndex = index;
                  }
                      
                  
                  

                  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);
                  
                          this->setStyleSheet("background-color: transparent");
                  
                  
                          layout->addWidget(iconLabel);
                          layout->addSpacing(10);
                          layout->addWidget(lineEdit);
                          layout->addSpacing(10);
                          layout->addWidget(checkBox);
                  
                          // Zugriff auf das QLineEdit-Widget und setzen Sie den Hintergrund transparent
                          lineEdit->setStyleSheet("background-color: transparent;");
                          lineEdit->setFrame(false);
                          lineEdit->setPlaceholderText("<Empty>");
                  
                          checkBox->setStyleSheet("background-color: transparent");
                          
                              //QPoint globalPos = checkBox->mapToGlobal(QPoint(0, 0));
                              //qDebug() << "Global position of checkbox on init: " << globalPos;
                              
                          
                              
                      }
                      
                      // 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;
                      bool editorEvent(QEvent *event, QAbstractItemModel *model, const QStyleOptionViewItem &option, const QModelIndex &index) override;
                      
                      
                      
                       QModelIndex currentlyEditedIndex;
                       
                       
                       void setCurrentlyEditedIndex(const QModelIndex &index);
                  
                      //Speichert die Position wo geklickt wurde
                       QPointF ClickPosition;
                       
                  
                       
                   public slots:
                      
                      void onLineEditTextChanged(const QString &text);
                  
                  
                  signals:
                      
                      
                      
                      
                      
                      
                      
                  
                    
                  };
                     
                  
                  #endif // VIEWLAYERITEMDELEGATE_H
                  
                  
                  1 Reply Last reply
                  0

                  • Login

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