Qt 中用于项(Item)处理的组件有两类,一类是 Item Views,包括 QListView、QTreeView、 QTableView、QColumnView 等;另一类是 Item Widgets,包括 QListWidget、QTreeWidget 和 QTable Widget。QListWidget其实是QListView的遍历类,QListView 是基于模型/视图(Model/View)结构,视图(View)与模型数据(Model Data)关联实现数据的显示和编辑;而QListWidget 可直接对每一项直接操作,所以对于一些简单的界面显示,可采用QListWidget ,如果对于一些复杂的显示,实现数据和界面显示分离,可采用QListView 。
下面给大家介绍QListWidget控件的常见使用。
在UI设计器上,手动拉一个ListWidget控件,如图:
双击 ListWidget 组件,可以打开其列表项编辑器,如图 所示。在这个编辑器里可以增加、删除、上移、下移列表项,可以设置每个项的属性,包括文字内容、字体、文字对齐方式、背景色、前景色等。
比较重要的是其 flags 属性(如图 3 所示),用于设置项的一些标记,这些标记是枚举类型 Qt::ItemFlag 的具体值,包括以下几种:
UserCheckable:项是否可以被复选,若为 true,项前面出现一个 CheckBox,对应枚举值 Qt::ItemlsUserCheckable。
Enabled:项是否被使能,对应枚举值 Qt:: ItemlsEnabled。
Tristate:是否允许 Check 的第三种状态,若为 false,则只有 checked 和 unchecked 两种状态,对应枚举值 Qt::ItemIsAutoTristate。
在代码中设置项的 flags 属性时,使用函数 setFlags(),例如:
aItem->setFlags(Qt::ItemIsSelectable | Qt::ItemIsUserCheckable |Qt::ItemIsEnabled);
不过QListWidget 的列表项一般是在程序里动态创建。所以下面通过一个例子给大家介绍该控件的动态创建。
UI界面如图:
1、首先是实现插入项的功能,也就是新增一项,代码如下:
void Widget::on_InsertBtn_clicked()
{
//首先是获取项的总数
int itemCount = ui->listWidget->count();
//new一个空的子项
QListWidgetItem * item = new QListWidgetItem;
//初始化空的子项,比如设置颜色,高度,内容等等
//设置大小
item->setSizeHint(QSize(ui->listWidget->width(),50));
//设置内容
item->setText(QString("自定义子项%1").arg(itemCount));
//设置属性
item->setFlags(Qt::ItemIsEditable|Qt::ItemIsEnabled|Qt::ItemIsUserCheckable);//双击可被编辑,可选中
item->setCheckState(Qt::Unchecked);//默认 不选中状态
//最后将初始化好的子项插入到listWidget控件中
ui->listWidget->addItem(item);
}
2、删除项,删除当前选中的项,代码如下:
void Widget::on_DelBtn_clicked()
{
//先判断当前是否选中,如果没有选中则提示
if(!ui->listWidget->currentItem()){
QMessageBox::warning(this,"警告","请先选中当前项再进行删除!");
return;
}
//获取当前想要删除的子项
QListWidgetItem * delItem = ui->listWidget->takeItem(ui->listWidget->currentRow());
if(delItem)//注意需要手动删除
delete delItem;
}
这里需要注意的是takeItem函数,查看QT官方手册介绍:
QListWidgetItem *QListWidget::takeItem(int row)
Removes and returns the item from the given row in the list widget; otherwise returns nullptr.
Items removed from a list widget will not be managed by Qt, and will need to be deleted manually.
大体的意思是:
从列表小部件的给定行中移除并返回项;否则返回nullptr。
从列表小部件中删除的项目将不由Qt管理,需要手动删除。
所以在这里我们需要手动删除子项。
3、清空列表,调用clear()函数即可。
void Widget::on_ClearBtn_clicked()
{
ui->listWidget->clear();
}
4、状态栏的显示
void Widget::on_listWidget_currentRowChanged(int currentRow)
{
//如果没有子项,直接退出
if(currentRow<0)
return;
//获取当前项
QListWidgetItem *curItem = ui->listWidget->currentItem();
//获取内容
QString curText = curItem->text();
//在状态栏进行显示内容和选中状态
QString stateText;
stateText = (QString("当前选中第%1项:").arg(currentRow)+curText);
if(curItem->checkState() == Qt::Checked)
stateText += " 选中";
else
stateText += " 没有选中";
ui->StateLabel->setText(stateText);
}
5、右键菜单功能显示
首先在构造函数生效,自定义菜单策略,代码如下:
//设置控件的自定义菜单策略
ui->listWidget->setContextMenuPolicy(Qt::CustomContextMenu);
当用户点击鼠标右键时,listWidget控件 会发射信号customContextMenuRequested(const QPoint &pos),关联槽函数,代码如下:
void Widget::on_listWidget_customContextMenuRequested(const QPoint &pos)
{
//定义菜单类,listWidget控件为父类,作用就是把菜单和控件进行绑定
QMenu *m_menu = new QMenu(ui->listWidget);
QAction *act;
//new一个Action功能类,菜单的子项
act = new QAction(this);
act->setText("插入项");
//当触发该子项时,执行对应的槽函数
connect(act,SIGNAL(triggered()),this,SLOT(on_InsertBtn_clicked()));
//将该子项插入菜单中
m_menu->addAction(act);
//执行菜单,菜单的位置在当前光标位置上
m_menu->exec(QCursor::pos());
delete m_menu;//执行完毕删除菜单
}
6、常用设置
排序
ui->listWidget->setSortingEnabled(true);//生效排序
ui->listWidget->sortItems(Qt::DescendingOrder); //降序
显示方式
ui->listWidget->setViewMode(QListView::IconMode);
该实例可在博主的博客资源中下载(关注可下载)。资源名称:Listwidget控件实例1
void Widget::InitListwidget()
{
//自定义菜单策略
ui->listWidget->setContextMenuPolicy(Qt::CustomContextMenu);
//设置视图显示方式为图标模式(图标在上,文字在下)
ui->listWidget->setViewMode(QListView::IconMode);
//设置可以选择多项
ui->listWidget->setSelectionMode(QAbstractItemView::ExtendedSelection);
//设置背景颜色,使每个子项之间的间距有颜色区别
//ui->listWidget->setStyleSheet("background:transparent;");
//设置无边框
ui->listWidget->setFrameShape(QFrame::NoFrame);
//设置子项不能被拖拽
ui->listWidget->setDragEnabled(false);
//设置子项每个图标的大小
ui->listWidget->setIconSize(QSize(200,200));
//设置每个子项的大小固定
ui->listWidget->setUniformItemSizes(true);
//设置QLisView大小改变时,图标的调整模式,默认是固定的,可以改成自动调整
ui->listWidget->setResizeMode(QListView::Adjust);
//设置每个子项之间的间距
ui->listWidget->setSpacing(10);
//设置样式,直接在函数中设置
ui->listWidget->setStyleSheet("QListWidget{border:1px solid gray; color:black;background:transparent;}"
"QListWidget::Item{padding-top:20px; padding-bottom:4px; }"
"QListWidget::Item:hover{background:skyblue; }"
"QListWidget::item:selected{background:lightgray; color:red; }"
"QListWidget::item:selected:!active{border-width:0px; background:lightgreen; }"
);
}
2、打开文件
//打开文件
void Widget::on_OpenBtn_clicked()
{
QStringList fileNameList = QFileDialog::getOpenFileNames(this,"文件",".","图片文件(*.png *.jpg *.bmp)");
if(fileNameList.isEmpty())
return;
for(int i=0; i<fileNameList.count(); i++)
{
//创建子项,将图片作为icon,文件名作为文字描述
QListWidgetItem *item = new QListWidgetItem;
//设置子项
//图片作为子项的图标
QPixmap pic(fileNameList.at(i));
item->setIcon(QIcon(pic.scaled(QSize(200,200))));
//item->setSizeHint(QSize(100,50));
//文件名作为子项的文字描述
QFileInfo file(fileNameList.at(i));
item->setText(file.fileName());
//设置文字对齐方向,水平居中
item->setTextAlignment(Qt::AlignHCenter);
//将item子项插入 listwidget控件中,或者在new子项的时候传入父控件相当于添加item
ui->listWidget->addItem(item);
}
}
3、删除文件
//删除文件
void Widget::on_DelBtn_clicked()
{
//先判断当前列表是否为空
if(ui->listWidget->count()==0)
return;
//获取当前要删除的子项,可多选
QList<QListWidgetItem*> delItemList = ui->listWidget->selectedItems();
for(int i=0; i<delItemList.count(); i++)
{
//takeItem只是将该项从listwidget控件中移除,所以还要手动删除
QListWidgetItem *delItem = ui->listWidget->takeItem(ui->listWidget->row(delItemList.at(i)));
if(delItem)
delete delItem;
}
}
4、清空文件
void Widget::on_ClearBtn_clicked()
{
ui->listWidget->clear();
}
该实例可在博主的博客资源中下载(关注可下载)。资源名称:
<使用listwidget控件制作的缩略图项目>
在我们平时开发过程中,一般会自定义listwidget控件的子项和子项的窗口,详情请下载博主的源码