【嵌入式——QT】Model/View

【嵌入式——QT】Model/View

  • 基本原理
  • 数据模型
  • 视图组件
  • 代理
  • Model/View结构的一些概念
  • QFileSystemModel
  • QStringListModel
  • QStandardItemModel
  • 自定义代理

基本原理

GUI应用程序的一个很重要的功能是由用户在界面上编辑和修改数据,典型的如数据库应用程序,数据库应用程序中,用户在界面上执行各种操作,实际上是修改了界面组件所关联的数据库内的数据。将界面组件与所编辑的数据分离开来,又通过数据源的方式连接起来,是处理界面与数据的一种较好的方式,Qt使用Model/View结构来处理这种关系。

数据模型

QAbstractItemModel

  • QAbstractListModel:QStringListModel,处理字符串列表数据的数据模型类;
  • QAbstractProxyModel:QSortFilterProxyModel,提供排序和过滤功能的数据模型类;
  • QAbstractTableModel:QSqlQueryModel,数据库SQL查询结构的数据模型类;QSqlTableModel,用于数据库的一个数据表的数据模型类;QSqlRelationalTableModel,关系型数据表的数据模型类;
  • QStandardItemModel:每个项数据可以使任何数据类型;
  • QFileSystemModel:文件系统的数据模型类;

视图组件

  • QListView:用于显示单列的列表数据,适用于一维数据的操作;
  • QTreeView:用于显示树状结构数据,适用于树状结构数据的操作;
  • QTableView:用于显示表格状数据,适用于二维表格型数据的操作;
  • QColumnView:用多个QListView显示树状层次结构,树状结构的一层用一个QListView显示;
  • QHeaderView:提供行表头或列表头的视图组件,如QTableView的行表头和列表头;

代理

代理(Delegate)就是在视图组件上为编辑数据提供编辑器,如在表格组件中编辑一个单元格的数据时,缺省是使用一个QLineEdit编辑框。
代理负责从数据模型获取相应的数据,然后显示在编辑器里,修改数据后,又将其保存到数据模型中。
QAbstractItemDelegate是所有代理类的基类,它不能直接使用,它的一个子类QStyledItemDelegate,是Qt的视图组件缺省使用的代理类。

Model/View结构的一些概念

基本结构
数据模型中的存储数据的基本单元都是项(item),每个项都有一个行号,一个列号,还有一个父项。
模型索引
QModelIndex表示模型索引的类,模型索引提供数据存取的一个临时指针,用于通过数据模型提取或修改数据,因为模型内部数据的结构随时可能改变,所以模型索引是临时的。
行号和列号
数据模型的基本形式是用行和列定义的表格数据,要获得一个模型索引,必须提供行号、列号、父项的模型索引。
父项
当数据模型是列表或表格时,使用行号、列号存储数据比较直观,所有数据项的父项就是顶层项,当数据模型是树状结构时,情况比较复杂,一个节点可以有父节点,也可以是其他节点的父节点,在构造数据项的模型索引时,必须指定正确的行号、列号和父节点。
项的角色
在为数据模式的一个项设置数据时,可以赋予其不同项的角色的数据。
enum ItemDataRole

  • Qt::DisplayRole:在视图组件中显示字符串,标准角色;
  • Qt::ToolTipRole:鼠标提示消息;
  • Qt::UserRole:可以自定义数据;

QFileSystemModel

QFileSystemModel提供了一个可用于访问本机文件系统的数据模型,QFileSystemModel和视图组件QTreeView结合使用,可以用目录树的形式显示本机上的文件系统,如同Windows的资源管理器一样,使用QFileSystemModel提供的接口函数,可以创建目录,删除目录,重命名目录,可以获得文件名称、目录名称、文件大小等参数,还可以获得文件的详细信息。
图示
在这里插入图片描述

代码示例
ModelViewDialog.h

#ifndef MODELVIEWDIALOG_H
#define MODELVIEWDIALOG_H

#include <QDialog>
#include <QFileSystemModel>

namespace Ui
{
    class ModelViewDialog;
}

class ModelViewDialog : public QDialog
{
    Q_OBJECT

public:
    explicit ModelViewDialog(QWidget* parent = nullptr);
    ~ModelViewDialog();
private slots:
    void on_treeView_clicked(const QModelIndex& index);

private:
    Ui::ModelViewDialog* ui;

