je l'ai fait de mon mieux et voici ma solution. Le code de la sous-classe QStyledItemDelegate est principalement de here.
Solution Photo
Cependant, il y a une des choses que je suis curieux de fixer: (peut-être quelqu'un peut me aider et a laissé un commentaire)
QPixmap::grabWidget is deprecated, use QWidget::grab() instead
mais il ressemble QWidget::grab()
n'est pas la bonne solution à cette fin.
foo.h:
#ifndef LIBRARYITEMDELEGATE_H
#define LIBRARYITEMDELEGATE_H
#include <QStyledItemDelegate>
#include <QWidget>
#include <QPushButton>
#include <QTableView>
class LibraryItemDelegate : public QStyledItemDelegate
{
Q_OBJECT
public:
explicit LibraryItemDelegate(QObject *parent = 0);
~LibraryItemDelegate();
void paint(QPainter *painter, const QStyleOptionViewItem &option, const QModelIndex &index) const Q_DECL_OVERRIDE;
// QSize sizeHint(const QStyleOptionViewItem &option, const QModelIndex &index) const Q_DECL_OVERRIDE;
QWidget *createEditor(QWidget *parent, const QStyleOptionViewItem &option, const QModelIndex &index) const Q_DECL_OVERRIDE;
void setEditorData(QWidget *editor, const QModelIndex &index) const Q_DECL_OVERRIDE;
void setModelData(QWidget *editor, QAbstractItemModel *modal, const QModelIndex &index) const Q_DECL_OVERRIDE;
void updateEditorGeometry(QWidget *editor, const QStyleOptionViewItem &option, const QModelIndex &index) const Q_DECL_OVERRIDE;
public slots:
void cellEntered(const QModelIndex &index);
private:
QTableView *myView;
QPushButton *btn;
bool isOneCellInEditMode;
QPersistentModelIndex currentEditedCellIndex;
};
#endif // LIBRARYITEMDELEGATE_H
foo.cpp:
#include "libraryitemdelegate.h"
#include <QPainter>
#include <QStylePainter>
LibraryItemDelegate::LibraryItemDelegate(QObject *parent) : QStyledItemDelegate(parent)
{
if(QTableView *tableView = qobject_cast<QTableView*>(parent))
{
myView = tableView;
btn = new QPushButton("...", myView);
btn->hide();
myView->setMouseTracking(true);
connect(myView, SIGNAL(entered(QModelIndex)), this, SLOT(cellEntered(QModelIndex)));
isOneCellInEditMode = false;
}
}
LibraryItemDelegate::~LibraryItemDelegate(){}
void LibraryItemDelegate::paint(QPainter *painter, const QStyleOptionViewItem &option, const QModelIndex &index) const
{
if(index.model()->headerData(index.column(), Qt::Horizontal, Qt::UserRole).toInt() == 1)
{
btn->setGeometry(option.rect);
btn->setText("...");
if(option.state == QStyle::State_Selected)
{
painter->fillRect(option.rect, option.palette.highlight());
}
QPixmap map = QPixmap::grabWidget(btn);
painter->drawPixmap(option.rect.x(), option.rect.y(), map);
}
else
{
QStyledItemDelegate::paint(painter, option, index);
}
}
//QSize LibraryItemDelegate::sizeHint(const QStyleOptionViewItem &option, const QModelIndex &index) const
//{
// // return the QSize of the item in Your view
//}
QWidget *LibraryItemDelegate::createEditor(QWidget *parent, const QStyleOptionViewItem &option, const QModelIndex &index) const
{
if(index.model()->headerData(index.column(), Qt::Horizontal, Qt::UserRole).toInt() == 1)
{
QPushButton *btn = new QPushButton(parent);
// btn->setText(index.data().toString());
btn->setText("...");
return btn;
}
else
{
return QStyledItemDelegate::createEditor(parent, option, index);
}
}
void LibraryItemDelegate::setEditorData(QWidget *editor, const QModelIndex &index) const
{
if(index.model()->headerData(index.column(), Qt::Horizontal, Qt::UserRole).toInt() == 1)
{
QPushButton *btn = qobject_cast<QPushButton*>(editor);
// btn->setProperty("data_value", index.data());
btn->setProperty("data_value", "...");
btn->setText("...");
}
else
{
QStyledItemDelegate::setEditorData(editor, index);
}
}
void LibraryItemDelegate::setModelData(QWidget *editor, QAbstractItemModel *model, const QModelIndex &index) const
{
if(index.model()->headerData(index.column(), Qt::Horizontal, Qt::UserRole).toInt() == 1)
{
QPushButton *btn = qobject_cast<QPushButton*>(editor);
model->setData(index, btn->property("data_value"));
}
else
{
QStyledItemDelegate::setModelData(editor, model, index);
}
}
void LibraryItemDelegate::updateEditorGeometry(QWidget *editor, const QStyleOptionViewItem &option, const QModelIndex &index) const
{
editor->setGeometry(option.rect);
}
void LibraryItemDelegate::cellEntered(const QModelIndex &index)
{
if(index.model()->headerData(index.column(), Qt::Horizontal, Qt::UserRole).toInt() == 1)
{
if(isOneCellInEditMode)
{
myView->closePersistentEditor(currentEditedCellIndex);
}
myView->openPersistentEditor(index);
isOneCellInEditMode = true;
currentEditedCellIndex = index;
}
else
{
if(isOneCellInEditMode)
{
isOneCellInEditMode = false;
myView->closePersistentEditor(currentEditedCellIndex);
}
}
}
Mise en œuvre:
QStandardItemModel *myModel; // This is in the Header file
myModel = new QStandardItemModel(0,2,this);
myModel->setHeaderData(1, Qt::Horizontal, 1, Qt::UserRole);
myModel->setHorizontalHeaderLabels(QStringList(tr("Pfad zu den bibliotheks Ordnern")));
// Set Model and delegate to the View
ui->tableView_pathes->setModel(myModel);
LibraryItemDelegate *delegate = new LibraryItemDelegate(ui->tableView_pathes);
ui->tableView_pathes->setItemDelegate(delegate);
// Stretch only the first column
ui->tableView_pathes->horizontalHeader()->setSectionResizeMode(0,QHeaderView::Stretch);
ui->tableView_pathes->horizontalHeader()->setSectionResizeMode(1,QHeaderView::Fixed);
Edit: Voici le code pour les boutons du tableView. Connectez les signaux dans createEditor avec connect(btn, SIGNAL(pressed()), this, SLOT(buttonPressed()));
et définissez le délégué au QStandardItemModel.
void LibraryItemDelegate::buttonPressed()
{
QString dir = QFileDialog::getExistingDirectory(new QWidget(), tr("Wähle die bibliotheks Ordner"), "/home", QFileDialog::ShowDirsOnly);
qDebug() << "Test: " << dir;
if(!dir.isEmpty())
{
QModelIndex ind = currentEditedCellIndex.model()->index(currentEditedCellIndex.row(), 0);
myModel->setData(ind, dir, Qt::DisplayRole);
}
}
Est-ce que cela fonctionne réellement? Par exemple, le contrôle disparaît une fois l'édition terminée. – Mikhail
@Mikhail Ce code provient de mon application, donc cela devrait fonctionner. Mais il y a une chance que j'ai oublié de coller quelque chose, donc si vous l'avez essayé, et ça n'a pas marché, faites le moi savoir. – Szpaqn
Oui, donc le bouton disparaîtra quand sa cellule n'est pas activée. Ou plus précisément, 'paint()' est appelé, ce qui ne fait rien. Comment garder le bouton présent lorsqu'il n'est pas activé n'est pas trivial, vous pouvez voir l'autre réponse utilisée une méthode de capture d'écran obsolète. – Mikhail