QTreeWidget勾选QTreeWidgetItem的处理

1. 简介

QTreeWidget提供许多自身状态改变信号,但是缺少了一种常用的信号:勾选其中某一项时的信号(使用的QTreeWidgetItem是可以Check的,通过setCheckState设置)

没有Check信号时,可以使用void itemChanged(QTreeWidgetItem * item, int column) 这个信号,但是这个信号的触发情况太多,随便选择一项(并不是勾选,而是某一项被选中[类似于Windows中全选的那种反色显示的效果])也会触发,在代码中调用某些接口也会导致这个信号被触发。导致代码逻辑中会处理大量避免循环调用的情况,并不是很方便。为此可以为QTreeWidget添加勾选信号。

2. 设置

通过继承QTreeWidget和QTreeWidgetItem定义这两个类,提供信号和数据处理的设置,步骤如下:

2.1 继承QTreeWidget定义check信号

需要从QTreeWidget定义一个信号,代码如下:

class TestWidgetTree : public QTreeWidget
{
	Q_OBJECT

public:
	TestWidgetTree (QWidget * parent = 0) : QTreeWidget(parent){}
	~TestWidgetTree (){ }

signals:
	void itemCheckStateChanged(ThreeDTreeWidgetItem*, bool);
};

2.2 继承QTreeWidgetItem定义setData

class TestTreeWidgetItem : public QTreeWidgetItem
{
public:
	TestTreeWidgetItem ();

	TestTreeWidgetItem (int type = Type) :QTreeWidgetItem(type){ }
	TestTreeWidgetItem (const QStringList & strings, int type = Type) : QTreeWidgetItem(strings, type){ }
	TestTreeWidgetItem (QTreeWidget * parent, int type = Type) : QTreeWidgetItem(parent, type){}
	TestTreeWidgetItem (QTreeWidget * parent, const QStringList & strings, int type = Type) 
		:QTreeWidgetItem(parent, strings, type){}
	TestTreeWidgetItem (QTreeWidget * parent, QTreeWidgetItem * preceding, int type = Type) 
		: QTreeWidgetItem(parent, preceding, type){}
	TestTreeWidgetItem (QTreeWidgetItem * parent, int type = Type) :QTreeWidgetItem(parent, type){}
	TestTreeWidgetItem (QTreeWidgetItem * parent, const QStringList & strings, int type = Type) 
		:QTreeWidgetItem(parent, strings, type){}
	TestTreeWidgetItem (QTreeWidgetItem * parent, QTreeWidgetItem * preceding, int type = Type) 
		:QTreeWidgetItem(parent, preceding, type){}

	~TestTreeWidgetItem (){}

	void setData(int column, int role, const QVariant& value);
};

void TestTreeWidgetItem ::setData(int column, int role, const QVariant& value)
{
	const bool isCheckChange = column == 0
		&& role == Qt::CheckStateRole
		&& data(column, role).isValid() // Don't "change" during initialization
		&& checkState(0) != value;
	QTreeWidgetItem::setData(column, role, value);
	if (isCheckChange) {
		TestWidgetTree *tree = static_cast(treeWidget());
		emit tree->itemCheckStateChanged(this, checkState(0) == Qt::Checked);
	}
}

3. 使用

在使用的时候非常简单,在构建树结构的时候需要使用我们定义的TestTreeWidget控件,并且它的Item都要使用 TestTreeWidgetItem之后就可以使用TestTreeWidget的 itemCheckStateChanged信号

	connect(_treeWidget3D, SIGNAL(itemCheckStateChanged(ThreeDTreeWidgetItem*, bool)), 
		this, SLOT(itemCheckStateChangedSlot(ThreeDTreeWidgetItem*, bool)));

实现插槽函数 itemCheckStateChangedSlot

void MyMainWindow::itemCheckStateChangedSlot(TestTreeWidgetItem* item, bool isChecked)
{
	if (!item)
		return;

	if (item->isDisabled() || item->flags() == Qt::NoItemFlags)
		return;

	if (isChecked)
	{
		//do some stuff when item is checked.
	}
	else
	{
		//do some stuff when item is unchecked.
	}
}

4. 参考资料

1.QTreeWidget Class

2.Is it possible to create a signal for when a QTreeWidgetItem checkbox is toggled?

你可能感兴趣的:(Windows程序设计,Qt)