一.简介

Widget中要实现model的排序和过滤还是很方便的,直接使用QSortFilterProxyModel即可,而且Qt自带的两个demo——basicsortfiltermodel和customsortfiltermodel讲解了QSortFilterProxyModel的基本使用方法。在QML中如果实现过滤和排序,可以继承QSortFilterProxyModel然后将C++接口暴露给QML使用,可参考:Qt之在QML中使用QSortFilterProxyModel进行排序和过滤,该博客实现了source model使用QML内置model和source model使用自定义model两种方式,虽然实现了功能,但是通用性和灵活性一言难尽。
没想到有大佬开源了一个very nice的项目:SortFilterProxyModel,该项目解决了前面说的通用性和灵活性的问题,使在QML中优雅的使用过滤和排序成为可能
SortFilterProxyModel的github地址:https://github.com/oKcerG/SortFilterProxyModel/
源码不多,我都看了一遍,可以说是麻雀虽小五脏俱全,功能很丰富,能封装的都封装了,看了下issues里有人反馈性能问题,可以这样说如果这个项目有性能问题,那么你自己用QSortFilterProxyModel从头去弄也会有性能问题。
这个项目对QML内置的model支持的非常好,但是对自定义model会有些问题,详见第三节

二.使用

使用也是非常方便
1.在pro中添加include(SortFilterProxyModel/SortFilterProxyModel.pri)
2.在QML中添加import SortFilterProxyModel 0.2
一个简单的demo