    QFileSystemModel* model;
};

#endif // MODELVIEWDIALOG_H

ModelViewDialog.cpp

#include "ModelViewDialog.h"
#include "ui_ModelViewDialog.h"
ModelViewDialog::ModelViewDialog(QWidget* parent)
    : QDialog(parent)
    , ui(new Ui::ModelViewDialog)
{
    ui->setupUi(this);
    model = new QFileSystemModel(this);
    //QDir::currentPath() 获得本机文件系统
    model->setRootPath(QDir::currentPath());//设置根目录
    ui->treeView->setModel(model);//设置数据模型
    ui->listView->setModel(model);//设置数据模型
    ui->tableView->setModel(model);//设置数据模型
    connect(ui->treeView, SIGNAL(clicked(QModelIndex)), ui->listView, SLOT(setRootIndex(QModelIndex)));
    connect(ui->treeView, SIGNAL(clicked(QModelIndex)), ui->tableView, SLOT(setRootIndex(QModelIndex)));
}

ModelViewDialog::~ModelViewDialog()
{
    delete ui;
}


void ModelViewDialog::on_treeView_clicked(const QModelIndex& index)
{
    ui->checkBox->setChecked(model->isDir(index));//是否目录
    ui->labPath->setText(model->filePath(index));//返回节点的目录名或带路径的文件名
    ui->labType->setText(model->type(index));//返回描述节点类型的文字
    ui->labFileName->setText(model->fileName(index));//返回去除路径的文件夹名称或文件名
    int sz = model->size(index)/1024;//如果节点是文件,返回文件大小的字节数,如果节点是文件夹,返回0
    if(sz<1024) {
        ui->labSize->setText(QString("%1 KB").arg(sz));
    } else {
        ui->labSize->setText(QString::asprintf("%.1f MB", sz/1024.0));
    }
}


QStringListModel

QStringListModel用于处理字符串列表的数据模型,它可以作为QListView的数据模型,在界面上显示和编辑字符串列表。

图示
在这里插入图片描述

代码示例

QStringListModelDialog.h

#ifndef QSTRINGLISTMODELDIALOG_H
#define QSTRINGLISTMODELDIALOG_H

#include <QDialog>
#include <QStringListModel>

namespace Ui
{
    class QStringListModelDialog;
}

class QStringListModelDialog : public QDialog
{
    Q_OBJECT

public:
    explicit QStringListModelDialog(QWidget* parent = nullptr);
    ~QStringListModelDialog();

private slots:
    void on_pushButtonAdd_clicked();

    void on_pushButtonInsert_clicked();

    void on_pushButtonRemove_clicked();

    void on_pushButtonClear_clicked();

    void on_pushButtonShow_clicked();

    void on_listView_clicked(const QModelIndex& index);

    void on_pushButtonReset_clicked();

    void on_pushButtonClearText_clicked();

private:
    Ui::QStringListModelDialog* ui;

    QStringListModel* model;
};

#endif // QSTRINGLISTMODELDIALOG_H

QStringListModelDialog.cpp

#include "QStringListModelDialog.h"
#include "ui_QStringListModelDialog.h"
QStringListModelDialog::QStringListModelDialog(QWidget* parent)
    : QDialog(parent)
    , ui(new Ui::QStringListModelDialog)
{
    ui->setupUi(this);
    QStringList theStrList;
    theStrList<<"北京"<<"上海"<<"天津"<<"河北"<<"河南"<<"山东";
    model = new QStringListModel(this);
    //将一个字符串列表的内容作为数据模型的初始化数据内容
    model->setStringList(theStrList);
    ui->listView->setModel(model);
    //双击 或 选择并单击后进入编辑状态
    ui->listView->setEditTriggers(QAbstractItemView::DoubleClicked | QAbstractItemView::SelectedClicked);
}

QStringListModelDialog::~QStringListModelDialog()
{
    delete ui;
}

void QStringListModelDialog::on_pushButtonAdd_clicked()
{
    model->insertRow(model->rowCount());//在尾部插入一行
    QModelIndex index = model->index(model->rowCount()-1, 0);
    model->setData(index, "new item", Qt::DisplayRole);
    ui->listView->setCurrentIndex(index);//设置当前选中的行
}


