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

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

    • 在QListWidget显示QWidget
    • 通过代码中移动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(主要是不会)……

你可能感兴趣的:(qt,qt5,c++)