import QtQuick 2.2
import QtQuick.Controls 1.2
import SortFilterProxyModel 1.0ApplicationWindow {visible: truewidth: 640height: 480ListModel {id: personModelListElement{ firstName: "Adan"; lastName: "Gula"; favorite: true }ListElement{ firstName: "Alexandria"; lastName: "Armand"; favorite: false }ListElement{ firstName: "Alverta"; lastName: "Gorney"; favorite: false }ListElement{ firstName: "Annalisa"; lastName: "Dixion"; favorite: false }ListElement{ firstName: "Arlene"; lastName: "Drapeau"; favorite: false }ListElement{ firstName: "Ashely"; lastName: "Euler"; favorite: false }ListElement{ firstName: "Ashleigh"; lastName: "Terry"; favorite: false }ListElement{ firstName: "Audra"; lastName: "Vannorman"; favorite: false }ListElement{ firstName: "Bibi"; lastName: "Fraire"; favorite: false }ListElement{ firstName: "Branda"; lastName: "Melgoza"; favorite: false }ListElement{ firstName: "Breanna"; lastName: "Rotenberry"; favorite: false }ListElement{ firstName: "Brigette"; lastName: "Delk"; favorite: false }ListElement{ firstName: "Bruno"; lastName: "Raso"; favorite: false }ListElement{ firstName: "Calandra"; lastName: "Dudney"; favorite: true }ListElement{ firstName: "Carrol"; lastName: "Dedeaux"; favorite: false }ListElement{ firstName: "Celina"; lastName: "Bichrest"; favorite: false }ListElement{ firstName: "Celinda"; lastName: "Frutos"; favorite: false }ListElement{ firstName: "Celsa"; lastName: "Moen"; favorite: false }ListElement{ firstName: "Charise"; lastName: "Milan"; favorite: true }ListElement{ firstName: "Corazon"; lastName: "Burrus"; favorite: false }ListElement{ firstName: "Coreen"; lastName: "Dehner"; favorite: false }ListElement{ firstName: "Coretta"; lastName: "Stillwell"; favorite: false }ListElement{ firstName: "Cornell"; lastName: "Fierros"; favorite: false }ListElement{ firstName: "Deedee"; lastName: "Ruggerio"; favorite: false }ListElement{ firstName: "Demetrice"; lastName: "Mcclaren"; favorite: false }ListElement{ firstName: "Desiree"; lastName: "Marcano"; favorite: false }ListElement{ firstName: "Dimple"; lastName: "Harig"; favorite: false }ListElement{ firstName: "Divina"; lastName: "Fahie"; favorite: true }ListElement{ firstName: "Don"; lastName: "Thill"; favorite: false }ListElement{ firstName: "Ellena"; lastName: "Fredrick"; favorite: false }ListElement{ firstName: "Elmo"; lastName: "Routh"; favorite: false }ListElement{ firstName: "Elsie"; lastName: "Raulerson"; favorite: false }ListElement{ firstName: "Ervin"; lastName: "Bardsley"; favorite: false }ListElement{ firstName: "Estela"; lastName: "Alverson"; favorite: false }ListElement{ firstName: "Eufemia"; lastName: "Sheely"; favorite: true }ListElement{ firstName: "Fawn"; lastName: "Opie"; favorite: false }ListElement{ firstName: "Fred"; lastName: "Ralphs"; favorite: false }ListElement{ firstName: "Genevie"; lastName: "Spires"; favorite: false }ListElement{ firstName: "Genna"; lastName: "Quin"; favorite: false }ListElement{ firstName: "Gerri"; lastName: "Aden"; favorite: false }ListElement{ firstName: "Gianna"; lastName: "Shears"; favorite: false }ListElement{ firstName: "Gilda"; lastName: "Doyel"; favorite: false }ListElement{ firstName: "Glady"; lastName: "Peguero"; favorite: false }ListElement{ firstName: "Guy"; lastName: "Sondag"; favorite: false }ListElement{ firstName: "Herschel"; lastName: "Flowers"; favorite: false }ListElement{ firstName: "Hilda"; lastName: "Hamm"; favorite: false }ListElement{ firstName: "Hiroko"; lastName: "Mccarley"; favorite: false }ListElement{ firstName: "Jackeline"; lastName: "Millington"; favorite: false }ListElement{ firstName: "Jacqualine"; lastName: "Twiss"; favorite: false }ListElement{ firstName: "Jacquelyne"; lastName: "Worsley"; favorite: false }ListElement{ firstName: "Janelle"; lastName: "Broman"; favorite: false }ListElement{ firstName: "Jani"; lastName: "Reddish"; favorite: false }ListElement{ firstName: "Jasper"; lastName: "Krone"; favorite: false }ListElement{ firstName: "Jene"; lastName: "Gump"; favorite: false }ListElement{ firstName: "Jimmie"; lastName: "Cooley"; favorite: false }ListElement{ firstName: "Kellye"; lastName: "Wiest"; favorite: false }ListElement{ firstName: "Kristie"; lastName: "Jules"; favorite: false }ListElement{ firstName: "Kymberly"; lastName: "Moodie"; favorite: false }ListElement{ firstName: "Latesha"; lastName: "Netter"; favorite: false }ListElement{ firstName: "Lavelle"; lastName: "Lasala"; favorite: false }ListElement{ firstName: "Lesli"; lastName: "Czapla"; favorite: false }ListElement{ firstName: "Lorette"; lastName: "Prescott"; favorite: false }ListElement{ firstName: "Lorie"; lastName: "Hoeft"; favorite: false }ListElement{ firstName: "Lyndia"; lastName: "Schwalm"; favorite: false }ListElement{ firstName: "Mable"; lastName: "Marron"; favorite: false }ListElement{ firstName: "Marcelino"; lastName: "Spence"; favorite: false }ListElement{ firstName: "Marcie"; lastName: "Yopp"; favorite: false }ListElement{ firstName: "Margrett"; lastName: "Spagnuolo"; favorite: false }ListElement{ firstName: "Maris"; lastName: "Ruff"; favorite: false }ListElement{ firstName: "Marvella"; lastName: "Bowlby"; favorite: false }ListElement{ firstName: "Mauro"; lastName: "Winberg"; favorite: false }ListElement{ firstName: "Maybelle"; lastName: "Chute"; favorite: false }ListElement{ firstName: "Meghan"; lastName: "Burts"; favorite: false }ListElement{ firstName: "Micah"; lastName: "Hoggan"; favorite: false }ListElement{ firstName: "Mireille"; lastName: "Eastin"; favorite: false }ListElement{ firstName: "Mitsue"; lastName: "Ohler"; favorite: false }ListElement{ firstName: "Monica"; lastName: "Mccall"; favorite: false }ListElement{ firstName: "Morris"; lastName: "Cappel"; favorite: false }ListElement{ firstName: "Myong"; lastName: "Bale"; favorite: false }ListElement{ firstName: "Nannie"; lastName: "Poore"; favorite: false }ListElement{ firstName: "Noella"; lastName: "Gledhill"; favorite: false }ListElement{ firstName: "Ofelia"; lastName: "Bane"; favorite: true }ListElement{ firstName: "Phoebe"; lastName: "Bui"; favorite: false }ListElement{ firstName: "Quincy"; lastName: "Sweeting"; favorite: false }ListElement{ firstName: "Raguel"; lastName: "Ross"; favorite: false }ListElement{ firstName: "Raymundo"; lastName: "Headlee"; favorite: false }ListElement{ firstName: "Ressie"; lastName: "Helt"; favorite: false }ListElement{ firstName: "Rikki"; lastName: "Gilligan"; favorite: false }ListElement{ firstName: "Roselee"; lastName: "Swain"; favorite: false }ListElement{ firstName: "Shanda"; lastName: "Ballew"; favorite: false }ListElement{ firstName: "Stephine"; lastName: "Dimauro"; favorite: false }ListElement{ firstName: "Tamesha"; lastName: "Roop"; favorite: false }ListElement{ firstName: "Temple"; lastName: "Mcbain"; favorite: false }ListElement{ firstName: "Tiesha"; lastName: "Crumley"; favorite: false }ListElement{ firstName: "Tova"; lastName: "Kiel"; favorite: false }ListElement{ firstName: "Wade"; lastName: "Fossum"; favorite: false }ListElement{ firstName: "Willodean"; lastName: "Ferguson"; favorite: false }ListElement{ firstName: "Winfred"; lastName: "High"; favorite: false }ListElement{ firstName: "Winter"; lastName: "Furrow"; favorite: false }ListElement{ firstName: "Yvone"; lastName: "Edge"; favorite: true }}TextField {id: textFieldanchors { top: parent.top; left: parent.left; right: parent.right }height: implicitHeight}SortFilterProxyModel {id: personProxyModelsourceModel: personModelfilters: RegExpFilter {roleName: "lastName"pattern: textField.textcaseSensitivity: Qt.CaseInsensitive}sorters: StringSorter { roleName: "firstName" }}ListView {anchors { top: textField.bottom; bottom: parent.bottom; left: parent.left; right: parent.right }model: personProxyModeldelegate: Text { text: model.firstName + " " + model.lastName}}
}