void QStringListModelDialog::on_pushButtonInsert_clicked()
{
    QModelIndex index = ui->listView->currentIndex();
    model->insertRow(index.row());
    model->setData(index, "inserted item", Qt::DisplayRole);
    ui->listView->setCurrentIndex(index);
}


void QStringListModelDialog::on_pushButtonRemove_clicked()
{
    QModelIndex index = ui->listView->currentIndex();
    model->removeRow(index.row());
}


void QStringListModelDialog::on_pushButtonClear_clicked()
{
    model->removeRows(0, model->rowCount());
}


void QStringListModelDialog::on_pushButtonShow_clicked()
{
    QStringList tmpList = model->stringList();
    ui->plainTextEdit->clear();
    for(int i=0; i<tmpList.count(); i++) {
        ui->plainTextEdit->appendPlainText(tmpList.at(i));
    }
}


void QStringListModelDialog::on_listView_clicked(const QModelIndex& index)
{
    ui->label->setText(QString::asprintf("current:row=%d,column=%d", index.row(), index.column()));
}


void QStringListModelDialog::on_pushButtonReset_clicked()
{
    model->removeRows(0, model->rowCount());
    QStringList theStrList;
    theStrList<<"北京"<<"上海"<<"天津"<<"河北"<<"河南"<<"山东";
    model->setStringList(theStrList);
}


void QStringListModelDialog::on_pushButtonClearText_clicked()
{
    ui->plainTextEdit->clear();
}

QStandardItemModel

QStandardItemModel是标准的以项数据为基础的标准数据模型类,通常与QTableView组合成Model/View结构。实现通用的二维数据的管理功能。

图示
在这里插入图片描述

代码示例
QStandardItemModelDialog.h

#ifndef QSTANDARDITEMMODELDIALOG_H
#define QSTANDARDITEMMODELDIALOG_H

#include <QDialog>
#include <QLabel>

#include <QStandardItemModel>
#include <QItemSelectionModel>
#define FixedColumnCount 6
namespace Ui
{
    class QStandardItemModelDialog;
}

class QStandardItemModelDialog : public QDialog
{
    Q_OBJECT

public:
    explicit QStandardItemModelDialog(QWidget* parent = nullptr);
    ~QStandardItemModelDialog();

    void initModelFromStringList(QStringList& fFileContent);

public slots:
    void on_currentChanged(const QModelIndex& current, const QModelIndex& previous);


private slots:
    void on_pushButtonOpen_clicked();

    void on_pushButtonAdd_clicked();

    void on_pushButtonInsert_clicked();

    void on_pushButtonRemove_clicked();

    void on_pushButtonLeft_clicked();

    void on_pushButtonMid_clicked();

    void on_pushButtonRight_clicked();

    void on_pushButtonBold_clicked();

    void on_pushButtonSaveAs_clicked();

private:
    Ui::QStandardItemModelDialog* ui;
    QStandardItemModel* model;
    QLabel* labCurFile;
    QLabel* labCellPos;
    QLabel* labCellText;
    QItemSelectionModel* theSelection;


};

#endif // QSTANDARDITEMMODELDIALOG_H

QStandardItemModelDialog.cpp

#include "QStandardItemModelDialog.h"
#include "ui_QStandardItemModelDialog.h"
#include <QAbstractItemView>
#include <QFileDialog>
#include <QTextStream>

QStandardItemModelDialog::QStandardItemModelDialog(QWidget* parent)
    : QDialog(parent)
    , ui(new Ui::QStandardItemModelDialog)
{
    ui->setupUi(this);
    model = new QStandardItemModel(0, FixedColumnCount, this);
    theSelection = new QItemSelectionModel(model);
    connect(theSelection, SIGNAL(currentChanged(QModelIndex, QModelIndex)), this, SLOT(on_currentChanged(QModelIndex, QModelIndex)));
    ui->tableView->setModel(model);
    ui->tableView->setSelectionModel(theSelection);
    ui->tableView->setSelectionMode(QAbstractItemView::ExtendedSelection);
    ui->tableView->setSelectionBehavior(QAbstractItemView::SelectItems);
}

QStandardItemModelDialog::~QStandardItemModelDialog()
{
    delete ui;
}

