QTreeWidget提供许多自身状态改变信号,但是缺少了一种常用的信号:勾选其中某一项时的信号(使用的QTreeWidgetItem是可以Check的,通过setCheckState设置)
没有Check信号时,可以使用void itemChanged(QTreeWidgetItem * item, int column)
这个信号,但是这个信号的触发情况太多,随便选择一项(并不是勾选,而是某一项被选中[类似于Windows中全选的那种反色显示的效果])也会触发,在代码中调用某些接口也会导致这个信号被触发。导致代码逻辑中会处理大量避免循环调用的情况,并不是很方便。为此可以为QTreeWidget添加勾选信号。
通过继承QTreeWidget和QTreeWidgetItem定义这两个类,提供信号和数据处理的设置,步骤如下:
需要从QTreeWidget定义一个信号,代码如下:
class TestWidgetTree : public QTreeWidget
{
Q_OBJECT
public:
TestWidgetTree (QWidget * parent = 0) : QTreeWidget(parent){}
~TestWidgetTree (){ }
signals:
void itemCheckStateChanged(ThreeDTreeWidgetItem*, bool);
};
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);
}
}
在使用的时候非常简单,在构建树结构的时候需要使用我们定义的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.
}
}
1.QTreeWidget Class
2.Is it possible to create a signal for when a QTreeWidgetItem checkbox is toggled?