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.
Forum Updated to NodeBB v4.3 + New Features

QTreeView prevent stacking indentation after certain childs.

Scheduled Pinned Locked Moved Unsolved General and Desktop
8 Posts 3 Posters 728 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