void QStandardItemModelDialog::initModelFromStringList(QStringList& fFileContent)
{
    int rowCnt = fFileContent.count();
    model->setRowCount(rowCnt);
    QString header = fFileContent.at(0);
    //用一个或多个空白字符分隔  SkipEmptyParts函数会跳过任何空的部分
    QStringList headerList = header.split(QRegExp("\\s+"), QString::SkipEmptyParts);
    model->setHorizontalHeaderLabels(headerList);
    QStandardItem* item;
    QStringList tmpList;
    int j;
    for(int i=1; i<rowCnt; i++) {
        QString aLinText = fFileContent.at(i);
        tmpList = aLinText.split(QRegExp("\\s+"), QString::SkipEmptyParts);
        for(j=0; j<FixedColumnCount-1; j++) {
            item = new QStandardItem(tmpList.at(j));
            model->setItem(i-1, j, item);
        }
        item = new QStandardItem(headerList.at(j));
        item->setCheckable(true);
        if(tmpList.at(j) == "0") {
            item->setCheckState(Qt::Unchecked);
        } else {
            item->setCheckState(Qt::Checked);
        }
        model->setItem(i-1, j, item);
    }
}

void QStandardItemModelDialog::on_currentChanged(const QModelIndex& current, const QModelIndex& previous)
{
    if(current.isValid()) {
        // labCellPos->setText(QString::asprintf("current: row=%d , col=%d", current.row(), current.column()));
        QStandardItem* item = model->itemFromIndex(current);
        // this->labCellText->setText("text:"+item->text());
        // QFont font = item->font();
    }
}

void QStandardItemModelDialog::on_pushButtonOpen_clicked()
{
    QString curPath = QCoreApplication::applicationDirPath();
    QString aFileName = QFileDialog::getOpenFileName(this, u8"打开文件", curPath);
    if(aFileName.isEmpty()) {
        return;
    }
    QStringList fFileContent;
    QFile afile(aFileName);
    if(afile.open(QIODevice::ReadOnly |QIODevice::Text)) {
        QTextStream aStream(&afile);
        ui->plainTextEdit->clear();
        while(!aStream.atEnd()) {
            QString str = aStream.readLine();
            ui->plainTextEdit->appendPlainText(str);
            fFileContent.append(str);
        }
        afile.close();
        // labCurFile->setText("currentFile:"+aFileName);
        initModelFromStringList(fFileContent);
    }
}


void QStandardItemModelDialog::on_pushButtonAdd_clicked()
{
    QList<QStandardItem*> itemList;
    QStandardItem* item;
    //不包含最后一列
    for(int i=0; i<FixedColumnCount-1; i++) {
        item = new QStandardItem("0");
        // item->setCheckable(true);
        itemList<<item;
    }
    QString str = model->headerData(model->columnCount()-1, Qt::Horizontal, Qt::DisplayRole).toString();
    item = new QStandardItem(str);
    item->setCheckable(true);
    itemList<<item;
    model->insertRow(model->rowCount(), itemList);
    QModelIndex curIndex = model->index(model->rowCount()-1, 0);
    theSelection->clearSelection();
    theSelection->setCurrentIndex(curIndex, QItemSelectionModel::Select);
}


void QStandardItemModelDialog::on_pushButtonInsert_clicked()
{
    QList<QStandardItem*> itemList;
    QStandardItem* item;
    //不包含最后一列
    for(int i=0; i<FixedColumnCount-1; i++) {
        item = new QStandardItem("0");
        // item->setCheckable(true);
        itemList<<item;
    }
    QString str = model->headerData(model->columnCount()-1, Qt::Horizontal, Qt::DisplayRole).toString();
    item = new QStandardItem(str);
    item->setCheckable(true);
    itemList<<item;
    QModelIndex curIndex = theSelection->currentIndex();
    int curRow = curIndex.row();
    model->insertRow(curRow, itemList);
    curIndex = model->index(curRow, 0);
    theSelection->clearSelection();
    theSelection->setCurrentIndex(curIndex, QItemSelectionModel::Select);
}


