Qt中显示数据有个很好的控件QTableWidget; 功能很强大,可以排序,可以在单元格添加控件(table->setCellWidget(0,0,pWidget);)
不过有时候还是不能满足需要。我自己就遇到了一个需求:显示的时候除了进度条,其他都要显示文字或者数字等其他数据;编辑的时候要显示控件,比如QSpinBox、QComboBox。这两个其实都还好解决,特别是QSpinBox 在Qt的例子里面既有现成的“Spin Box Delegate Example”。关键是一个选择文件的按钮,选择完毕以后要显示文件路径。网上搜了很久都没有。不过类似的都是逃不过自定义委托。
自定义委托逃不过:
QTableView、QStandardItemModel/QAbstractItemModel 、QStyledItemDelegate/QItemDelegate和QModelIndex;
先上图看效果吧
选择文件按钮这一列,第0行是点击后进入编辑模式时显示按钮的情况。
下面一行是显示的选择文件的全路径。
第2行”C:“是初始化时设置的值,只是为了测试显示。
最后一行是没有选择文件。
我实现的这个SelectFileButton办法:
a、定义一个类继承自QPushButton; class SelectFileButton: public QPushButton{}
b、在自定义的类SelectFileButton里实现一个槽函数:功能,点击时选择文件并返回路径。
c、委托控件继承自QItemDelegate;
d、然后再重写createEditor();返回SelectFileButton的指针
e、重写setModelData()、setEditorData(); 设置模型数据和设置编辑数据的。
上代码吧:
#ifndef SELECTFILEBUTTONDELEGATE_H
#define SELECTFILEBUTTONDELEGATE_H
#include
#include
#include
#include
#include
#include
class SelectFileButton: public QPushButton
{
Q_OBJECT
public:
SelectFileButton(const QModelIndex & index, QWidget *parent = 0)
: QPushButton(parent)
{
Init(index);
}
SelectFileButton(const QModelIndex & index, const QString &text, QWidget *parent = 0)
: QPushButton(text, parent)
{
Init(index);
}
SelectFileButton(const QModelIndex & index, const QIcon& icon, const QString &text, QWidget *parent = 0)
:QPushButton(icon, text, parent)
{
Init(index);
}
~SelectFileButton() {
qDebug() << "~SelectFileButton";
}
protected:
void Init(const QModelIndex & index)
{
m_index = index;
connect(this, SIGNAL(clicked()), this, SLOT(btnClick_slot()));
}
public slots:
void btnClick_slot()
{
QString strValue;
QModelIndex index = this->m_index;
QFileDialog * pDlg = new QFileDialog(0);
int res = pDlg->exec(); //这里开启新的线程,顶层会释放这个按钮,所以要把Index 保存一份
if (res==QFileDialog::Accepted)
{
strValue = pDlg ->selectedFiles()[0];
QAbstractItemModel* model = const_cast(index.model());
model->setData(index, strValue);
}
}
private:
QModelIndex m_index;
};
/********************class SelectFileButtonDelegate *****************************/
class SelectFileButtonDelegate : public QItemDelegate
{
Q_OBJECT
public:
SelectFileButtonDelegate(QObject *parent);
~SelectFileButtonDelegate();
public:
QWidget *createEditor(QWidget *parent, const QStyleOptionViewItem &option,
const QModelIndex &index) const
{
SelectFileButton* pBtn = new SelectFileButton(index,QStringLiteral("查找文件路径"), parent); //这个是其他线程里的 所以不能保存下来。每次的btn还不一样
return pBtn;
}
void setModelData(QWidget *editor, QAbstractItemModel *model,
const QModelIndex &index) const;
void setEditorData(QWidget *editor, const QModelIndex &index) const;
};
#endif //!SELECTFILEBUTTONDELEGATE_H
Cpp文件 :
#include "SelectFileButtonDelegate.h"
//将Model中数据赋值到控件上
void SelectFileButtonDelegate::setEditorData(QWidget *editor,
const QModelIndex &index) const
{
//返回该索引的模型,继而返回该模型中此索引的编辑角色数据
QString strValue = index.model()->data(index, Qt::EditRole).toString();
//给控件赋值
SelectFileButton *pBtn = static_cast(editor);
pBtn->setToolTip(strValue);
}
void SelectFileButtonDelegate::setModelData(QWidget *editor, QAbstractItemModel *model,
const QModelIndex &index) const
{
SelectFileButton *pBtn = static_cast(editor);
QString strValue = pBtn ->toolTip();
//设置模型的数据
model->setData(index, strValue, Qt::EditRole);
}
SelectFileButtonDelegate::SelectFileButtonDelegate(QObject *parent)
: QItemDelegate(parent)
{
}
SelectFileButtonDelegate::~SelectFileButtonDelegate()
{
}
在QTableView里面设置某一列为自定义委托控件:
pTableView->setItemDelegateForColumn(4, new SelectFileButtonDelegate(this) );// 4 是列索引值
如果对你有一点点帮助,欢迎下方评论;