QTableView使用示例-Qt模型视图委托(MVD)(Model-View-Delegate)

         模型视图委托(MVD)是Qt中特有的设计模式,类似MVC设计模式,将MVC设计模式中的Controller当做MVD中的Delegate,两者的概念基本相同。不同的是委托不是独立存在,而是包含在视图里面。 模型视图委托设计模式中,模型负责存储和管理数据;视图负责显示数据,其中界面的框架和基础信息是视图负责,具体数据的显示是委托负责;委托不仅仅负责数据的显示,还有一个重要的功能是负责数据的编辑,如在视图中双击就可以编辑数据。

一、MVD简介

        QT当中model-view-delegate(模型-视图-代理),此结构实现数据和界面的分离。

        Qt的模型-视图结构分为三部分:模型(mode)-视图(view)-代理(Delegate) ,其中模型与数据源通信,并为其它部件提供接口;视图从模型中引用数据条的模型索引(Modellndex),在视图当中,代理负责绘制数据条目,比如编辑条目,代理和模型进行直接通信。

1、模型 (model): 实现自定义模型可以通过QAbstractltemModel类继承,也可以通过QAbstractListModel和QAbstractTableModel类继承实现列表模型或者表格模型
2、视图(view): 实现自定义的视图View,可以继承子QAbstractltemView类,对所需要的虚拟函数进行重定义。

3、代理 (delegate) :在表格当中嵌入各种不同的控件,通过表格中控件对编辑的内容进行操作。表格插入控件方式,控件始终显示。

二、简述

         本实例基于QT的委托代理机制实现的Qt模型视图代理(Model-View-Delegate)使用示例。以QTableView为基础,实现表头排序,列表复选框,插入按钮、下拉框、进度条。在Qt中,QTableView是一个用于显示表格数据的控件,可以使用Qt的模型视图代理(Model-View-Delegate)设计模式来定制QTableView的外观和行为。

三、效果 

四、核心代码  

student.h 学生信息

#ifndef STUDENT_H
#define STUDENT_H#include <QtCore>struct Student
{bool checked = false;quint16 id = 0;QString name;quint16 age = 0;QString gender = QObject::tr("男");quint16 achievement= 0;qint16 process = 50;
};Q_DECLARE_METATYPE(Student);//将自定义类型声明为元类型(MetaType),以便在信号与槽机制中通过传递
Q_DECLARE_METATYPE(Student*);#endif // STUDENT_H
1、下拉框委托类

comboboxdelegate.h

#ifndef COMBOBOXDELEGATE_H
#define COMBOBOXDELEGATE_H#include <QStyledItemDelegate>//下拉框委托类
class ComboBoxDelegate : public QStyledItemDelegate
{Q_OBJECT
public:explicit ComboBoxDelegate(QObject *parent = nullptr): QStyledItemDelegate(parent){}protected:QWidget *createEditor(QWidget *parent,const QStyleOptionViewItem &,const QModelIndex &) const Q_DECL_OVERRIDE;void setEditorData(QWidget *editor, const QModelIndex &index) const Q_DECL_OVERRIDE;void setModelData(QWidget *editor,QAbstractItemModel *model,const QModelIndex &index) const Q_DECL_OVERRIDE;
};#endif // COMBOBOXDELEGATE_H

 comboboxdelegate.cpp

#include "comboboxdelegate.h"
#include "student.h"#include <QtWidgets>QWidget *ComboBoxDelegate::createEditor(QWidget *parent,const QStyleOptionViewItem &,const QModelIndex &) const
{QComboBox *comboBox = new QComboBox(parent);comboBox->addItems(QStringList() << tr("男") << tr("女"));return comboBox;
}void ComboBoxDelegate::setEditorData(QWidget *editor, const QModelIndex &index) const
{QComboBox *comboBox = qobject_cast<QComboBox *>(editor);comboBox->setCurrentIndex(index.data(Qt::EditRole).toInt());
}void ComboBoxDelegate::setModelData(QWidget *editor,QAbstractItemModel *model,const QModelIndex &index) const
{QComboBox *comboBox = qobject_cast<QComboBox *>(editor);model->setData(index, comboBox->currentText(), Qt::EditRole);
}
2、按钮委托类