void QStandardItemModelDialog::on_pushButtonRemove_clicked()
{
    QModelIndex curIndex = theSelection->currentIndex();
    if(curIndex.row() == model->rowCount()-1) {
        model->removeRow(curIndex.row());
    } else {
        model->removeRow(curIndex.row());
        theSelection->setCurrentIndex(curIndex, QItemSelectionModel::Select);
    }
}


void QStandardItemModelDialog::on_pushButtonLeft_clicked()
{
    if(!theSelection->hasSelection()) {
        return;
    }
    QModelIndexList selectedIndex = theSelection->selectedIndexes();
    for(int i=0; i<selectedIndex.count(); i++) {
        QModelIndex aIndex = selectedIndex.at(i);
        QStandardItem* item = model->itemFromIndex(aIndex);
        item->setTextAlignment(Qt::AlignLeft);
    }
}


void QStandardItemModelDialog::on_pushButtonMid_clicked()
{
    if(!theSelection->hasSelection()) {
        return;
    }
    QModelIndexList selectedIndex = theSelection->selectedIndexes();
    for(int i=0; i<selectedIndex.count(); i++) {
        QModelIndex aIndex = selectedIndex.at(i);
        QStandardItem* item = model->itemFromIndex(aIndex);
        item->setTextAlignment(Qt::AlignCenter);
    }
}


void QStandardItemModelDialog::on_pushButtonRight_clicked()
{
    if(!theSelection->hasSelection()) {
        return;
    }
    QModelIndexList selectedIndex = theSelection->selectedIndexes();
    for(int i=0; i<selectedIndex.count(); i++) {
        QModelIndex aIndex = selectedIndex.at(i);
        QStandardItem* item = model->itemFromIndex(aIndex);
        item->setTextAlignment(Qt::AlignRight);
    }
}


void QStandardItemModelDialog::on_pushButtonBold_clicked()
{
    if(!theSelection->hasSelection()) {
        return;
    }
    QModelIndexList selectedIndex = theSelection->selectedIndexes();
    for(int i=0; i<selectedIndex.count(); i++) {
        QModelIndex aIndex = selectedIndex.at(i);
        QStandardItem* item = model->itemFromIndex(aIndex);
        QFont font = item->font();
        font.setBold(Qt::Checked);
        item->setFont(font);
    }
}


void QStandardItemModelDialog::on_pushButtonSaveAs_clicked()
{
    QString curPath = QCoreApplication::applicationDirPath();
    QString aFileName = QFileDialog::getSaveFileName(this, u8"选择一个文件", curPath);
    if(aFileName.isEmpty()) {
        return;
    }
    QFile file(aFileName);
    if(!(file.open(QIODevice::ReadWrite | QIODevice::Text| QIODevice::Truncate))) {
        return;
    }
    QTextStream aStream(&file);
    QStandardItem* item;
    int i, j;
    QString str;
    ui->plainTextEdit->clear();
    for(int i=0; i<model->columnCount(); i++) {
        item = model->horizontalHeaderItem(i);
        str = str +item->text()+"\t\t";
    }
    aStream<<str<<"\n";
    ui->plainTextEdit->appendPlainText(str);
    for(i=0; i<model->rowCount(); i++) {
        str="";
        for(j=0; j<model->columnCount()-1; j++) {
            item = model->item(i, j);
            str=str+item->text()+QString::asprintf("\t\t");
        }
        item = model->item(i, j);
        if(item->checkState() == Qt::Checked) {
            str = str+"1";
        } else {
            str = str+"0";
        }
        ui->plainTextEdit->appendPlainText(str);
        aStream<<str<<"\n";
    }
}


自定义代理

QAbstractItemDelegate是所有代理类的抽象基类,QStyledItemDelegate是视图组件使用的缺省的代理类,QItemDelegate也是类似功能的类。
QStyledItemDelegate和QItemDelegate的差别在于前者可以使用样式表设置来绘制组件,因此建议使用QStyledItemDelegate作为自定义代理类组件的基类。
无论从QStyledItemDelegate还是QItemDelegate继承设计自定义代理组件,都会必须实现这四个函数。

  1. createEditor:创建用于编辑模型数据的widget组件,如QSpinBox组件;
  2. setEditorData:从数据模型获取数据,供widget组件进行编辑;
  3. setModelData:将widget上的数据更新到数据模型;
  4. updateEditorGeometry:用于给widget组件设置一个合适的大小;

