【问题标题】:QListWidget with items checkable on item clickQListWidget 带有可在项目单击时检查的项目
【发布时间】:2015-03-09 14:34:36
【问题描述】:

我有一个带有可检查项目的 QListWidget,到目前为止它工作正常。现在我想检查项目,不仅要点击小复选框矩形,还要点击项目本身。

所以我实现了这个功能

void TagList::on_tagList_itemClicked(QListWidgetItem *item)
{
    if( item==nullptr )
        return;

    clicked_ = true;
    if( item->data(Qt::CheckStateRole) != Qt::Checked  )
        item->setData( Qt::CheckStateRole, Qt::Checked );
    else
        item->setData( Qt::CheckStateRole, Qt::Unchecked );
    clicked_ = false;
}

(clicked_ 是我接下来描述的肮脏黑客的类变量。)

这会在项目单击时设置检查状态,但是现在这些项目不再可以通过单击复选框矩形来检查,因为它被两次切换,由 ListWidget 和我的插槽切换。 不幸的是,ListWidget 仅使用单列模型,因此我无法区分单击复选框和单击模型索引的项目。

然后我也实现了

void TagList::onModelItemChanged(QModelIndex tl, QModelIndex br, QVector<int> roles)
{
if( (roles.empty() || roles.contains(Qt::CheckStateRole)) && !clicked_ ){
    qDebug() << "changed with no click";
    clicked_ = true;
    if( tl.data(Qt::CheckStateRole)== Qt::Unchecked )
        ui->tagList->model()->setData(tl,Qt::Checked,Qt::CheckStateRole);
    else
        ui->tagList->model()->setData(tl,Qt::Unchecked,Qt::CheckStateRole);
    clicked_ = false;
}else{
    qDebug() << "changed after click";
}
}

并将其连接到模型的 dataChanged 信号。这工作正常,但列表也是可编辑的,所以每当我重命名列表中的对象时,检查状态会发生变化,不幸的是,列表小部件也忽略了 dataChanged 信号的角色向量。因此,roles.empty() 情况总是适用 :( 并且重命名会触发检查状态更改...

有没有人为这种情况提供简单的解决方案?我不想仅仅为这个简单的案例创建自己的模型。

【问题讨论】:

  • 在这种情况下,我可能会重载mouseReleaseEvent(QMouseEvent*) 并尝试找出点击是在文本还是复选框上,如果它在文本。当然,您需要检查这是否适用于不同的字体大小等。这也有点像黑客,但我最好的主意来自我的头脑

标签: c++ qt


【解决方案1】:

您只需在添加新项目时取消设置Qt::ItemIsUserCheckable 标志:

void TagList::addNewTag(QString name) 
{
    QListWidgetItem *item= new QListWidgetItem(name, ui->tagList);
    item->setFlags(item->flags() & (~Qt::ItemIsUserCheckable));
    item->setCheckState(Qt::Unchecked);
    ui->tagList->addItem(item);
}

这样当用户点击复选框时,项目的检查状态不会改变。

然后像你一样实现on_tagList_itemClicked 槽:

void TagList::on_tagList_itemClicked(QListWidgetItem *item)
{
    if(item == nullptr)
        return;
    if(item->data(Qt::CheckStateRole) != Qt::Checked)
        item->setData(Qt::CheckStateRole, Qt::Checked);
    else
        item->setData(Qt::CheckStateRole, Qt::Unchecked);
}

【讨论】:

    【解决方案2】:

    hacky 但可行的解决方案是在模型的每个 datachanged 信号上启动 QTimer::singleshot() 60 毫秒,并阻止 itemClicked 信号直到计时器完成。

    如果您有更好的解决方案,请告诉我。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2019-09-25
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多