当QTreeWidgetItem的复选框切换时,是否可以创建一个信号?

13
我使用下面的代码创建了一个既是复选框又是QTreeWidgetItem的控件。
//Populate list
QTreeWidgetItem *program = createCheckedTreeItem(QString::fromStdString(itr->first), true);
treePrograms->addTopLevelItem(program);

QTreeWidgetItem* ConfigDialog::createCheckedTreeItem(QString name,bool checkBoxState)
{
  QTreeWidgetItem *item = new QTreeWidgetItem(QStringList(name));
  item->setFlags(item->flags()|Qt::ItemIsUserCheckable);
  if (checkBoxState)
  {
    item->setCheckState(0,Qt::Unchecked);
  }
  else
  {
    item->setCheckState(0,Qt::Checked);
  }
  return item;
}

我需要一种连接信号和槽的方法,以便在更改此复选框的状态时进行响应。我目前实现的方式如下,但不幸的是并没有起作用。有人能解释一下我做错了什么以及我需要做什么才能够连接成功吗?

connect(program, SIGNAL(toggled(bool)), this, SLOT(programChecked(bool)));
5个回答

8

您需要获取来自QTreeWidget的信号itemChanged(QTreeWidgetItem * item, int column)


1
这样不好,因为随着树形数据的变化,它会不断地被标记。 - G Huxley

6

连接到树的信号itemClicked(QTreeWidgetItem* item, int column)。在处理信号时,只需验证item->checkState(column)


当用户仅单击复选框时,不会发出信号。例如,用户单击项目,然后单击复选框。checkState 不会在复选框单击时被调用。至少在 Qt 5.3 中是如此。 - Chrismit
我目前正在使用Qt 5.3.1的fine版本,同时在Mac和Win上运行。 - G Huxley
这个可以工作,但是你必须检查项目的选中状态与你自己的模型进行比较以进行更改。 - kainjow

5

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


@GHuxley 但是你仍然可以连接到QTreeWidget的默认底层模型,例如 treeWidget.model().dataChanged.connect(handle_dataChanged)。不确定这是否比仅连接到itemChanged更好,但它看起来相似。 - blah238

3
我们发现的最佳解决方案是在项目子类中重新实现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);
    }
}

确实将其应用于Qt会非常方便,这让我考虑直接贡献一个itemCheckStateChanged信号 :)

PS:设置Qt :: ItemIsUserCheckable是不必要的,所有QTreeWidgetItems默认都启用此标志。


0
请将此信号添加到您的QTreeWidget对象中:
connect(ui->treeWidget, &QTreeWidget::itemChanged, this, &YourDialog::treeWidgetItemChanged);

所以你可以使用这个插槽来接收信号:

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

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接