该demo按照firstName排序,按照lastName过滤来实现搜索,效果如下:


demo稍微有点简陋,而且只用到一个filter和sorter,像AllOf和AnyOf这种容器类型的filter都没用到,而且sorter的种类也很丰富,这里只用到了字符串排序,好在官方提供了一个漂亮的demo—SFPMShowcase
SFPMShowcase的github地址:https://github.com/oKcerG/SFPMShowcase
效果如下:


具体实现可参考其实现
但是如果要真正用好SortFilterProxyModel,源码还是得看的

三.自定义model

如果自定义model中的数据和roleName是一样对应的关系,那么这个自定义model对SortFilterProxyModel来说在使用上和内置model是一样的,下面是一个例子
QHListModel.h

#ifndef QHLISTMODEL_H
#define QHLISTMODEL_H#include <QAbstractListModel>enum Roles
{IDRole = Qt::UserRole + 1,NameRole = Qt::UserRole + 2
};class QHListModel : public QAbstractListModel
{
public:QHListModel();~QHListModel();void addData(int id, const QString &name);protected:int rowCount(const QModelIndex &parent = QModelIndex()) const override;QVariant data(const QModelIndex &index, int role = Qt::DisplayRole) const override;QHash<int, QByteArray> roleNames() const override;private:QList<int> m_userIDs;QStringList m_userNames;
};#endif // QHLISTMODEL_H

QHListModel.cpp

#include "QHListModel.h"QHListModel::QHListModel()
{}QHListModel::~QHListModel()
{}void QHListModel::addData(int id, const QString &name)
{beginInsertRows(QModelIndex(), rowCount(), rowCount());m_userIDs.append(id);m_userNames.append(name);endInsertRows();
}int QHListModel::rowCount(const QModelIndex &parent) const
{Q_UNUSED(parent)return m_userNames.count();
}QVariant QHListModel::data(const QModelIndex &index, int role) const
{if (index.row() < 0 || index.row() >= m_userNames.count()){return QVariant();}if (role == IDRole){return m_userIDs[index.row()];}if (role == NameRole){return m_userNames[index.row()];}return QVariant();
}QHash<int, QByteArray> QHListModel::roleNames() const
{QHash<int, QByteArray> roles;roles[IDRole] = "userID";roles[NameRole] = "userName";return roles;
}

这个model中的用户ID和用户名数据相对应的roleName分别是userID和userName,在SortFilterProxyModel中只需操作userID和userName即可
main.qml

