【QT】QListWidget添加自定义Widget后移动Item问题和方法

QT QListWidget添加自定义Widget后移动Item问题和方法

用的qt5.12.12

在QListWidget显示QWidget

像这样添加:

QListWidget *listWidget = new QListWidget;
MyWidget *info = new MyWidget;   //MyWidget继承QWidget,里面有许多控件
QListWidgetItem *item = new QListWidgetItem;
listWidget->addItem(item);
listWidget->setItemWidget(item, info);
item->setSizeHint(info->sizeHint());
........

通过代码中移动item

有需求要把选中的项移动到第一个位置,查了一下可以这样:

//将某个item移动到list的第一个位置,也就是row=0
int currentIndex = listWidget->currentRow();
auto currentItem = listWidget->takeItem(currentIndex);
listWidget->insertItem(0,currentItem);

失败了

运行发现,我的MyWidget 对象 info的析构函数被调用了,也就是info被销毁了,于是列表上显示空白。
我查网上的问题,给的答案都是使用这个方法,还有的是listWidget->model()->moveRow(),测试并没有效果。

但又成功了

经过实验发现,如果item是QString,则上述方法有效,比如:

QApplication app(argc, argv);

    QListWidget listWidget;
    QStringList items;
    items << "Item 1"
          << "Item 2"
          << "Item 3"
          << "Item 4";
    listWidget.addItems(items);

    QPushButton moveButton("Move Selected Item to Top");
    QObject::connect(&moveButton, &QPushButton::clicked, [&]() {
        QList<QListWidgetItem *> selectedItems = listWidget.selectedItems();
        foreach (QListWidgetItem *item, selectedItems) {
            listWidget.insertItem(0, listWidget.takeItem(listWidget.row(item)));
        }
    });

    QVBoxLayout *layout = new QVBoxLayout;
    layout->addWidget(&listWidget);
    layout->addWidget(&moveButton);

    QWidget mainWidget;
    mainWidget.setLayout(layout);
    mainWidget.show();

    return app.exec();

奇技淫巧的方法

用了一个看起来比较奇怪的方法实现了移动,我不明白是为什么(很难受),但它能正常工作:

//先获取当前item的widget
int currentIndex = listWidget->currentRow();
auto *oldItem = listWidget->item(currentIndex);
auto info = listWidget->itemWidget(oldItem);

//创建一个新的item,不要指定父类
QListWidgetItem *newItem = new QListWidgetItem();
//直接在指定位置插入新的item
listWidget->insertItem(0, newItem);
//绑定 info (这一步很关键,我的理解是,newItem把info抢了过来)
listWidget->setItemWidget(newItem, info);
newItem->setSizeHint(info->sizeHint());

//然后再移除旧的item,不要提前删
int oldItemRrow = listWidget->row(oldItem);
delete listWidget->takeItem(row);
//选中我们插入的item,如果有对这个项进行其他操作,释放就的item以后再做
ui->listWidget->setCurrentRow(0);

我想知道有没有其他办法,这个看起来就很不稳定。我刚学不久,比较懒不想自己实现Model-View(主要是不会)……

  • 14
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 4
    评论
好的,关于qlistwidget添加自定义item并且释放内存的问题,可以分为两个部分来回答。 第一部分,如何添加自定义item。在使用qlistwidget时,我们可以通过继承QListWidgetItem类来实现自定义item。具体步骤如下: 1. 创建一个QListWidgetItem类的子类,例如CustomItem。 2. 在CustomItem类中添加新的成员变量和成员函数,用于自定义item的属性和操作。 3. 在CustomItem类中重载paint()函数,实现item的绘制。也可以使用QPainter对象绘制。 4. 在主程序中使用QListWidget的addItem()函数添加CustomItem对象到列表中。 代码示例: ``` class CustomItem : public QListWidgetItem { public: CustomItem(const QString &text, QWidget *parent = nullptr) : QListWidgetItem(text, parent) {} QString customText() const { return m_customText; } void setCustomText(const QString &text) { m_customText = text; } protected: void paint(QPainter *painter, const QStyleOptionViewItem &option, const QModelIndex &index) const override { // 绘制自定义item painter->drawText(option.rect, m_customText); } private: QString m_customText; }; // 添加自定义item CustomItem *item = new CustomItem("Custom Item", listWidget); item->setCustomText("This is a custom item"); listWidget->addItem(item); ``` 第二部分,如何释放内存。在使用qlistwidget时,我们需要手动管理item对象的内存,以避免内存泄漏。具体步骤如下: 1. 在移除item之前,先调用listwidget的takeItem()函数将item从列表中移除。 2. 显式调用delete操作符释放item对象的内存。 代码示例: ``` // 删除item CustomItem *item = static_cast<CustomItem *>(listWidget->takeItem(0)); delete item; ``` 希望这样能够帮助你解决问题

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值