注意:QListWidget添加子Item时,最外层最好设置完整背景颜色,否则移入Item会自带淡蓝色背景

一、QListWidget 中使 QListWidgetItem自适应大小
父部件ListWidgetForm.cpp

void ListWidgetForm::setCard()
{
	//设置边距、间距
	ui->listStudy->setContentsMargins(0, 0, 0, 0);
	ui->listStudy->setSpacing(12);
	
	//MessageCardForm 是插入的子Item关联小部件(你自定义的)
	MessageCardForm *card = new MessageCardForm(this);

	//QListWidgetItem不能设置父组件为QListWidget,不然头插不生效,还是插到最后
    QListWidgetItem *newItem = new QListWidgetItem();
    newItem->setSizeHint(card->size());
    newItem->setFlags(Qt::NoItemFlags);

	//1.头插(ui->listStudy是QListWidget)
    ui->listStudy->insertItem(0, newItem);
    //2.尾插
    ui->listStudy->addItem(newItem);
    
    ui->listStudy->setItemWidget(newItem, card);
    //隐藏item
    //ui->listStudy->setItemHidden(newItem, true);
    m_card[card] = newItem;

    //如果需要自适应大小,需要从子部件传出大小改变的信号,
    //进而重新设置QListWidgetItem大小,达到自适应的目的
    connect(card, &MessageCardForm::sizeChange, this, [=]() {
        m_card[card]->setSizeHint(card->size());
    });
}

父部件ListWidgetForm.h

private:
	//一个小部件对应一个子Item,建议使用hash
	QMap<MessageCardForm*, QListWidgetItem*> m_card;

子部件MessageCardForm.cpp

void MessageCardForm::on_btnOpen_clicked()
{
	//子部件由于文本长度不一定,导致部件大小不一
	//所以经过调整大小后,将大小改变的信号发出
    ui->labelLongMessage->setText("百里守约");
    this->adjustSize();
    emit sizeChange();
}

二、删除一条子Item

//子部件发出删除Item信号,父部件开始删除
void ListWidgetForm::onDeleteCard()
{
    MessageCardForm *card = dynamic_cast<MessageCardForm *>(sender());
	
	//删除Item
	QListWidgetItem *widItem =  m_card[card];
    ui->listStudy->removeItemWidget(widItem);
    delete widItem;
    widItem = nullptr;

	//删除存储的键值
    QMapIterator<MessageCardForm*, QListWidgetItem*> i(m_card);
    while (i.hasNext()) {
        i.next();
        if (i.key() == card) {
            m_card.remove(i.key());
        }
    }
}

三、清空Item

void ListWidgetForm::clearItem()
{
	// 第一种写法
    QMapIterator<MessageCardForm*, QListWidgetItem*> i(m_card);
    while (i.hasNext()) {
        i.next();
        QListWidgetItem* curItem = i.value();
        ui->listStudy->removeItemWidget(curItem);
        delete curItem;
        curItem = nullptr;
        m_card.remove(i.key());
    }

	// 第二种写法,一次性拿到item指针,全局方法进行删除
	qDeleteAll(m_card.values());
	m_card.clear();
}

在item被删除时,系统也会自动删除销毁自定义子部件,不会造成内存泄漏


四、滚动条显示与隐藏

//默认显示
//隐藏水平滚动条
ui->listStudy->horizontalScrollBar()->hide();
//隐藏垂直滚动条
ui->listStudy->verticalScrollBar()->hide();

五、滚动条滚动位置

//滚到顶部
ui->listStudy->scrollToTop();
//滚到底部
ui->listStudy->scrollToBottom();

六、得到滚动条的位置

void InfoNoticeForm::init()
{
    //初始化时,连接信号
	connect(ui->listStudy->verticalScrollBar(), SIGNAL(valueChanged(int)),
            this,SLOT(onStudyValueChanged(int)));
}
void InfoNoticeForm::onStudyValueChanged(int num)
{
    if (ui->listStudy->verticalScrollBar()->minimum() == num) {
        qDebug()<<"滚动条最顶部";
    }

    if (ui->listStudy->verticalScrollBar()->maximum() == num) {
        qDebug()<<"滚动条最底部";
    }
}
Logo

开放原子开发者工作坊旨在鼓励更多人参与开源活动,与志同道合的开发者们相互交流开发经验、分享开发心得、获取前沿技术趋势。工作坊有多种形式的开发者活动,如meetup、训练营等,主打技术交流,干货满满,真诚地邀请各位开发者共同参与!

更多推荐