@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