Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/136.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 是否可以在切换QTreeWidgetItem复选框时创建信号?_C++_Qt_Checkbox_Signals Slots_Qtreewidgetitem - Fatal编程技术网

C++ 是否可以在切换QTreeWidgetItem复选框时创建信号?

C++ 是否可以在切换QTreeWidgetItem复选框时创建信号?,c++,qt,checkbox,signals-slots,qtreewidgetitem,C++,Qt,Checkbox,Signals Slots,Qtreewidgetitem,我使用下面的代码创建了一个复选框,它也是一个QTreeWidgetItem //Populate list QTreeWidgetItem *program = createCheckedTreeItem(QString::fromStdString(itr->first), true); treePrograms->addTopLevelItem(program); 我需要一种连接信号和插槽的方式,以便在更改此复选框的状态时使用。下面是我目前实现这一点的方法,但不幸的是不起作用

我使用下面的代码创建了一个复选框,它也是一个QTreeWidgetItem

//Populate list
QTreeWidgetItem *program = createCheckedTreeItem(QString::fromStdString(itr->first), true);
treePrograms->addTopLevelItem(program);

我需要一种连接信号和插槽的方式,以便在更改此复选框的状态时使用。下面是我目前实现这一点的方法,但不幸的是不起作用。有人能解释我做错了什么,我需要做什么才能让它连接起来吗

connect(program, SIGNAL(toggled(bool)), this, SLOT(programChecked(bool)));

您的
QTreeWidgetItem
直接链接到您的模型数据,因此您应该连接到QTreeWidget的模型的
QAbstractItemModel::dataChanged
信号以获得更改通知。

您必须获取信号
itemChanged(QTreeWidgetItem*item,int列)
来自。

连接到树的信号
项已单击(QTreeWidgetItem*项,int列)
。处理信号时,只需验证
item->checkState(column)

我们找到的最佳解决方案是在item子类中重新实现setData:

void MyItem::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) {
        MyTree *tree = static_cast<MyTree *>(treeWidget);
        emit tree->itemCheckStateChanged(this, checkState(0) == Qt::Checked);
    }
}
void MyItem::setData(int列、int角色、const QVariant和value)
{
const bool isCheckChange=列==0
&&role==Qt::CheckStateRole
&&数据(列,角色).isValid()//在初始化期间不“更改”
&&checkState(0)!=值;
QTreeWidgetItem::setData(列、角色、值);
如果(isCheckChange){
MyTree*tree=静态_转换(treeWidget);
emit tree->itemCheckStateChanged(这个,checkState(0)=Qt::Checked);
}
}
在Qt中使用它真的很方便。事实上,它让我想到直接在那里提供一个itemCheckStateChanged信号:)


PS:不需要设置Qt::ItemIsUserCheckable,默认情况下,所有QTreeWidgetItems的此标志都处于启用状态。

将此信号添加到QTreeWidget对象:

connect(ui->treeWidget, &QTreeWidget::itemChanged, this, &YourDialog::treeWidgetItemChanged);
因此,您可以使用此插槽接收信号:

void YourDialog::treeWidgetItemChanged(QTreeWidgetItem *TWI, int column)
{
    //Do some staff
}

这是不好的,因为它会随着树数据的变化而不断发出信号。当用户只单击复选框时,不会发出信号。例如,用户单击该项。然后单击复选框。复选框单击时不会调用checkState。至少对Qt5.3来说是这样的,我目前在Mac和Win上都在Qt5.3.1中使用fine。这是可行的,但您必须对照您自己的模型检查项目的选中状态是否有更改。@GHuxley,但您仍然可以连接到QTreeWidget的底层默认模型,例如
treeWidget.model().dataChanged.connect(handle\u dataChanged)
。不确定这是否比仅仅连接到
itemChanged
更好,但似乎类似。
void YourDialog::treeWidgetItemChanged(QTreeWidgetItem *TWI, int column)
{
    //Do some staff
}