import QtQuick 2.9
import QtQuick.Window 2.2
import QtQuick.Controls 2.0
import QtQuick.Layouts 1.0
import SortFilterProxyModel 0.2Window {visible: truewidth: 480height: 800title: qsTr("Hello World")Item {anchors.fill: parentanchors.margins: 10SortFilterProxyModel {id: proxyModelsourceModel: searchModelsorters: RoleSorter {roleName: "userID"sortOrder: searchTool.sortOrder}filters: RegExpFilter {roleName: "userName"pattern: textField.textcaseSensitivity: Qt.CaseInsensitive}}Rectangle {id: searchToolanchors.top: parent.topanchors.left: parent.leftanchors.right: parent.rightheight: 40property int sortOrder: Qt.AscendingOrderRowLayout {anchors.fill: parentanchors.centerIn: parentTextField {id: textFieldplaceholderText: "请输入关键字"Layout.fillWidth: truefont.pointSize: 12}CheckBox {text: "DescendingOrder"onCheckedChanged:{searchTool.sortOrder = checked ? Qt.DescendingOrder : Qt.AscendingOrder;}}}}ListView {id: viewmodel: proxyModelanchors.top: searchTool.bottomanchors.topMargin: 3anchors.bottom: parent.bottomanchors.left: parent.leftanchors.right: parent.rightcacheBuffer: 100clip: truespacing: 1delegate: Rectangle{width: parent.widthradius: 5anchors.horizontalCenter: parent.horizontalCenterheight: 40color: "black"RowLayout {anchors.fill: parentanchors.leftMargin: 30spacing: 30Text {text: userIDfont.pointSize: 12font.bold: truecolor: "white"}Text {text: userNamefont.pointSize: 12font.bold: truecolor: "white"Layout.fillWidth: true}}}ScrollBar.vertical: ScrollBar {anchors.right: parent.rightanchors.rightMargin: 1width: 16}}}
}

在SortFilterProxyModel中,使用userID进行排序,使用userName进行过滤
main.cpp