buttondelegate.h

#ifndef BUTTONDELEGATE_H
#define BUTTONDELEGATE_H#include <QStyledItemDelegate>//按钮委托类
class ButtonDelegate : public QStyledItemDelegate
{
public:ButtonDelegate(QObject* parent = nullptr);void paint(QPainter *painter,const QStyleOptionViewItem &option,const QModelIndex &index) const override;protected:bool editorEvent(QEvent *event, QAbstractItemModel *model,const QStyleOptionViewItem &option,const QModelIndex &index) override;private:QScopedPointer<QStyleOptionButton> m_buttonPtr;
};#endif // BUTTONDELEGATE_H

 buttondelegate.cpp

#include "buttondelegate.h"
#include "student.h"#include <QPainter>
#include <QApplication>
#include <QMouseEvent>
#include <QtWidgets>ButtonDelegate::ButtonDelegate(QObject *parent): QStyledItemDelegate(parent), m_buttonPtr(new QStyleOptionButton)
{}void ButtonDelegate::paint(QPainter *painter,const QStyleOptionViewItem &option,const QModelIndex &index) const
{int w = qMin(option.rect.width(), option.rect.height()) / 10.0;m_buttonPtr->rect = option.rect.adjusted(w, w, -w, -w);m_buttonPtr->text = index.model()->data(index).toString();m_buttonPtr->state |= QStyle::State_Enabled;painter->save();if (option.state & QStyle::State_Selected) {painter->fillRect(option.rect, option.palette.highlight());painter->setBrush(option.palette.highlightedText());}QPushButton button;qApp->style()->drawControl(QStyle::CE_PushButton, m_buttonPtr.data(), painter, &button);painter->restore();
}bool ButtonDelegate::editorEvent(QEvent *event,QAbstractItemModel *model,const QStyleOptionViewItem &option,const QModelIndex &index)
{int w = qMin(option.rect.width(), option.rect.height()) / 10.0;switch (event->type()) {case QEvent::MouseButtonPress:{QMouseEvent* mouseEvent =(QMouseEvent*)event;if (option.rect.adjusted(w, w, -w, -w).contains(mouseEvent->pos())) {m_buttonPtr->state |= QStyle::State_Sunken;}} break;case QEvent::MouseButtonRelease:{QMouseEvent* mouseEvent =(QMouseEvent*)event;if (option.rect.adjusted(w, w, -w, -w).contains(mouseEvent->pos())) {m_buttonPtr->state &= (~QStyle::State_Sunken);Student* stu = model->data(index, Qt::UserRole).value<Student*>();if(stu){QString details = tr("This Student id = %1, name = %2, age = %3, ""gender = %4, achievement = %5").arg(stu->id).arg(stu->name).arg(stu->age).arg(stu->gender).arg(stu->achievement);QDialog dialog;QHBoxLayout *layout = new QHBoxLayout(&dialog);layout->addWidget(new QLabel(details, &dialog));dialog.exec();}}}break;default: break;}return true;
}
3、 进度条委托类

progressbardelegate.h

#ifndef PROGRESSBARDELEGATE_H
#define PROGRESSBARDELEGATE_H#include <QStyledItemDelegate>//进度条委托类
class ProgressBarDelegate : public QStyledItemDelegate
{
public:ProgressBarDelegate(QObject* parent = nullptr) : QStyledItemDelegate(parent) {}void paint(QPainter *painter,const QStyleOptionViewItem &option,const QModelIndex &index) const;
};#endif // PROGRESSBARDELEGATE_H

 progressbardelegate.cpp

