1、 Qt Model/View(模型/视图)结构
Model/View(模型/视图)结构是 Qt 中用界面组件显示与编辑数据的一种结构,视图(View)是显示和编辑数据的界面组件,模型(Model)是视图与原始数据之间的接口。
-
数据(Data)是实际的数据,如数据库的一个数据表或SQL查询结果,内存中的一个 StringList,或磁盘文件结构等。
-
视图或视图组件(View)是屏幕上的界面组件,视图从数据模型获得每个数据项的模型索引(model index),通过模型索引获取数据,然后为界面组件提供显示数据。Qt 提供一些现成的数据视图组件,如 QListView、QTreeView 和 QTableView 等。
-
模型或数据模型(Model)与实际数据通信,并为视图组件提供数据接口。它从原始数据提取需要的内容,用于视图组件进行显示和编辑。Qt 中有一些预定义的数据模型,如 QStringListModel 可作为 StringList 的数据模型,QSqlTableModel 可以作为数据库中一个数据表的数据模型。
-
在 Model/View 结构中,还提供了代理(Delegate)功能,代理功能可以让用户定制数据的界面显示和编辑方式。在标准的视图组件中,代理功能显示一个数据,当数据被编辑时,代理通过模型索引与数据模型通信,并为编辑数据提供一个编辑器,一般是一个 QLineEdit 组件。
-
模型、视图和代理之间使用信号和槽通信。当源数据发生变化时,数据模型发射信号通知视图组件;当用户在界面上操作数据时,视图组件发射信号表示这些操作信息;当编辑数据时,代理发射信号告知数据模型和视图组件编辑器的状态。
2、QListView 和 QListWidget
QListView是QListWidget的基类,QListView只用于显示,基于模型的,数据和控件是独立的
QListWidget是QListView的派生类,更好用,里面可以放普通QT的预定义控件,也可以放自定义控件
2.1 QListView
(0)在窗口类中定义模型和数据容器
QStringListModel *model;
QStringList *slist;
(1)先设置模型, 为列表视图设置模型
ui->listView->setModel(model);
(2)更新模型里面的数据,就可以直接表现在listWiew中
(*slist)<<"hello world";
model->setStringList(*slist);//更新模型里面的数据
(3)移除某条数据
QModelIndex i = ui->listView->currentIndex();
slist.removeAt(i.row());
model->setStringList(slist);
2.2 QListWidget
(1)添加一个label
ui->listWidget->addItem("hello world");
(2)添加一个label控件
QListWidgetItem *item = new QListWidgetItem(QIcon(":/icon/logo.ico"), "hello world");
ui->listWidget->addItem(item);
(3)添加一个按钮控件
//创建一个按钮
QPushButton *btn = new QPushButton("按钮"); //创建一个项
QListWidgetItem *item = new QListWidgetItem; //将这个项添加到listWidget里面
ui->listWidget->addItem(item); //将列表中的item控件设置为按钮
ui->listWidget->setItemWidget(item, btn);
(4)添加一个自定义控件
//创建一个自定义控件
MyWidget *myw = new MyWidget(this, ":/icon/logo.ico", "tom", "no pain no gains"); QListWidgetItem *item = new QListWidgetItem; //设置item的尺寸与MyWidget控件大小一致
item->setSizeHint(myw->size());
ui->listWidget->addItem(item);
ui->listWidget->setItemWidget(item, myw);
(5)移除一项
QListWidgetItem *item = ui->listWidget->takeItem(ui->listWidget->currentRow());
delete item;
(6)全部移除
int count = ui->listWidget->count();
for(int i=0; i<count; i++)
{
QListWidgetItem *item = ui->listWidget->takeItem(0);
delete item;
}
(7)双击处理
void MainWindow::on_listWidget_itemDoubleClicked(QListWidgetItem *item)
{
//得到双击事件点中的是哪一个自定义控件mw,从而获取相关的信息
MyWidget *mw = dynamic_cast<MyWidget *>(ui->listWidget->itemWidget(item));
qDebug()<<"name:"<<mw->get_name();
ChatDialog *c = new ChatDialog(mw->get_name());
c->show();
}
2.3 控件右键菜单
(1)在头文件中声明Action和Menu
#include <QMenu>
#include <QAction>
//声明动作
QAction *act1;
QAction *act2;
QAction *act3;
//声明菜单
QMenu *menu;
(2)定义动作
//定义动作
act1 = new QAction("查看好友资料");
act2 = new QAction("删除好友");
act3 = new QAction("举报");
//关联三个动作的槽函数
// connect(act1, &QAction::triggered, this, f1);
// connect(act2, &QAction::triggered, this, f2);
// connect(act3, &QAction::triggered, this, f3);
(3)初始化菜单
//初始化菜单、将动作添加到菜单
menu = new QMenu(this);
menu->addAction(act1);
menu->addAction(act2);
menu->addAction(act3);
(4)给指定控件右键信号创建槽函数,显示菜单
//给控件添加菜单策略
ui->listWidget->setContextMenuPolicy(Qt::CustomContextMenu);
//给指定控件右键信号创建槽函数,显示菜单
connect(ui->listWidget, &QListWidget::customContextMenuRequested, this, &MainWindow::open_menu);
//显示菜单
void MainWindow::open_menu(const QPoint &pos)
{
qDebug()<<"位置:"<<pos;
menu->exec(QCursor::pos());
}