#include <QGuiApplication>
#include <QQmlApplicationEngine>
#include <QQmlContext>#include "QHListModel.h"#pragma execution_character_set("utf-8")// 随机民生成器.
inline void DataBaseRoll(std::string &name)
{//百家姓-单姓.std::string NA1[444] = { "赵", "钱", "孙", "李", "周", "吴", "郑", "王", "冯", "陈", "褚", "卫", "蒋", "沈", "韩", "杨", "朱", "秦", "尤", "许", "何", "吕", "施", "张", "孔", "曹", "严", "华", "金", "魏", "陶", "姜", "戚", "谢", "邹", "喻", "柏", "水", "窦", "章", "云", "苏", "潘", "葛", "奚", "范", "彭", "郎", "鲁", "韦", "昌", "马", "苗", "凤", "花", "方", "俞", "任", "袁", "柳", "酆", "鲍", "史", "唐", "费", "廉", "岑", "薛", "雷", "贺", "倪", "汤", "滕", "殷", "罗", "毕", "郝", "邬", "安", "常", "乐", "于", "时", "傅", "皮", "卞", "齐", "康", "伍", "余", "元", "卜", "顾", "孟", "平", "黄", "和", "穆", "萧", "尹", "姚", "邵", "湛", "汪", "祁", "毛", "禹", "狄", "米", "贝", "明", "臧", "计", "伏", "成", "戴", "谈", "宋", "茅", "庞", "熊", "纪", "舒", "屈", "项", "祝", "董", "梁", "杜", "阮", "蓝", "闵", "席", "季", "麻", "强", "贾", "路", "娄", "危", "江", "童", "颜", "郭", "梅", "盛", "林", "刁", "钟", "徐", "邱", "骆", "高", "夏", "蔡", "田", "樊", "胡", "凌", "霍", "虞", "万", "支", "柯", "昝", "管", "卢", "莫", "经", "房", "裘", "缪", "干", "解", "应", "宗", "丁", "宣", "贲", "邓", "郁", "单", "杭", "洪", "包", "诸", "左", "石", "崔", "吉", "钮", "龚", "程", "嵇", "邢", "滑", "裴", "陆", "荣", "翁", "荀", "羊", "於", "惠", "甄", "麴", "家", "封", "芮", "羿", "储", "靳", "汲", "邴", "糜", "松", "井", "段", "富", "巫", "乌", "焦", "巴", "弓", "牧", "隗", "山", "谷", "车", "侯", "宓", "蓬", "全", "郗", "班", "仰", "秋", "仲", "伊", "宫", "宁", "仇", "栾", "暴", "甘", "钭", "厉", "戎", "祖", "武", "符", "刘", "景", "詹", "束", "龙", "叶", "幸", "司", "韶", "郜", "黎", "蓟", "薄", "印", "宿", "白", "怀", "蒲", "邰", "从", "鄂", "索", "咸", "籍", "赖", "卓", "蔺", "屠", "蒙","池", "乔", "阴", "郁", "胥", "能", "苍", "双", "闻", "莘", "党", "翟", "谭", "贡", "劳", "逄", "姬", "申", "扶", "堵", "冉", "宰", "郦", "雍", "舄", "璩", "桑", "桂", "濮", "牛", "寿", "通", "边", "扈", "燕", "冀", "郏", "浦", "尚", "农", "温", "别", "庄", "晏", "柴", "瞿", "阎", "充", "慕", "连", "茹", "习", "宦", "艾", "鱼", "容", "向", "古", "易", "慎", "戈", "廖", "庾", "终", "暨", "居", "衡", "步", "都", "耿", "满", "弘", "匡", "国", "文", "寇", "广", "禄", "阙", "东", "殴", "殳", "沃", "利", "蔚", "越", "夔", "隆", "师", "巩", "厍", "聂", "晁", "勾", "敖", "融", "冷", "訾", "辛", "阚", "那", "简", "饶", "空", "曾", "毋", "沙", "乜", "养", "鞠", "须", "丰", "巢", "关", "蒯", "相", "查", "後", "荆", "红", "游", "竺", "权", "逯", "盖", "益", "桓", "公", "仉", "督", "晋", "楚", "闫", "法", "汝", "鄢", "涂", "钦", "归", "海","岳", "帅", "缑", "亢", "况", "后", "有", "琴", "商", "牟", "佘", "佴", "伯", "赏", "墨", "哈", "谯", "笪", "年", "爱", "阳", "佟", "言", "福" };std::string NA2[59] = { "万俟", "司马", "上官", "欧阳", "夏侯", "诸葛", "闻人", "东方", "赫连", "皇甫", "尉迟", "公羊", "澹台", "公冶", "宗政", "濮阳", "淳于", "单于", "太叔", "申屠", "公孙", "仲孙", "轩辕", "令狐", "钟离", "宇文", "长孙", "慕容", "鲜于", "闾丘", "司徒", "司空", "亓官", "司寇", "子车", "颛孙", "端木", "巫马", "公西", "漆雕", "乐正", "壤驷", "公良", "拓跋", "夹谷", "宰父", "谷梁", "百里", "东郭", "南门", "呼延", "羊舌", "微生", "梁丘", "左丘", "东门", "西门", "南宫", "第五" };std::string ME1m[140] = { "伟", "刚", "勇", "毅", "俊", "峰", "强", "军", "平", "保", "东", "文", "辉", "力", "明", "永", "健", "世", "广", "志", "义", "兴", "良", "海", "山", "仁", "波", "宁", "贵", "福", "生", "龙", "元", "全", "国", "胜", "学", "祥", "才", "发", "武", "新", "利", "清", "飞", "彬", "富", "顺", "信", "子", "杰", "涛", "昌", "成", "康", "星", "光", "天", "达", "安", "岩", "中", "茂", "进", "林", "有", "坚", "和", "彪", "博", "诚", "先", "敬", "震", "振", "壮", "会", "思", "群", "豪", "心", "邦", "承", "乐", "绍", "功", "松", "善", "厚", "庆", "磊", "民", "友", "裕", "河", "哲", "江", "超", "浩", "亮", "政", "谦", "亨", "奇", "固", "之", "轮", "翰", "朗", "伯", "宏", "言", "若", "鸣", "朋", "斌", "梁", "栋", "维", "启", "克", "伦", "翔", "旭", "鹏", "泽", "晨", "辰", "士", "以", "建", "家", "致", "树", "炎", "德", "行", "时", "泰", "盛" };std::string ME1f[165] = { "秀", "娟", "英", "华", "慧", "巧", "美", "娜", "静", "淑", "惠", "珠", "翠", "雅", "芝", "玉", "萍", "红", "娥", "玲", "芬", "芳", "燕", "彩", "春", "菊", "兰", "凤", "洁", "梅", "琳", "素", "云", "莲", "真", "环", "雪", "荣", "爱", "妹", "霞", "香", "月", "莺", "媛", "艳", "瑞", "凡", "佳", "嘉", "琼", "勤", "珍", "贞", "莉", "桂", "娣", "叶", "璧", "璐", "娅", "琦", "晶", "妍", "茜", "秋", "珊", "莎", "锦", "黛", "青", "倩", "婷", "姣", "婉", "娴", "瑾", "颖", "露", "瑶", "怡", "婵", "雁", "蓓", "纨", "仪", "荷", "丹", "蓉", "眉", "君", "琴", "蕊", "薇", "菁", "梦", "岚", "苑", "筠", "柔", "竹", "霭", "凝", "晓", "欢", "霄", "枫", "芸", "菲", "寒", "欣", "滢", "伊", "亚", "宜", "可", "姬", "舒", "影", "荔", "枝", "思", "丽", "秀", "飘", "育", "馥", "琦", "晶", "妍", "茜", "秋", "珊", "莎", "锦", "黛", "青", "倩", "婷", "宁","蓓", "纨", "苑", "婕", "馨", "瑗", "琰", "韵", "融", "园", "艺", "咏", "卿", "聪", "澜", "纯", "毓", "悦", "昭", "冰", "爽", "琬", "茗", "羽", "希" };std::string sex = (rand()%2 == 0?"男":"女");//男女选择.name = (rand()%56 != 5?NA1[rand()%444]:NA2[rand()%59]);//单姓Or复姓选择.name += (sex == "男" ? ME1m[rand()%140] : ME1f[rand()%165]);//取名第一字.if(rand()%2 == 0) name += (sex == "男" ? ME1m[rand()%140] : ME1f[rand()%165]);//取名第二字.
}int main(int argc, char *argv[])
{QCoreApplication::setAttribute(Qt::AA_EnableHighDpiScaling);QGuiApplication app(argc, argv);QHListModel listModel;for(int i=0;i<1000;i++){std::string name;DataBaseRoll(name);QString userName = QString::fromStdString(name);listModel.addData(i,userName);}QQmlApplicationEngine engine;QQmlContext *context = engine.rootContext();context->setContextProperty("searchModel", &listModel);engine.load(QUrl(QStringLiteral("qrc:/main.qml")));if (engine.rootObjects().isEmpty())return -1;return app.exec();
}