详见我之前一段时间所写的文章 文章地址

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/438500.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

wsl 安装 ubuntu

文章目录 打开Windows PowerShell查看可安装的ubuntu安装相对应的ubuntu将用户添加到sudoers文件中&#xff0c;并赋予了该用户sudo权限。 打开Windows PowerShell 以管理员的身份运行 查看可安装的ubuntu wsl.exe --list --online安装相对应的ubuntu wsl --install 版本…

计算机网络面经-HTTPS加密过程

前言 在上篇文章HTTPS详解一中&#xff0c;我已经为大家介绍了 HTTPS 的详细原理和通信流程&#xff0c;但总感觉少了点什么&#xff0c;应该是少了对安全层的针对性介绍&#xff0c;那么这篇文章就算是对HTTPS 详解一的补充吧。还记得这张图吧。 HTTPS 和 HTTP的区别 显然&am…

安装zabbix

部署Zabbix监控平台 部署一台Zabbix监控服务器&#xff0c;一台被监控主机&#xff0c;为进一步执行具体的监控任务做准备&#xff1a; 安装LNMP环境源码安装Zabbix安装监控端主机&#xff0c;修改基本配置初始化Zabbix监控Web页面修改PHP配置文件&#xff0c;满足Zabbix需求…

2024 GoLand激活,分享几个GoLand激活的方案

文章目录 GoLand公司简介我这边使用GoLand的理由GoLand 最新变化GoLand 2023.3 最新变化AI Assistant 正式版GoLand 中的 AI Assistant&#xff1a;_Rename_&#xff08;重命名&#xff09;GoLand 中的 AI Assistant&#xff1a;_Write documentation_&#xff08;编写文档&…

VScode+Zotero+Latex文献引用联动

一、VScodeLatex联动 1、VScode的安装 2、texlive.iso安装 可以参考以下&#xff0c;也可以忽略所有直接一步一步默认安装 https://zhuanlan.zhihu.com/p/442308176 3、Vscode的插件安装&#xff1a;【latex workshop】 4、打开设置&#xff0c;搜索json&#xff0c;然后点击…

最新基于R语言lavaan结构方程模型(SEM)技术应用

结构方程模型&#xff08;Sructural Equation Modeling&#xff0c;SEM&#xff09;是分析系统内变量间的相互关系的利器&#xff0c;可通过图形化方式清晰展示系统中多变量因果关系网&#xff0c;具有强大的数据分析功能和广泛的适用性&#xff0c;是近年来生态、进化、环境、…

JVM运行时数据区——对象的实例化内存布局与访问定位

文章目录 1、对象的实例化1.1、创建对象的方式1.2、创建对象的步骤 2、对象的内存布局3、对象的访问定位3.1、对象访问的定位方式3.2、使用句柄访问3.3、使用指针访问 4、小结 平时大家经常使用new关键字来创建对象&#xff0c;那么我们创建对象的时候&#xff0c;怎么去和运行…

css 用flex做成田字型

哈喽&#xff0c;各位小伙伴&#xff01;今天给大家来css控制div完成田字型样式&#xff0c;来&#xff0c;看看下面的效果图&#xff1a; 一看就知道你们想要代码了&#xff0c;不急。代码&#xff1a; <!DOCTYPE html> <html lang"en"> <head>&…

Qt/C++音视频开发68-检查是否含有B帧/转码推流/拉流显示/监控拉流推流/海康大华宇视监控

一、前言 为什么需要判断视频文件是否含有B帧&#xff0c;这个在推流的时候很容易遇到这个问题&#xff0c;一般来说&#xff0c;没有B帧的视频文件&#xff0c;解码后的数据帧pts和dts都是顺序递增的&#xff0c;而有B帧的则未必&#xff0c;可能有些需要先解码后面显示&…

uniapp+node.js前后端做帖子模块:发布帖子评论(社区管理平台的小程序)

目录 0前提1.一些准备1.1表帖子表 post帖子评论表 postComment 1.2总体思路 2.前端3.后端4.验证结果 &#x1f44d; 点赞&#xff0c;你的认可是我创作的动力&#xff01; ⭐️ 收藏&#xff0c;你的青睐是我努力的方向&#xff01; ✏️ 评论&#xff0c;你的意见是我进步的…

