写在前面
我们使用QListWidget是想实现单列的列表形式,无论是简单的文本列表形式或是复杂的自定义界面列表形式。
和QTableWidget相似,我们会遇到动态添加内容以及交换两行内容的问题,但是QListWidget与QTableWidget的处理方式会有一点区别,最近也有人问到,刚好在项目中使用到了这部分内容,这里就用一个简单的demo来实现动态添加内容以及交换两行内容。
实现界面和第一种添加方式
首先我们在QtDesigner实现我们的软件界面,同时,QListWidget的第一种添加方式就是在QtDesigner中,这种方式主要为了方便测试。
只需要双击添加进去的QListWidget控件就可以生成一部分的列表内容。

接下来我们添加几个实现我们想法和功能的按钮和spinbox, 界面大概就是下面的样子。
两种内容动态添加方式
有了已经设置好的界面,接下来完成各按钮的响应函数
首先我们来实现最简单的动态添加函数,通过直接添QString的方式。
void ListWidgetDemo::on_addPushButton_string_clicked()
{
ui->listWidget->addItem(QString("第%1行").arg(ui->listWidget->count() + 1));
ui->spinBox_1->setMaximum(ui->listWidget->count());
ui->spinBox_2->setMaximum(ui->listWidget->count());
}
不得不说这个方法对于全文本的列表形式还是非常方便的,但是对于更加复杂的列表形式,比如自定义widget列表形式就不是那么适用,所以我们需要了解更加通用的动态添加方式。
经过实际使用,借助QListWidgetItem 进行内容添加的方式,是我觉得最具适用性的的方式。
void ListWidgetDemo::on_addPushButton_item_clicked()
{
QListWidgetItem *item = new QListWidgetItem(ui->listWidget);//还可以不使用带参构造函数形式,只是需要调用addItem函数
//经过上一步,item已经添加了,只是还没有内容
item->setText(QString("第%1行").arg(ui->listWidget->count()));
ui->spinBox_1->setMaximum(ui->listWidget->count());
ui->spinBox_2->setMaximum(ui->listWidget->count());
}
这里补充说明一下,如果想要添加自定义的widget,,具体的就是使用这个函数
ui->listWidget->setItemWidget(item,widget)
如果需要对每个widget中的控件进行操控,设置,也必须使用这个方式,如果有人需要详细一点的代码,可以评论一下,我之后有时间可以写一写~
交换两行内容
最后就是交换两行内容的按钮
void ListWidgetDemo::on_swapPushButton_clicked()
{
swapTwoRaw(*ui->listWidget, ui->spinBox_1->value() - 1, ui->spinBox_2->value() - 1);
}
具体的交换函数是
/**
* 交换ListWidget两行内容
*/
void ListWidgetDemo::swapTwoRaw(QListWidget &list_widget, int first_row, int second_row)
{
//保证first row永远在second_row之前,方便后面的处理
if (first_row > second_row)
{
int temp = first_row;
first_row = second_row;
second_row = temp;
}
else if (first_row == second_row)//相同的两行不允许进行后续交换操作
{
return;
}
if (second_row > 0)
{
//因为listWidget没有tableWidget中的
QListWidgetItem *first_row_item = list_widget.takeItem(first_row);//首先提取row较小的一行,使用takeItem这个函数会删除这一行
QListWidgetItem *second_row_item = list_widget.takeItem(second_row - 1);//因为,现在总行数-1,所以row较大的一行需要-1才能准确定位
list_widget.insertItem(first_row, second_row_item);//首先在前部,即row较小的一行,插入得到的row较大的一行的QListWidgetItem
list_widget.insertItem(second_row, first_row_item);//然后在后部插入
}
}
写在最后及程序下载
- 其实最开始我是想,如果listWidget有和tablewidget相似的setItem的方式,就非常简单了。直接通过item函数得到两行的内容,再通过setItem函数就可以进行内容交换了,但是把QListWidget的函数看了一个遍也没有这种实现方式。
- 另外还是推荐QListWidgetItem这个更加通用的方法,这样无论item中是文字还是我们自定义的widget,都能很好的工作
说明:程序提供的下载(本程序是利用VS2017+Qt 5.11.2进行编写,建议用相同环境打开,不同的Qt版本可能会导致编译不成功)
程序下载连接