main函数里没啥特别的,随机生成了1000个名字并添加到自定义model中
运行效果如下:

但是像这样一种数据对应一个roleName还是比较麻烦的,实际上我们可以只使用一个roleName(比如说modelData),然后roleName对应的数据是一个容器(通常是指针类型),容器中包含着所需的各种属性(userID、userName、systemType、loginTime、online等等)
此时如果要用SortFilterProxyModel过滤userName,像上面那样写就不行的,实际上应该像下面这样写

SortFilterProxyModel {id: proxyModelsourceModel: searchModelfilters: RegExpFilter {roleName: "modelData.userName"pattern: textField.textcaseSensitivity: Qt.CaseInsensitive}
}

但是SortFilterProxyModel对"modelData.userName"这种二级roleName解析会有问题,无法实现想要的效果,因此得修改其源码才行

原文链接:https://blog.csdn.net/caoshangpa/article/details/126446067

Qt优秀开源项目之十四:SortFilterProxyModel相关推荐

  1. Qt优秀开源项目之十:开源截图工具flameshot

    这是一个功能强大的截图工具,支持的工具包括画笔.直线.箭头.矩形.椭圆.文字.马塞克,支持的操作也很丰富,具体自己去发现,上几张效果图: 最新版的还支持类似QQ的放大取色功能 外观支持定制,这个就很另 ...

  2. Qt优秀开源项目之十二:shotcut

    官网:https://www.shotcut.org/ github地址:https://github.com/mltframework/shotcut shotcut基于FFmpeg开发,是一款免费 ...

  3. Qt优秀开源项目之四:茶绘君

    茶绘君是一款能让你和你的朋友一起在线上绘画.享受创作的软件! 茶绘君包括客户端和服务器两部分,客户端由Qt开发. 茶绘君创意无限,截图如下: 官网:茶绘君 - 带你进入茶绘的世界! github:Gi ...

  4. Qt优秀开源项目之一:流媒体直播系统Open Broadcaster Software

    Open Broadcaster Software(OBS)是一款用于音视频录制和直播的免费开源软件.可以轻松部署到多种平台,目前支持Windows.MAC和Linux. 特性: 1.高性能的实时视频 ...

  5. Qt优秀开源项目之五:TTKMusicplayer

    这是一款高仿酷狗音乐播放器(支持网易云音乐.QQ音乐.酷我音乐.酷狗音乐),基于qmmp和Qt库开发 平台 Qt & 编译器 状态 Linux 4.8.7 GCC & 5.x GCC ...

  6. jeecg智能开发平台参与-2013年度中国优秀开源项目评比

    JEECG正在参与<2013年度中国十大优秀开源项目> 评比,如果大家觉得JEECG还不错, 请投出你宝贵的一票,给我们以支持吧!!! [目前排名第8位] https://code.csd ...

  7. 寻优秀开源项目,百万程序员为你助力!

    在近三十年的科技创新里,开源已成为技术应用和行业数字化发展的基石,开发者极度依赖与关注开源,开源商业化也取得了巨大突破. 全球开源的大趋势下,中国正逐渐成为全球开源软件的主要使用者和核心贡献者,大力发 ...

  8. Golang优秀开源项目汇总(持续更新。。。)

    Golang优秀开源项目汇总(持续更新...) 我把这个汇总放在github上了, 后面更新也会在github上更新. https://github.com/hackstoic/golang-open ...

  9. 阿里巴巴Java“代码反潜机”P3C喜提首届中国优秀开源项目二等奖!

    12 月 12-14 日,由中国开源云联盟.中国电子技术标准化研究院和全国信标委云计算标准工作组主办的第八届中国云计算标准和应用大会在京举行. 聚焦企业上云和开源,大会公布了首届中国优秀开源项目的名单 ...

  10. Apache RocketMQ 荣获 2021 中国开源云联盟优秀开源项目

    为推动国内开源生态产业发展,中国开源云联盟(China Open Source Cloud League,简称"COSCL")组织开展了 2021 杰出开源贡献者.优秀开源项目.最 ...