#include "progressbardelegate.h"#include <QPainter>
#include <QtWidgets>void ProgressBarDelegate::paint(QPainter *painter,const QStyleOptionViewItem &option,const QModelIndex &index) const
{QStyleOptionViewItem viewOption(option);initStyleOption(&viewOption, index);if (option.state.testFlag(QStyle::State_HasFocus))viewOption.state = viewOption.state ^ QStyle::State_HasFocus;QStyledItemDelegate::paint(painter, viewOption, index);int value = index.model()->data(index).toUInt();if (value < 0)value = 0;else if (value > 100)value = 100;int w = qMin(option.rect.width(), option.rect.height()) / 10.0;QStyleOptionProgressBar progressBarOption;progressBarOption.initFrom(option.widget);progressBarOption.rect = option.rect.adjusted(w, w, -w, -w);progressBarOption.minimum = 0;progressBarOption.maximum = 100;progressBarOption.textAlignment = Qt::AlignCenter;progressBarOption.textVisible = true;progressBarOption.progress = value;progressBarOption.text = tr("%1%").arg(progressBarOption.progress);painter->save();if (option.state & QStyle::State_Selected) {painter->fillRect(option.rect, option.palette.highlight());painter->setBrush(option.palette.highlightedText());}QProgressBar progressBar;qApp->style()->drawControl(QStyle::CE_ProgressBar, &progressBarOption, painter, &progressBar);painter->restore();
}
 4、排序代理

sortfilterproxymodel.h

#ifndef SORTFILTERPROXYMODEL_H
#define SORTFILTERPROXYMODEL_H#include <QSortFilterProxyModel>//排序代理
class SortFilterProxyModel : public QSortFilterProxyModel
{
public:SortFilterProxyModel(QObject *parent = nullptr): QSortFilterProxyModel(parent) {}protected:bool lessThan(const QModelIndex &left, const QModelIndex &right) const override; //重定义排序规则
};#endif // SORTFILTERPROXYMODEL_H

      sortfilterproxymodel.cpp  

#include "sortfilterproxymodel.h"#include <QDateTime>bool SortFilterProxyModel::lessThan(const QModelIndex &left, const QModelIndex &right) const
{QVariant leftData = sourceModel()->data(left);QVariant rightData = sourceModel()->data(right);if (leftData.userType() == QMetaType::QDateTime) {return leftData.toDateTime() < rightData.toDateTime();} else if(leftData.userType() == QMetaType::Int) {return leftData.toInt() > rightData.toInt();}QString leftString = leftData.toString();QString rightString = rightData.toString();return QString::localeAwareCompare(leftString, rightString) < 0;
}
5、学生数据表数据模型

 studenttablemodel.h

#ifndef STUDENTTABLEMODEL_H
#define STUDENTTABLEMODEL_H#include <QAbstractTableModel>struct Student;
class StuedentTableModel : public QAbstractTableModel
{Q_OBJECT
public:explicit StuedentTableModel(QObject *parent = nullptr): QAbstractTableModel(parent){}int rowCount(const QModelIndex & = QModelIndex()) const { return m_students.count(); }int columnCount(const QModelIndex & = QModelIndex()) const { return 7; }QVariant data(const QModelIndex &index, int role = Qt::DisplayRole) const;bool setData(const QModelIndex &index, const QVariant &value, int role = Qt::EditRole);QVariant headerData(int section, Qt::Orientation orientation, int role = Qt::DisplayRole) const;Qt::ItemFlags flags(const QModelIndex &index) const;void setStudents(const QList<Student *> &students);private:QList<Student *> m_students;
};#endif // STUDENTTABLEMODEL_H

 studenttablemodel.cpp

