当前位置: 首页 > article >正文

Qt中的Model与View 3:从样例出发理解QStringListModel和QListView

目录

Ui文件设计如下:

初始化窗口

这里,就是一经典的例子

你可以看到,我们的环境变量是一个经典的List列表,其中承载的就是我们的字符串。我们现在来仿照着搞一个:

Ui文件设计如下:

我们下面来逐一演示用法。

初始化窗口

首先我们说,Qt的Model View编程必须有Model和对应的显示的View。这里,我们的View已经在Ui设计文件的左下角的ListView出现了,Model呢?则需要我们自己存储住:

#ifndef MAINWINDOW_H
#define MAINWINDOW_H
#include <QMainWindow>
#include <QStringListModel>
​
QT_BEGIN_NAMESPACE
namespace Ui {
class MainWindow;
}
QT_END_NAMESPACE
​
class MainWindow : public QMainWindow {
    Q_OBJECT
​
public:
    MainWindow(QWidget *parent = nullptr);
    ~MainWindow();
private:
    static constexpr const char *LISTS_DATA_ORG[] = {
        "Apple", "Banana", "你好", "Shenzhen", "我也不知道写啥了,乐!"};
​
    QStringList                       original_stringlist;
    std::unique_ptr<QStringListModel> model;
    Ui::MainWindow                   *ui;
};
#endif  // MAINWINDOW_H
​

可以看到我们使用了QStringListModel作为存储,当然unique_ptr是一个智能指针,笔者这里习惯使用了,您可以直接使用new分配内存,也行!

MainWindow::MainWindow(QWidget* parent)
    : QMainWindow(parent), ui(new Ui::MainWindow) {
    ui->setupUi(this);
​
    // 初始化StringList列表
    for (const auto& each : MainWindow::LISTS_DATA_ORG)
        original_stringlist << each;
​
    // 初始化一下我们的model
    model = std::make_unique<QStringListModel>(this);
​
    model->setStringList(original_stringlist);
​
    ui->listView->setModel(model.get());
    ::setIfEnableEdit(ui->listView, true);
}

我们的Model的来源就是使用setStringList这接口来设置数据的。之后我们使用其他的例子也是一样,寻找这个Model的设置接口的函数。

不要忘记,我们的Model初始化完成数据之后要交给View显示里面的数据,这里,所有的View都存在接口setModel,请不要忘记调用!

最后的setIfEnableEdit是笔者自己封装的函数,结合上一篇博客所学,我们轻而易举的能写出:

static void setIfEnableEdit(QListView* view, bool is_editable) {
    is_editable ? view->setEditTriggers(
                      QAbstractItemView::DoubleClicked |
                      QAbstractItemView::SelectedClicked) /* is editable */
                : view->setEditTriggers(
                      QAbstractItemView::NoEditTriggers); /* is not  editable*/
}

当然,static表达的是文件内部调用不暴露使用,当我们想要使用编辑功能的时候,需要设置view是:QAbstractItemView::DoubleClicked |QAbstractItemView::SelectedClicked(表达的是双击 或者是 点中项再点击选择的意思)。禁用编辑就是不分配触发点击的flag!

void MainWindow::on_btnResumeList_clicked() {
    model->setStringList(original_stringlist);
}
​
void MainWindow::on_btnListClear_clicked() {
    model->setStringList({});
    // model->removeRows(0,m_model->rowCount())
}
​
void MainWindow::on_chkEditable_clicked(bool checked) {
    ::setIfEnableEdit(ui->listView, checked);
}

这三个接口:回复列表,清空列表和允许编辑很好理解,这里不展开

