ui界面(左边是QListView,右边是plaintexteditor)
模型是QStringListModel,视图是QListView,QListView有自带的QItemSelectionModel,可以不用自己设置
Mainwindow头文件关键内容
QStringList m_strlist;
QStringListModel *m_model;
数据来源是m_strlist,m_model是模型。
Mainwindow构造函数关键内容
MainWindow::MainWindow(QWidget *parent)
: QMainWindow(parent)
, ui(new Ui::MainWindow)
{
ui->setupUi(this);
m_strlist<<"北京"<<"上海"<<"南昌"<<"苏州";//往Stringlist里加内容
m_model=new QStringListModel(this);
m_model->setStringList(m_strlist);//为模型设置数据
ui->listView->setModel(m_model);//为视图设置模型
ui->listView->setEditTriggers(QAbstractItemView::DoubleClicked|
QAbstractItemView::SelectedClicked);//设置EditTriggers属性
}
具体而言,
editTriggers
属性定义了触发编辑的事件。以下是一些可能的值:
QAbstractItemView::NoEditTriggers: 无法触发编辑。用户无法通过点击或其他事件启动编辑操作。
QAbstractItemView::CurrentChanged: 当前项更改时启用编辑。当用户移动到不同的项时,当前项发生变化,此时可以启动编辑。
QAbstractItemView::DoubleClicked: 双击项时启用编辑。只有在用户双击项时,编辑才会启动。
QAbstractItemView::SelectedClicked: 单击已选择的项时启用编辑。只有在用户单击已选择的项时,编辑才会启动。
等等...
问gpt的
查看Qt的帮助文档,以下是所有枚举值
本示例中默认选择的是双击编辑和单击已选项编辑
下面代码是各个按钮的槽函数
void MainWindow::on_pushButton_clicked()//恢复列表
{
m_model->setStringList(m_strlist);//就是重新设置model
}
void MainWindow::on_pushButton_2_clicked()//清除列表
{
m_model->removeRows(0,m_model->rowCount());
//removeRows是清除从row开始的count行,从0开始的所有行就是清除整个列表
}
void MainWindow::on_checkBox_clicked(bool checked)//允许编辑的checkbox
{
if(checked){
ui->listView->setEditTriggers(QAbstractItemView::DoubleClicked|
QAbstractItemView::SelectedClicked);
}
else ui->listView->setEditTriggers(QAbstractItemView::NoEditTriggers);//不允许编辑的话就设置成No
}
void MainWindow::on_pushButton_3_clicked()//添加项
{
//我们这里的增删只在模型中进行,不更改数据源
m_model->insertRow(m_model->rowCount());
//在最后一行增加数据
QModelIndex index=m_model->index(m_model->rowCount()-1);//注意这一行的rowcount已经是增加完后的行数了,所以得到的index是新加的那个项
m_model->setData(index,"new item",Qt::DisplayRole);//设置数据
ui->listView->setCurrentIndex(index);//让选中的项自动变成新增的那个
}
void MainWindow::on_pushButton_4_clicked()//插入项
{
QModelIndex index=ui->listView->currentIndex();
m_model->insertRow(index.row());
//插入的项会把原来的项挤到下面去
m_model->setData(index,"new item",Qt::DisplayRole);
ui->listView->setCurrentIndex(index);
}
void MainWindow::on_pushButton_5_clicked()//删除项
{
m_model->removeRow(ui->listView->currentIndex().row());
}
void MainWindow::on_pushButton_6_clicked()//上移
{
QModelIndex index;//在listview中,parent没有意义,可以随便传一个进去
int currow=ui->listView->currentIndex().row();
m_model->moveRow(index,currow,index,currow-1);
}
//下移为什么加2?
//Qt的设置是如果两个数在同一行,那么老的数据会被挤到新数据的下一行去,所以下移的目的地应该加2
void MainWindow::on_pushButton_7_clicked()//下移
{
QModelIndex index;//在listview中,parent没有意义,可以随便传一个进去
int currow=ui->listView->currentIndex().row();
m_model->moveRow(index,currow,index,currow+2);//如果是+1没有变化,+2是对的
}
void MainWindow::on_pushButton_8_clicked(bool checked)//排序
{
if(checked){
m_model->sort(0,Qt::AscendingOrder);
}
else m_model->sort(0,Qt::DescendingOrder);
}
void MainWindow::on_pushButton_9_clicked()//清空文本
{
ui->plainTextEdit->clear();
}
void MainWindow::on_pushButton_10_clicked()//显示数据模型的stringlist
{
MainWindow::on_pushButton_9_clicked();//显示前先手动清空
QStringList tmp=m_model->stringList();
for(auto &str:tmp){
ui->plainTextEdit->appendPlainText(str);
}
}
最后,我们实现以下QListView的click的槽函数
void MainWindow::on_listView_clicked(const QModelIndex &index)//点击模型上的项会在状态栏显示信息
{
QString str=QString::asprintf("模型索引:row=%d,column=%d",index.row(),index.column());
str+=m_model->data(index,Qt::DisplayRole).toString();
ui->statusbar->showMessage(str);
}
有些可能不清楚的地方:
setdata里的role是什么?
看不懂?问一下gpt
在Qt中,
setData
方法是QAbstractItemModel
类中的一个虚函数,用于更新数据模型中项的值。该方法的签名如下:
bool QAbstractItemModel::setData(const QModelIndex &index, const QVariant &value, int role = Qt::EditRole);
其中,
role
参数指定了要设置的数据的角色。角色表示了项的不同方面或属性。在Qt中,有一些标准的角色,例如Qt::DisplayRole
用于显示文本,Qt::EditRole
用于编辑文本等。下面是一些常见的角色及其作用:
Qt::DisplayRole: 用于在视图中显示项的文本。
Qt::EditRole: 用于编辑项的文本。
Qt::ToolTipRole: 提供给视图项的工具提示文本。
Qt::DecorationRole: 用于显示项的图标或装饰。
Qt::UserRole: 为用户定义的角色提供一个基准值。
在
setData
中,role
参数允许您指定要更新的项的特定角色。这是因为一个项可能具有多个方面的数据,而这些方面可能需要在不同的上下文中使用。通过使用角色,可以更灵活地处理这些情况。
一般情况,把需要显示在界面上的内容的数据设置为DisplayRole
不过在我的测试里发现,QStringListModel里DisplayRole和EditRole是同步的,也就没法通过这个例子显示这两role的区别了
moveRow?
bool QAbstractItemModel::moveRow(const QModelIndex &sourceParent, int sourceRow, const QModelIndex &destinationParent, int destinationChild);
参数如下:
sourceParent
:源行的父索引。sourceRow
:源行的起始索引。destinationParent
:目标位置的父索引。destinationChild
:目标位置的子索引。
父索引在listmodel里没用,随便传一个就行
源代码
链接:https://pan.baidu.com/s/16aK1PGqEorRTNncBXFLSSw
提取码:oopp
源代码用的是Qt6.2,qmake,mingw,直接打开不一定能行