#include "studenttablemodel.h"
#include "student.h"enum Property { ID, NAME, AGE, GENDER, ACHIEVEMENT, MENUBUTTON, PROCESS };QVariant StuedentTableModel::data(const QModelIndex &index, int role) const
{if (!index.isValid())return false;int row = index.row();int col = index.column();Student *stu = m_students.at(row);switch (role) {case Qt::TextAlignmentRole: return Qt::AlignCenter;case Qt::CheckStateRole:switch (col) {case ID: return stu->checked;default: break;}break;case Qt::DisplayRole:case Qt::EditRole: { //双击为空需添加switch (col) {case ID: return stu->id;case NAME: return stu->name;case AGE: return stu->age;case GENDER: return stu->gender;case ACHIEVEMENT: return stu->achievement;case MENUBUTTON: return tr("Detail");case PROCESS: return stu->process;default: break;}case Qt::UserRole: {switch (col) {case MENUBUTTON: return QVariant::fromValue(stu);default: break;}}}default: break;}return QVariant();
}bool StuedentTableModel::setData(const QModelIndex &index, const QVariant &value, int role)
{if (!index.isValid())return false;int row = index.row();int col = index.column();Student *stu = m_students[row];switch (role) {case Qt::CheckStateRole:switch (col) {case ID:stu->checked = !stu->checked;emit dataChanged(index, index);return true;default: break;}break;case Qt::EditRole:switch (col) {case ID: stu->id = value.toUInt(); break;case NAME: stu->name = value.toString(); break;case AGE: stu->age = value.toUInt(); break;case GENDER: stu->gender = value.toString(); break;case ACHIEVEMENT: stu->achievement = value.toUInt(); break;case PROCESS: stu->process = value.toUInt(); break;}emit dataChanged(index, index);return true;default: break;}return false;
}QVariant StuedentTableModel::headerData(int section, Qt::Orientation orientation, int role) const
{const QStringList names = {tr("ID"),tr("姓名"),tr("年龄"),tr("性别"),tr("成绩"),tr("详情"),tr("进度")};if (section < 0 || section >= names.size())return QVariant();if (orientation == Qt::Horizontal && role == Qt::DisplayRole)return names.at(section);return QVariant();
}Qt::ItemFlags StuedentTableModel::flags(const QModelIndex &index) const
{Qt::ItemFlags flags = QAbstractTableModel::flags(index);flags |= Qt::ItemIsEditable;if (index.column() == ID)flags |= Qt::ItemIsUserCheckable;return flags;
}void StuedentTableModel::setStudents(const QList<Student *> &students)
{beginResetModel(); //重置数据之前调用,会自动触发 modelAboutToBeReset 信号m_students = students;endResetModel();   //重置数据完成后调用,会自动触发 modelReset 信号
}
 6、学生数据表

stuedenttable.h

#ifndef STUDENTTABLE_H
#define STUDENTTABLE_H#include <QAbstractTableModel>
#include <QStyledItemDelegate>
#include <QTableView>struct Student;
class StuedentTableModel;
class StudentsTable : public QTableView
{Q_OBJECT
public:StudentsTable(QWidget *parent = nullptr);void setStudents(const QList<Student *> &students);protected:void contextMenuEvent(QContextMenuEvent *event) override;signals:void insertItem();void removeItem();private:void initMenu();StuedentTableModel *m_stuModel;QMenu *m_menu;
};#endif // STUDENTTABLE_H

 stuedenttable.cpp

#include "stuedenttable.h"
#include "buttondelegate.h"
#include "comboboxdelegate.h"
#include "progressbardelegate.h"
#include "sortfilterproxymodel.h"
#include "studenttablemodel.h"#include <QtWidgets>StudentsTable::StudentsTable(QWidget *parent): QTableView(parent), m_stuModel(new StuedentTableModel(this)), m_menu(new QMenu(this))
{setShowGrid(true);setWordWrap(false);setAlternatingRowColors(true);verticalHeader()->setVisible(false);verticalHeader()->setDefaultSectionSize(30);horizontalHeader()->setStretchLastSection(true);horizontalHeader()->setDefaultSectionSize(90);horizontalHeader()->setMinimumSectionSize(35);horizontalHeader()->setSectionResizeMode(QHeaderView::Interactive);setSelectionBehavior(QAbstractItemView::SelectItems);setSelectionMode(QAbstractItemView::SingleSelection);setContextMenuPolicy(Qt::DefaultContextMenu);//设置委托setItemDelegateForColumn(3, new ComboBoxDelegate(this)); //下拉框setItemDelegateForColumn(5, new ButtonDelegate(this));  //按钮setItemDelegateForColumn(6, new ProgressBarDelegate(this)); //进度条//设置代理实现自定义排序setSortingEnabled(true);SortFilterProxyModel *sortModel = new SortFilterProxyModel(this);sortModel->setSourceModel(m_stuModel);setModel(sortModel);initMenu();
}void StudentsTable::setStudents(const QList<Student *> &students)
{m_stuModel->setStudents(students);
}void StudentsTable::contextMenuEvent(QContextMenuEvent *event)
{if (!currentIndex().isValid())return;m_menu->exec(mapToGlobal(event->pos()));
}void StudentsTable::initMenu()
{m_menu->addAction(tr("insert"), this, &StudentsTable::insertItem);m_menu->addAction(tr("remove"), this, &StudentsTable::removeItem);m_menu->addAction(tr("rename"), this, [this] { edit(currentIndex().siblingAtColumn(0)); });
}

五、使用示例

以下是一个简单的示例代码,演示了如何在Qt中使用StudentsTable控件:

mainwindow.h
#ifndef MAINWINDOW_H
#define MAINWINDOW_H#include <QMainWindow>struct Student;
class StudentsTable;
class MainWindow : public QMainWindow
{Q_OBJECTpublic:MainWindow(QWidget *parent = nullptr);~MainWindow();private slots:void onInsertItem();void onRemoveItem();private:void init();void setupUI();StudentsTable *m_table;QList<Student *> m_students;
};
#endif // MAINWINDOW_H
mainwindow.cpp
#include "mainwindow.h"
#include "student.h"
#include "studenttablemodel.h"
#include "stuedenttable.h"#include <QtWidgets>MainWindow::MainWindow(QWidget *parent): QMainWindow(parent)
{setupUI();init();resize(800, 300);
}MainWindow::~MainWindow()
{if (!m_students.isEmpty()) {qDeleteAll(m_students);m_students.clear();}
}void MainWindow::onInsertItem()
{int row = m_table->currentIndex().row();Student *stu = new Student;stu->id = m_students.size();if (row < 0 || row >= m_students.size())m_students.append(stu);elsem_students.insert(row, stu);m_table->setStudents(m_students);
}void MainWindow::onRemoveItem()
{QModelIndex index = m_table->currentIndex();if (!index.isValid())return;int row = index.row();delete m_students.takeAt(row);m_table->setStudents(m_students);
}void MainWindow::init()
{m_students.append(new Student{true, 0, "Jason", 15, "男", 66, 10});m_students.append(new Student{false, 1, "Lily", 13, "女", 85, 20});m_students.append(new Student{true, 2, "Odin", 16, "女", 76, 30});m_students.append(new Student{false, 3, "Willion", 12, "男", 89, 40});m_students.append(new Student{true, 4, "Nieo", 14, "男", 77, 50});m_table->setStudents(m_students);m_table->selectRow(m_students.size() - 1);
}void MainWindow::setupUI()
{QPushButton *addBtn = new QPushButton(tr("增加"), this);QPushButton *removeBtn = new QPushButton(tr("删除"), this);m_table = new StudentsTable(this);QHBoxLayout *hLayout = new QHBoxLayout;hLayout->addStretch(1);hLayout->addWidget(addBtn);hLayout->addWidget(removeBtn);QVBoxLayout *layout = new QVBoxLayout;layout->addLayout(hLayout);layout->addWidget(m_table);QFrame *frame = new QFrame(this);frame->setLayout(layout);setCentralWidget(frame);connect(m_table, &StudentsTable::insertItem, this, &MainWindow::onInsertItem);connect(m_table, &StudentsTable::removeItem, this, &MainWindow::onRemoveItem);connect(addBtn, &QPushButton::clicked, this, &MainWindow::onInsertItem);connect(removeBtn, &QPushButton::clicked, this, &MainWindow::onRemoveItem);
}

        到此本文基于QTableView的Model View Delegate使用方法就介绍到这了。

        总的来说,Qt的模型视图代理提供了一种灵活的方式来显示和编辑数据,在处理大量数据和复杂数据结构时特别有用。它将数据与界面分离,使得数据的表示和样式能够独立于数据本身进行修改。这种模式不仅提高了开发效率,还使得代码更加清晰和易于维护。

        谢谢您的阅读,希望本文能为您带来一些帮助和启发。如果您有任何问题或意见,请随时与我联系。祝您度过美好的一天!

六、源代码下载

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

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

West-Wild-v1.1靶机

信息收集&#xff1a; 靶机地址&#xff1a;https://www.vulnhub.com/entry/westwild-11,338/ &#xff08;1&#xff09;主页给出靶机ip&#xff0c;kali跟靶机仅主机网卡就可以 &#xff08;2&#xff09;端口扫描 nmap 192.168.8.129 -p- -A -sV -Pn &#xff08;3&#…

iOS ------ UIKit相关

UIView和CALayer UIView UIView表示屏幕上的一块矩形区域&#xff0c;它是基本上iOS中所有可视化控件的父类。UIView可以管理矩形区域里的内容&#xff0c;处理矩形区域的事件&#xff0c;包括子视图的管理以及动画的实现。 UIKit相关类的继承关系 UIView继承自UIResponde…

云原生-利用容器和编排器

容器和编排器旨在解决单片部署方法中常见的问题。 1. 整体部署的挑战 传统上&#xff0c;大多数应用程序都是作为单个单元部署的。这样的应用程序被称为单体。这种将应用程序作为单个单元部署的一般方法&#xff08;即使它们由多个模块或程序集组成&#xff09;称为单体架构&…

OrangePi AIpro学习4 —— 昇腾AI模型应用

目录 一、ATC模型转换 1.1 模型 1.2 ATC工具 1.3 实操模型转换 1.4 使用ATC工具时的一些关键注意事项 1.5 ATC模型转换命令举例 二、运行昇腾AI模型应用样仓程序 2.1 程序目录 2.2 下载模型和模型转换 2.3 下载图片和编译程序 2.4 解决报错 2.5 运行程序 三、运行…

《决胜B端 产品经理升级之路》 知识点总结

什么是b端产品&#xff1f; b端产品是指面向企业或组织的经营管理问题&#xff0c;旨在解决企业规模、成本、效率、品质和风控等方面的产品。这些产品主要帮助企业提高运营效率、降低成本、改善品质和控制风险等。b端产品适用于各种行业和企业类型&#xff0c;可以为企业带来深…

Parallels Desktop 可以做什么?

现在 Mac 电脑在全球越来越火&#xff0c;但是很多时候我们还是需要用win上的老物件&#xff0c;也就导致越来越多的用户都想在 Mac 上跑 Windows 软件和游戏。虽说 MacOS 本身有不少厉害的应用程序&#xff0c;可有些 Windows 专用的软件和游戏在 MacOS 里还是没法直接跑。 黑…

视觉SLAM ch3—三维空间的刚体运动

如果对于某些线性代数的知识不太牢固&#xff0c;可以看一下我的另一篇博客&#xff0c;写了一些基础知识并推荐了一些视频。 旋转矩阵 单元所需的线代基础知识https://blog.csdn.net/Johaden/article/details/141023668 一、旋转矩阵 1.点、向量、坐标系 在数学中&…

线程池总结

一.线程池的概念 线程池是一种管理和复用线程的设计模式&#xff0c;主要用于提高多线程编程中的效率。它通过维护一组线程来执行多个任务&#xff0c;从而避免频繁地创建和销毁线程所带来的性能开销。 线程池里取线程比从系统中申请线程更高效的原因&#xff0c;也是因为线程池…

基于深度学习的太阳暗条检测(2020年以来)

A universal method for solar filament detection from Hα observations using semi-supervised deep learning A&A, 686, A213 (2024) A universal method for solar filament detection from Hα observations using semi-supervised deep learning (aanda.org) ABS…

七夕特辑:用Ta的照片定制专属二维码,传递独一无二的爱

七夕火热进行中&#xff0c;有人还在纠结送啥礼物合适么&#xff1f; 围观可能是“全网第一人”的技术助力七夕之特别礼物 &#xff01;&#xff01;&#xff01; 欢迎扫码关注围观。 七夕特辑&#xff1a;扫码解锁爱情故事&#xff0c;让爱穿越时空 七夕特辑&#xff1a;用…

猫头虎推荐:人类通向AGI之路 史上最重磅的20篇论文你值得学习

猫头虎推荐&#xff1a;人类通向AGI之路 史上最重磅的20篇论文你值得学习 &#x1f44b; 大家好&#xff0c;我是猫头虎&#xff0c;今天我们为大家带来一篇穿越时空的AI研究大作&#xff01;这篇文章将带你领略过去15年推动人工智能&#xff08;AI&#xff09;发展的20篇经典…

【驱动篇】龙芯LS2K0300之RTC设备驱动

实验介绍 本次实验是关于pcf8563 RTC模块的驱动移植&#xff0c;大致流程如下&#xff1a; 注册i2c设备驱动编写RTC设备驱动将device和driver驱动部署到开发板并装载&#xff0c;通过hwclock命令来测试 模块连接 VCC接Pin2&#xff0c;GND接Pin1&#xff0c;SCL接Pin16&…

比OpenAI的Whisper快50%,最新开源语音模型

生成式AI初创公司aiOla在官网开源了最新语音模型Whisper-Medusa&#xff0c;推理效率比OpenAI开源的Whisper快50%。 aiOla在Whisper的架构之上进行了修改采用了“多头注意力”机制的并行计算方法&#xff0c;允许模型在每个推理步骤中预测多个token&#xff0c;同时不会损失性…

略谈set与map的pair封装与进入哈希

引子&#xff1a;之前我们讲了红黑树的自实现&#xff0c;与小小的接口实现&#xff0c;那set与map的pair封装是如何实现的呢&#xff1f;&#xff0c;今天我们来一探究竟&#xff0c;而且我们也要进入新章节--哈希 对于operator--()的封装&#xff1a; 注意&#xff1a;牢记思…

一款.NET开发的AI无损放大工具

一款.NET开发的AI无损放大工具 思维导航 前言项目功能支持语言系统要求项目源代码项目运行小图片进行无损放大项目源码地址优秀项目和框架精选 前言 今天大姚给大家分享一款由.NET开源&#xff08;GPL-3.0 license&#xff09;、基于腾讯ARC Lab提供的Real-ESRGAN模型开发的A…

Linux知识复习第2期

RHCE 远程登录服务-CSDN博客 Linux 用户和组管理_linux用户和组的管理-CSDN博客 Linux 文件权限详解-CSDN博客 目录 1、sshd 免密登录 (1)纯净实验环境 (2)生成密钥 (3)上锁 2、用户管理 (1)添加新用户 (2)删除用户 (3)修改用户信息 (4)为用户账号设…

【Linux:环境变量】

目录 命令行参数&#xff1a; 环境变量&#xff1a; 命令行参数&#xff1a; argv是一个char*类型的数组&#xff0c;里面存放着字符、字符串的指针地址&#xff0c;且该数组必定是以NULL结尾 命令行中启动的进程都是Bash的子进程&#xff0c;命令行参数的存在本质上就是通过…

[qt] 多线程应用01

源码: 点击此处 一 多线程应用 实现一个多线程的网络时间服务器&#xff0c;利用多线程功能的技术&#xff0c;为每个客户端返回当前的时间&#xff0c;并且在返回后自动退出。同时&#xff0c;服务器也会记录当前受到的请求次数。其实这相当于一个ntp时间服务器 二 服务器实…

职场中,这些事情是禁忌

越级打报告 身处职场&#xff0c;一定要清晰地明确自己所处的位置。要了解部门的运营架构和人事结构&#xff0c;这是身为职场人对自己的最基本的要求。以此确保一旦工作中出现什么问题时&#xff0c;你能找到相应的负责人。但是这里一定要注意&#xff0c;千万不要故作聪明越…

【数据结构】顺序表实现

0. 前言 小伙伴们大家好&#xff0c;从今天开始&#xff0c;我们就开始学习《数据结构》这门课程~ 首先想给大家讲讲什么是数据结构&#xff1f; 0.1 数据结构是什么&#xff1f; 数据结构是由“数据”和“结构”两词组合⽽来。 什么是数据&#xff1f; 比如常⻅的数值1、…