void MainWindow::on_btnListAppend_clicked() {
    model->insertRow(model->rowCount());
    auto modelIndex = model->index(model->rowCount() - 1);
    model->setData(modelIndex, "键入新值");
    ui->listView->setCurrentIndex(modelIndex);
}
​
void MainWindow::on_btnListInsert_clicked() {
    auto indexRow = ui->listView->currentIndex().row();
    if (indexRow == -1) {
        // 用户没选中, 可以做尾插,也可以提示(这个最好!)
        return on_btnListAppend_clicked();
    }
    model->insertRow(indexRow);
    auto modelIndex = model->index(indexRow);
    model->setData(modelIndex, "键入插入的新值!");
    ui->listView->setCurrentIndex(modelIndex);
}
​
void MainWindow::on_btnListDelete_clicked() {
    auto indexRow = ui->listView->currentIndex().row();
    // 当然最合适的还是做用户处理!
    if (indexRow == -1) return;
​
    model->removeRow(indexRow);
}

上面插入的和删除的我说一嘴:我们拿到modelIndex是一个索引不是数据本身,数据还是在背后存储的model里。所以我们需要绕个弯取model项!

void MainWindow::on_btnListMoveUp_clicked() {
    auto indexRow = ui->listView->currentIndex().row();
    auto index    = QModelIndex();  // ListModel没有父节点
    if (indexRow == -1) return;
​
    model->moveRow(index, indexRow, index, indexRow - 1);
}
​
void MainWindow::on_btnListMoveDown_clicked() {
    auto indexRow = ui->listView->currentIndex().row();
    auto index    = QModelIndex();  // ListModel没有父节点
    if (indexRow == -1) return;
​
    model->moveRow(index, indexRow, index, indexRow + 2);
}

上下移动使用moveRow函数,注意参数名称就告诉你第一个和第三个参数是modelIndex父节点,所以,对于ListView没有父节点的view是传ModelIndex()的默认构造。

void MainWindow::on_btnListSort_clicked() {
    model->sort(0);
}

sort是对内容的排序,默认是升序,你可以设置第二个参数!

void MainWindow::on_listView_clicked(const QModelIndex& index) {
    const QString gain_printed_string = QString::asprintf(
        "row: %d, column: %d, data:", index.row(), index.column());
    const QString gain_data = ui->listView->currentIndex().data().toString();
    statusBar()->showMessage(gain_printed_string + gain_data);
}
​
​

上面是点击了ListView的项做出的反应,可以一览!

最后是两个显示:

void MainWindow::on_btn_clear_data_clicked() {
    ui->textEdit->clear();
}
​
void MainWindow::on_btn_fetch_data_clicked() {
    const QStringList display = model->stringList();
    for (const auto& each : display) {
        ui->textEdit->append(each);
    }
}

http://www.kler.cn/a/378735.html

相关文章:

  • selinux和防火墙
  • 相机硬触发
  • thrift rpc 四种类型的服务端的实现详细介绍
  • Python毕业设计选题:基于Hadoop的租房数据分析系统的设计与实现
  • 2024版红娘金媒10.3婚恋相亲系统源码小程序(亲测)
  • 高级SQL技巧详解与实例
  • 【mod分享】极品飞车9仿虚幻引擎模组,支持光追,高清纹理材质,体验一会虚幻引擎风格的极品9
  • 【前端项目工程】Uni-app 离线打包apk
  • masm汇编字符输入换行输出演示
  • 【论文笔记】Dense Connector for MLLMs
  • keepalived + nginx 实现网站高可用性(HA)
  • 你需要了解的Android主题相关知识
  • myqld二进制安装和破解数据库密码(linux)
  • 掌控板micropython编程实现OLED显示天气信息
  • YOLOv8分析与改进-专栏介绍
  • 模型监控--深入了解python中包装器和hook等区别
  • SpringMVC学习中遇到编码问题(过滤器)
  • 【深度学习】PromptFix:多功能AI修图
  • vue2.0版本引入Element-ui问题解决
  • 11.3笔记
  • 基于MATLAB的加噪语音信号的滤波
  • [数据结构]插入排序(全)
  • 宁德时代嵌入式面试题及参考答案(万字长文)
  • Linux驱动开发(3):字符设备驱动
  • Linux系统性能调优
  • 《Java 实现冒泡排序:详细解析与示例代码》