Skip to content
  • Categories
  • Recent
  • Tags
  • Popular
  • Users
  • Groups
  • Search
  • Get Qt Extensions
  • Unsolved
Collapse
Brand Logo
  1. Home
  2. Qt Development
  3. General and Desktop
  4. QStyledItemDelegate how to force close the editor?
Forum Updated to NodeBB v4.3 + New Features

QStyledItemDelegate how to force close the editor?

Scheduled Pinned Locked Moved Unsolved General and Desktop
4 Posts 2 Posters 374 Views 1 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

    I have an QTreeView and when doubleclicking the editor opens.
    I want it so when i double click on a certain point of my QTreeview that the editor is closed directly for the index where the index was created.

    In short im searching for a way to prevent opening the editor when double clicking on a certain position of my item. But still the editor should open when clicking elsewhere.

    How could this be done? Thanks.

    cf375cad-22cf-4c12-81c4-22f7be862d35-image.png
    Doubleclicking the checkbox currently is triggering the createEditor of my delegate i only want the editor to be created when double clicking above the lineEdit. Here is my code:

    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);
            
            emit SendCloseEditorToViewLayerList(index);
            
                        
    
            }
         
    
    
    
            
          }
              
            
            
            
    
            
    
          
       }
        
        
        // 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;
    }
        
    
    
    Christian EhrlicherC 1 Reply Last reply
    0
    • S StudentScripter

      I have an QTreeView and when doubleclicking the editor opens.
      I want it so when i double click on a certain point of my QTreeview that the editor is closed directly for the index where the index was created.

      In short im searching for a way to prevent opening the editor when double clicking on a certain position of my item. But still the editor should open when clicking elsewhere.

      How could this be done? Thanks.

      cf375cad-22cf-4c12-81c4-22f7be862d35-image.png
      Doubleclicking the checkbox currently is triggering the createEditor of my delegate i only want the editor to be created when double clicking above the lineEdit. Here is my code:

      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);
              
              emit SendCloseEditorToViewLayerList(index);
              
                          
      
              }
           
      
      
      
              
            }
                
              
              
              
      
              
      
            
         }
          
          
          // 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;
      }
          
      
      
      Christian EhrlicherC Online
      Christian EhrlicherC Online
      Christian Ehrlicher
      Lifetime Qt Champion
      wrote on last edited by Christian Ehrlicher
      #2

      I don't see a way to achieve this in the delegate - I would override QAIV::edit() and add the appropriate checks in there.

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

      S 1 Reply Last reply
      0
      • Christian EhrlicherC Christian Ehrlicher

        I don't see a way to achieve this in the delegate - I would override QAIV::edit() and add the appropriate checks in there.

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

        @Christian-Ehrlicher i have overwritten the edit event but how do i prevent or close the createEditor of my delegate? I tried leaving out the call for the edit event in this case, but sadly this way my delegates editevent logic isnt working anymore when clicking on this area.

        bool ViewLayerList::edit(const QModelIndex &index, EditTrigger trigger, QEvent *event)
        {
        
              if (event && (event->type() == QEvent::MouseButtonPress)) {
                QMouseEvent *mouseEvent = static_cast<QMouseEvent*>(event);
                QPoint clickPosition = mouseEvent->pos();
                qDebug() << "EVENT CLICKPOS: " << clickPosition;
                
                
                    QRect itemRect = this->visualRect(index);
                qDebug() << "Item size: " << itemRect.size();
            
                 if(clickPosition.x() >= itemRect.width()-30 && clickPosition.x() <= itemRect.width())
                 {
                 qDebug() << "Kein Editor erstellt";
                 
                 }else if(clickPosition.x() < itemRect.width()-30){
                  return QTreeView::edit(index, trigger, event);
                 }
                
            }
        
         
            
           
        }
        
        
        

        Alternatively i would like to close the editor here: (Have a look at the comment)

        #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
                
        
            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);
                
               
                
        
        
                //CLOSE THE EDITOR HERE!!!!!!!!!!!!!!!!!!!
        
        
                            
        
                }
             
        
        
        
                
              }
                  
                
                
                
        
                
        
              
           }
            
            
            // Standardverhalten beibehalten für andere Ereignisse
            return QStyledItemDelegate::editorEvent(event, model, option, index);
        }
        
        
        
        
        
        
        Christian EhrlicherC 1 Reply Last reply
        0
        • S StudentScripter

          @Christian-Ehrlicher i have overwritten the edit event but how do i prevent or close the createEditor of my delegate? I tried leaving out the call for the edit event in this case, but sadly this way my delegates editevent logic isnt working anymore when clicking on this area.

          bool ViewLayerList::edit(const QModelIndex &index, EditTrigger trigger, QEvent *event)
          {
          
                if (event && (event->type() == QEvent::MouseButtonPress)) {
                  QMouseEvent *mouseEvent = static_cast<QMouseEvent*>(event);
                  QPoint clickPosition = mouseEvent->pos();
                  qDebug() << "EVENT CLICKPOS: " << clickPosition;
                  
                  
                      QRect itemRect = this->visualRect(index);
                  qDebug() << "Item size: " << itemRect.size();
              
                   if(clickPosition.x() >= itemRect.width()-30 && clickPosition.x() <= itemRect.width())
                   {
                   qDebug() << "Kein Editor erstellt";
                   
                   }else if(clickPosition.x() < itemRect.width()-30){
                    return QTreeView::edit(index, trigger, event);
                   }
                  
              }
          
           
              
             
          }
          
          
          

          Alternatively i would like to close the editor here: (Have a look at the comment)

          #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
                  
          
              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);
                  
                 
                  
          
          
                  //CLOSE THE EDITOR HERE!!!!!!!!!!!!!!!!!!!
          
          
                              
          
                  }
               
          
          
          
                  
                }
                    
                  
                  
                  
          
                  
          
                
             }
              
              
              // Standardverhalten beibehalten für andere Ereignisse
              return QStyledItemDelegate::editorEvent(event, model, option, index);
          }
          
          
          
          
          
          
          Christian EhrlicherC Online
          Christian EhrlicherC Online
          Christian Ehrlicher
          Lifetime Qt Champion
          wrote on last edited by
          #4

          @StudentScripter said in QStyledItemDelegate how to force close the editor?:

          but sadly this way my delegates editevent logic isnt working anymore when clicking on this area.

          What does this mean?
          clickPosition is relative to the view, not relative to the current cell (how should it be?).

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

          1 Reply Last reply
          0

          • Login

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