最新文章

  1. Cesium界面学习以及隐藏界面控件
  2. ARMV8/ARMV9指令集概述(翻译)
  3. Math 对象的扩展
  4. CSDN 蒋涛对话英特尔中国区董事长王锐:我愿是当代的一个开发者
  5. 2021年第十八届五一数学建模竞赛题目 C题 数据驱动的异常检测与预警问题 解题论文完整版
  6. qq令牌64位密钥提取_令牌QQ号代码64位数字+字母只截图保存可转换文字再来获取口令...
  7. 主动轮廓线模型Snake模型简介amp;openCV中cvSnakeImage()函数代码分析
  8. 十大自动化软件测试工具
  9. 一线明星纷纷失业,数据告诉你今年的演员有多难
  10. QNX 在车机系统中的应用
  11. scrapy安装时遇到问题怎么解决
  12. 小程序与H5,APP有什么不同-小程序支付开发1
  13. 协同感知综述:从异质单体到分层合作
  14. CentOS6.6下配置KMS自动激活服务器
  15. 又一恐怖技能!卡耐基梅隆大学发布超强智能体,炸翻科研圈
  16. 【驻油点】一辆重型卡车欲穿过1000公里的沙漠,卡车耗油为1升/公里,卡车总载油能力为500公升。显然卡车一次是过不了沙漠的。因此司机必须设法在沿途建立几个贮油点,使卡车能顺利穿越沙漠,试问司机如何建
  17. spark常见面试题
  18. 新星计划Day2【JavaSE】 枚举类与注解
  19. 什么是环境变量?为什么要配置环境变量
  20. JAVA微信开发(四), 公众号普通红包

热门文章

  1. 实用技巧:阿里云服务器建立公网物联网服务器(解决阿里云服务器端口,公网连接不上的问题)
  2. HTML 使用字体图标 引入图标
  3. ztree树默认根据ID默认选中该条数据
  4. 网站被黑了不要慌,4招教你如何破解!网站被黑的10大原因
  5. ICLR 2022 | 合作博弈新范式:为可解释性等机器学习估值问题提供新方法
  6. 下载各版本cuda,下载以前版本的cuda
  7. 20套数据可视化大屏模板,附源码下载
  8. Mysql 导出表结构或数据
  9. ExtJS6-项目创建
  10. 各种字体下载地址和移动端支持字体简析