CVPR 2022 Oral | Bailando: 基于编舞记忆和Actor-Critic GPT的3D舞蹈生成

目录 测试结果&#xff1a; 02 提出的方法 测试结果&#xff1a; 预测有3个步骤&#xff0c;速度比较慢 02 提出的方法 1. 针对舞蹈序列的VQ-VAE和编舞记忆 与之前的方法不同&#xff0c;我们不学习从音频特征到 3D 关键点序列的连续域的直接映射。相反&#xff0c;我们先让…

Springboot 的几种配置文件形式

方式一&#xff1a;多个yml文件 步骤1&#xff1a;创建多个配置文件 application.yml #主配置文件 application-dev.yml #开发环境的配置 application-prod.yml #生产环境的配置 application-test.yml #测试环境的配置步骤2&#xff1a;applicaiton.yml中指定配置 在a…

算法Day05_707.设计链表

推荐阅读 算法day01_ 27. 移除元素、977.有序数组的平方 算法day02_209.长度最小的子数组 算法day03_ 59.螺旋矩阵II 算法Day04_203.移除链表元素 目录 推荐阅读707.设计链表题目思路解法单链表解法双链表解法 707.设计链表 题目 你可以选择使用单链表或者双链表&#xff0c;设…

桶装水系统订水送水软件有哪些实用功能?

桶装水配送系统送水订水小程序预约水票开发定制桶装水管理软件特色; 1、订水软件界面简洁明了&#xff0c;操作简单易上手 2、桶装水管理软件正式版软件的功能全面&#xff0c;涉及到了桶装水后台管理的全部流程 3、财务报表可以自动计算出桶装水销售的详细数据 4、仓库管理、仓…

Android14音频进阶:AudioTrack与AudioFlinger创建数据通道(五十八)

简介: CSDN博客专家,专注Android/Linux系统,分享多mic语音方案、音视频、编解码等技术,与大家一起成长! 优质专栏:Audio工程师进阶系列【原创干货持续更新中……】🚀 优质专栏:多媒体系统工程师系列【原创干货持续更新中……】🚀 人生格言: 人生从来没有捷径,只…

代码训练LeetCode(3)移除元素

代码训练(3)LeetCode之移除元素 Author: Once Day Date: 2024年3月6日 漫漫长路&#xff0c;才刚刚开始… 全系列文章可参考专栏: 十年代码训练_Once-Day的博客-CSDN博客 参考文章: 27. 移除元素 - 力扣&#xff08;LeetCode&#xff09;力扣 (LeetCode) 全球极客挚爱的技…

Ubuntu 22.04桥接wifi上网,设置静态IP

记录一下整个过程 打开虚拟网络编辑器&#xff0c;配置桥接模式到主机无线网卡&#xff0c;如图 配置虚拟机网络适配器&#xff0c;设置为桥接模式&#xff0c;勾选“复制” 打开虚拟机&#xff0c;打开终端 cd /etc/netplan目录下有 .yaml 配置文件&#xff0c;用vim编辑器打…

《MySQL实战45讲》课程大纲

1MySQL实战45讲-01基础架构&#xff1a;一条SQL查询语句是如何执行的&#xff1f;2MySQL实战45讲-02日志系统&#xff1a;一条SQL更新语句是如何执行的&#xff1f;3MySQL实战45讲-03事务隔离&#xff1a;为什么你改了我还看不见&#xff1f;4MySQL实战45讲-04深入浅出索引&…

基于云效构建部署Springboot项目到ACK

介绍 为了提高项目迭代的速度加速交付产品给客户&#xff0c;我们通常会选择CICD工具来减少人力投入产生的成本&#xff0c;开源的工具比如有成熟的Jenkins&#xff0c;但是本文讲的是阿里云提高的解决方案云效平台&#xff0c;通过配置流水线的形式实现项目的快速部署到服务器…

React-Redux简单使用

1.配置环境 1.1开启项目 npx create-react-app react-redux-pro 1.2安装配套工具 说明&#xff1a;安装Redux Toolkit和react-redux。Redux Toolkit(RTK)~官方推荐编写Redux逻辑的方式&#xff0c;是一套工具的集合集&#xff0c;简化书写方式&#xff1b;react-redux-用来…