Qt自定义委托之按钮控件

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 <QItemDelegate>
#include <QPushButton>
#include <QModelIndex>
#include <QFileDialog>
#include <QAbstractItemModel>
#include <QDebug>



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<QAbstractItemModel*>(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<SelectFileButton*>(editor);
	pBtn->setToolTip(strValue);
}

void SelectFileButtonDelegate::setModelData(QWidget *editor, QAbstractItemModel *model,
	const QModelIndex &index) const
{
	SelectFileButton *pBtn = static_cast<SelectFileButton*>(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 是列索引值

如果对你有一点点帮助,欢迎下方评论;

  • 5
    点赞
  • 36
    收藏
    觉得还不错? 一键收藏
  • 3
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值