diff --git a/OpenGLDemo/OpenGLDemo.md b/OpenGLDemo/OpenGLDemo.md index 4fa5a0f4c81de648bba527aa7954d4dbf055d38b..bf13abb97a978f120869fdaeff36096e3012b759 100644 --- a/OpenGLDemo/OpenGLDemo.md +++ b/OpenGLDemo/OpenGLDemo.md @@ -44,6 +44,7 @@ * 单独使用子线程刷新QOpenGLWidget可以看出CPU占用率为10.3%,GPU占用率为:30.3%; * 单独使用子线程刷新QOpenGLWindow可以看出CPU占用率为:7.9%,GPU占用率为:24.4%。 + * 并且因为QOpenGLWidget使用子线程刷新速度过快,可能出现残缺的情况。 ![TestOpenGLWindow2-tuya](OpenGLDemo.assets/TestOpenGLWindow2-tuya.gif) diff --git a/OpenGLDemo/TestOpenGLWindow/TestOpenGLWindow.pro b/OpenGLDemo/TestOpenGLWindow/TestOpenGLWindow.pro index ff5b242ff23231951b66a600d7d0f47aa6a1b5a5..ab34dd333aa7e2c9c8edde47349bbe86dbede01a 100644 --- a/OpenGLDemo/TestOpenGLWindow/TestOpenGLWindow.pro +++ b/OpenGLDemo/TestOpenGLWindow/TestOpenGLWindow.pro @@ -49,7 +49,7 @@ else: unix:!android: target.path = /opt/$${TARGET}/bin !isEmpty(target.path): INSTALLS += target # 定义程序版本号 -VERSION = 1.0.0 +VERSION = 1.0.1 DEFINES += APP_VERSION=\\\"$$VERSION\\\" contains(QT_ARCH, i386){ # 使用32位编译器 diff --git a/OpenGLDemo/TestOpenGLWindow/openglwidget.cpp b/OpenGLDemo/TestOpenGLWindow/openglwidget.cpp index 96e2729ea3fbe29c9b15d323d7149a78e693d568..c2d830edf91108f2030f769f841e823df66f1915 100644 --- a/OpenGLDemo/TestOpenGLWindow/openglwidget.cpp +++ b/OpenGLDemo/TestOpenGLWindow/openglwidget.cpp @@ -118,8 +118,8 @@ void OpenGLWidget::paintGL() glVertexAttribPointer(GLuint(m_colAttr), 3, GL_FLOAT, GL_FALSE, 0, colors); // 启用顶点数组 - glEnableVertexAttribArray(0); - glEnableVertexAttribArray(1); + glEnableVertexAttribArray(GLuint(m_posAttr)); // 属性索引是从调用glGetAttribLocation接收的,或者传递给glBindAttribLocation。 + glEnableVertexAttribArray(GLuint(m_colAttr)); // 提供绘制功能,从数组数据中提取数据渲染基本图元 glDrawArrays(GL_TRIANGLES, // 图元类型 @@ -127,8 +127,8 @@ void OpenGLWidget::paintGL() 3); // 数组中顶点的数量 // 禁用顶点属性数组 - glDisableVertexAttribArray(0); - glDisableVertexAttribArray(1); + glDisableVertexAttribArray(GLuint(m_posAttr)); + glDisableVertexAttribArray(GLuint(m_colAttr)); m_program->release(); // 从当前QOpenGLContext中释放活动着色器程序。 #endif diff --git a/OpenGLDemo/TestOpenGLWindow/openglwindow.cpp b/OpenGLDemo/TestOpenGLWindow/openglwindow.cpp index 4cad682eb5a03c9251317ed966c65901da08ca40..8bfb0514179a5830164cea697a3f886831eb1172 100644 --- a/OpenGLDemo/TestOpenGLWindow/openglwindow.cpp +++ b/OpenGLDemo/TestOpenGLWindow/openglwindow.cpp @@ -99,8 +99,8 @@ void OpenGLWindow::paintGL() glVertexAttribPointer(GLuint(m_colAttr), 3, GL_FLOAT, GL_FALSE, 0, colors); // 启用顶点数组 - glEnableVertexAttribArray(0); - glEnableVertexAttribArray(1); + glEnableVertexAttribArray(GLuint(m_posAttr)); // 属性索引是从调用glGetAttribLocation接收的,或者传递给glBindAttribLocation,在Qt里就是通过attributeLocation()获取的索引 + glEnableVertexAttribArray(GLuint(m_colAttr)); // 提供绘制功能,从数组数据中提取数据渲染基本图元 glDrawArrays(GL_TRIANGLES, // 图元类型 @@ -108,8 +108,8 @@ void OpenGLWindow::paintGL() 3); // 数组中顶点的数量 // 禁用顶点属性数组 - glDisableVertexAttribArray(0); - glDisableVertexAttribArray(1); + glDisableVertexAttribArray(GLuint(m_posAttr)); + glDisableVertexAttribArray(GLuint(m_colAttr)); m_program->release(); // 从当前QOpenGLContext中释放活动着色器程序。 #endif diff --git a/QMNetwork/NetInterface/netproperty.cpp b/QMNetwork/NetInterface/netproperty.cpp index 66fc058e10abecac3d7c2cc2cfbd851aeaf3de70..6065812b1005975c8b621467add95752fb874e4b 100644 --- a/QMNetwork/NetInterface/netproperty.cpp +++ b/QMNetwork/NetInterface/netproperty.cpp @@ -54,7 +54,9 @@ void NetProperty::on_com_Interface_activated(int index) return; } ui->tableWidget->item(0, 1)->setText(QString::number(interface.index())); // 获取网卡索引 +#if (QT_VERSION >= QT_VERSION_CHECK(5,11,0)) // qt5.11以后版本才有 ui->tableWidget->item(1, 1)->setText(QString::number(interface.maximumTransmissionUnit())); // 获取网卡最大传输数据单元 +#endif ui->tableWidget->item(2, 1)->setText(interface.name()); // 获取网卡名称 #if 0 // 直接显示标志枚举 @@ -64,7 +66,9 @@ void NetProperty::on_com_Interface_activated(int index) #else ui->tableWidget->item(3, 1)->setText(FlagsToQString(interface.flags())); #endif +#if (QT_VERSION >= QT_VERSION_CHECK(5,11,0)) // qt5.11以后版本才有 ui->tableWidget->item(4, 1)->setText(TypeToQString(interface.type())); // 获取网络类型说明 +#endif ui->tableWidget->item(5, 1)->setText(interface.hardwareAddress()); // // 获取MAC地址 ui->textEdit_ip->clear(); @@ -144,6 +148,7 @@ QString NetProperty::FlagsToQString(int flags) */ QString NetProperty::TypeToQString(int type) { +#if (QT_VERSION >= QT_VERSION_CHECK(5,11,0)) // qt5.11以后版本才有 switch (type) { case QNetworkInterface::Loopback: return "虚拟环回接口,分配了环回 IP 地址 (127.0.0.1, ::1)"; @@ -162,5 +167,8 @@ QString NetProperty::TypeToQString(int type) case QNetworkInterface::Unknown: return "接口类型无法确定或不是其他列出的类型之一"; default:return "未知"; } +#else + Q_UNUSED(type) +#endif } diff --git a/QMNetwork/QMNetwork.pro b/QMNetwork/QMNetwork.pro index 24a3df2cf4fe9f10bd1f6380639658559e529de8..9fb374bfc9920989a6fc836e26c0c0e9b7be3204 100644 --- a/QMNetwork/QMNetwork.pro +++ b/QMNetwork/QMNetwork.pro @@ -40,7 +40,7 @@ include($$PWD/NetInterface/NetInterface.pri) # 网络接口管理模块 INCLUDEPATH += $$PWD/NetInterface # 定义程序版本号 -VERSION = 1.0.0 +VERSION = 1.0.1 DEFINES += APP_VERSION=\\\"$$VERSION\\\" contains(QT_ARCH, i386){ # 使用32位编译器 diff --git a/QMNetwork/widget.ui b/QMNetwork/widget.ui index dd24114abd32268b0b1abed83a4d6dfadd39db8b..2e2c1ae7731e38e9111e4083e0c128075475f5ac 100644 --- a/QMNetwork/widget.ui +++ b/QMNetwork/widget.ui @@ -6,195 +6,117 @@ 0 0 - 588 - 466 + 522 + 294 Widget - - - - 500 - 190 - 75 - 23 - - - - 释放所有窗口 - - - - - - 20 - 20 - 471 - 131 - - - - 简易版 - - - - - 20 - 30 - 75 - 23 - - - - TCP客户端 - - - - - - 100 - 30 - 75 - 23 - - - - TCP服务端 - - - - - - 190 - 30 - 81 - 23 - - - - UDP单播通信1 - - - - - - 290 - 30 - 75 - 23 - - - - UDP单播通信2 - - - - - - 20 - 80 - 75 - 23 - - - - UDP组播 - - - - - - 100 - 80 - 75 - 23 - - - - MQTT - - - - - - 200 - 80 - 75 - 23 - - - - HTTP - - - - - - 290 - 80 - 75 - 23 - - - - 网络属性 - - - - - - - 20 - 160 - 471 - 111 - - - - 稍复杂版 - - - - - 180 - 20 - 75 - 23 - - - - UDP单播 - - - - - - 20 - 20 - 75 - 23 - - - - TCP客户端 - - - - - - 100 - 20 - 75 - 23 - - - - TCP服务端 - - - + + + + + 简易版 + + + + + + TCP客户端 + + + + + + + TCP服务端 + + + + + + + UDP单播通信1 + + + + + + + UDP单播通信2 + + + + + + + UDP组播 + + + + + + + MQTT + + + + + + + HTTP + + + + + + + + + + 稍复杂版 + + + + + + TCP客户端 + + + + + + + TCP服务端 + + + + + + + UDP单播 + + + + + + + + + + 网络属性 + + + + + + + 释放所有窗口 + + + + diff --git a/QSqlDemo/QSqlDemo.pro b/QSqlDemo/QSqlDemo.pro index abd402deccbd8390e56d74c3f4a40f35f3552a59..1caffb542a47a2c724b3e256dcfdfe667cd6ce09 100644 --- a/QSqlDemo/QSqlDemo.pro +++ b/QSqlDemo/QSqlDemo.pro @@ -4,4 +4,5 @@ SUBDIRS += \ CachedTable \ # 通过QSqlTableModel显示和修改数据,通过按键保存修改内容和恢复修改内容 RelationalTableModel \ # 本示例展示了如何使用QSqlRelationalTableModel(关系表模型)来可视化数据库中[外键]的使用。 SqlWidgetMapper \ # 通过QDataWidgetMapper将数据库数据映射到小部件 - TableModel # 这个Demo中展示了如何使用具有表视图的专用 SQL 表模型(QSqlTableModel)来编辑数据库中的信息。 + TableModel \ # 这个Demo中展示了如何使用具有表视图的专用 SQL 表模型(QSqlTableModel)来编辑数据库中的信息。 + TableModel2 # 这个Demo中展示了如何使用具有表视图的专用 SQL 表模型(QSqlTableModel)来编辑数据库中的信息,实现创建空白数据行、自增key diff --git a/QSqlDemo/TableModel/main.cpp b/QSqlDemo/TableModel/main.cpp index 1c8c1374c15406c98ffb0a6b7132639b207f14c6..869f6b0f040da656683242d707f4319456efe92c 100644 --- a/QSqlDemo/TableModel/main.cpp +++ b/QSqlDemo/TableModel/main.cpp @@ -105,7 +105,7 @@ int main(int argc, char *argv[]) QTableView *view = new QTableView; // 创建一个用于显示表的视图实现(由于是基于QWidget的,所以可以直接显示) view->resize(400, 300); // 设置窗口大小 view->setWindowTitle(""); - view->setWindowTitle(QString("QSql-使用QSqlTableModel显示数据库内容Demo - V%1").arg(APP_VERSION)); + view->setWindowTitle(QString("QSql-使用QSqlTableModel显示数据库内容Demo1 - V%1").arg(APP_VERSION)); view->setModel(&model); // 设置需要显示的表model view->show(); diff --git a/QSqlDemo/TableModel2/TableModel2.pro b/QSqlDemo/TableModel2/TableModel2.pro new file mode 100644 index 0000000000000000000000000000000000000000..dd4157c00b0cd582f9c4bbc261fce73669512ef2 --- /dev/null +++ b/QSqlDemo/TableModel2/TableModel2.pro @@ -0,0 +1,51 @@ +#--------------------------------------------------------------------------------------- +# @功能: 这个Demo中展示了如何使用具有表视图的专用 SQL 表模型(QSqlTableModel)来编辑数据库中的信息 +# 1、通过按键新建 空白数据行; +# 2、使用自增Key; +# 3、通过按键更新数据; +# 4、判断表是否存在,不存在则创建。 +# @编译器: Desktop Qt 5.12.5 MSVC2017 64bit(也支持其它编译器) +# @Qt IDE: D:/Qt/Qt5.12.5/Tools/QtCreator/share/qtcreator +# +# @开发者 mhf +# @邮箱 1603291350@qq.com +# @时间 2022-10-07 11:29:40 +# @备注 +#--------------------------------------------------------------------------------------- +QT += core gui sql + +greaterThan(QT_MAJOR_VERSION, 4): QT += widgets + +CONFIG += c++11 +DEFINES += QT_DEPRECATED_WARNINGS + +SOURCES += \ + main.cpp \ + widget.cpp + +HEADERS += \ + widget.h + +FORMS += \ + widget.ui + +# Default rules for deployment. +qnx: target.path = /tmp/$${TARGET}/bin +else: unix:!android: target.path = /opt/$${TARGET}/bin +!isEmpty(target.path): INSTALLS += target + +# 定义程序版本号 +VERSION = 1.0.0 +DEFINES += APP_VERSION=\\\"$$VERSION\\\" + +contains(QT_ARCH, i386){ # 使用32位编译器 +DESTDIR = $$PWD/../bin # 程序输出路径 +}else{ +DESTDIR = $$PWD/../bin64 # 使用64位编译器 +} + +# msvc 编译器使用utf-8编码 +msvc { +QMAKE_CFLAGS += /utf-8 +QMAKE_CXXFLAGS += /utf-8 +} diff --git a/QSqlDemo/TableModel2/main.cpp b/QSqlDemo/TableModel2/main.cpp new file mode 100644 index 0000000000000000000000000000000000000000..b0a4ec26478f6b9aba3e1747ec464ea0c26dd5b9 --- /dev/null +++ b/QSqlDemo/TableModel2/main.cpp @@ -0,0 +1,11 @@ +#include "widget.h" + +#include + +int main(int argc, char *argv[]) +{ + QApplication a(argc, argv); + Widget w; + w.show(); + return a.exec(); +} diff --git a/QSqlDemo/TableModel2/widget.cpp b/QSqlDemo/TableModel2/widget.cpp new file mode 100644 index 0000000000000000000000000000000000000000..1f2e93de54abe24703679c492a6edcecf59d2461 --- /dev/null +++ b/QSqlDemo/TableModel2/widget.cpp @@ -0,0 +1,126 @@ +#include "widget.h" +#include "ui_widget.h" + +#include +#include +#include + +Widget::Widget(QWidget *parent) + : QWidget(parent) + , ui(new Ui::Widget) +{ + ui->setupUi(this); + this->setWindowTitle(QString("QSql-使用QSqlTableModel显示数据库内容Demo2 - V%1").arg(APP_VERSION)); +} + +Widget::~Widget() +{ + delete ui; +} + + +void Widget::on_but_connect_clicked() +{ + if(ui->but_connect->text() == "关闭数据库") + { + ui->but_connect->setText("连接数据库"); + + m_db.close(); + + } + else + { + + m_db = QSqlDatabase::addDatabase("QSQLITE"); // 使用数据库驱动(Qsqlite)和默认连接名称(qt_sql_default_connection)添加一个数据库 + qDebug() << QSqlDatabase::defaultConnection; // 打印默认数据库连接名称 + #if 1 + m_db.setDatabaseName("tableModel2.db"); // 使用文件数据库(可生成数据库文件,数据一直有效) + #else + m_db.setDatabaseName(":memory:"); // 使用内存数据库(不会生成数据库文件,所有数据都在内存中进行操作,性能强,程序退出后数据丢失) + #endif + + if(!m_db.open()) // 打开数据库 + { + QMessageBox::critical(nullptr, "Error", "打开数据库失败!"); + return ; + } + + // 如果表不存在则创建表 + if(!isTableExists("person")) + { + QSqlQuery query; + + // 创建一个表person,包含id、firstname、lastname三个字段 + bool ret = query.exec("create table person (" + "id integer primary key," // 索引(自增key),使用integer默认为自增, int不能设置主键自增 + "firstname varchar(20)," // 名 + "lastname varchar(20))"); // 姓 + if(!ret) + { + qDebug() << "创建表失败:"; + } + } + + initModel(); + + ui->but_connect->setText("关闭数据库"); + } +} + +/** + * @brief 判断表是否存在 + * @param table 表名称 + * @return true存在 false不存在 + */ +bool Widget::isTableExists(const QString &table) +{ + QSqlQuery query; + QString sql = QString("select * from sqlite_master where name = '%1';").arg(table); // 查询sqlite_master表中是否存在表名 + if(query.exec(sql)) + { + return query.next(); + } + return false; +} + +/** + * @brief SQL 表模型(QSqlTableModel)来编辑数据库中的信息 + */ +void Widget::initModel() +{ + if(m_model) + { + m_model->clear(); + delete m_model; + m_model = nullptr; + } + m_model = new QSqlTableModel(this, m_db); + m_model->setTable("person"); // 设置需要显示的数据库表 +#if 1 + m_model->setEditStrategy(QSqlTableModel::OnFieldChange); // 在界面上修改后数据立刻保存到数据库 +#else + m_model->setEditStrategy(QSqlTableModel::OnManualSubmit); // 将将编辑数据库中值的策略设置为[在调用 submitAll() 或 revertAll() 之前,所有更改都将缓存在模型中(即在界面上修改数据后不会立刻存入数据库)] +#endif + m_model->setHeaderData(0, Qt::Horizontal, "ID"); + m_model->setHeaderData(1, Qt::Horizontal, "名称"); + m_model->setHeaderData(2, Qt::Horizontal, "姓氏"); + ui->tableView->setModel(m_model); +} + +void Widget::on_but_add_clicked() +{ + QSqlQuery query; + query.prepare("insert into person(firstname, lastname)" // 写入数据时不需写入id字段,实现自增 + "values (:firstname, :lastname)"); + query.bindValue(":firstname", ""); + query.bindValue(":lastname", ""); + query.exec(); + m_model->select(); // 获取数据库中的数据 +} + +void Widget::on_but_read_clicked() +{ + if(!m_model) return; + m_model->select(); // 获取数据库中的数据 + ui->tableView->resizeColumnsToContents(); // 根据表格中的内容自动调整列宽 +} diff --git a/QSqlDemo/TableModel2/widget.h b/QSqlDemo/TableModel2/widget.h new file mode 100644 index 0000000000000000000000000000000000000000..20dcf60f6e9ca0296fea0f1506e8a5e1a21f47d5 --- /dev/null +++ b/QSqlDemo/TableModel2/widget.h @@ -0,0 +1,34 @@ +#ifndef WIDGET_H +#define WIDGET_H + +#include +#include +#include + +QT_BEGIN_NAMESPACE +namespace Ui { class Widget; } +QT_END_NAMESPACE + +class Widget : public QWidget +{ + Q_OBJECT + +public: + Widget(QWidget *parent = nullptr); + ~Widget(); + +private slots: + void initModel(); + bool isTableExists(const QString& table); + void on_but_connect_clicked(); + + void on_but_add_clicked(); + + void on_but_read_clicked(); + +private: + Ui::Widget *ui; + QSqlTableModel* m_model = nullptr; // 创建一个 单个数据库表的可编辑数据模型 + QSqlDatabase m_db; +}; +#endif // WIDGET_H diff --git a/QSqlDemo/TableModel2/widget.ui b/QSqlDemo/TableModel2/widget.ui new file mode 100644 index 0000000000000000000000000000000000000000..9e9fb3c3dea1ba4f6af8aaa208729dcc1bcc66d2 --- /dev/null +++ b/QSqlDemo/TableModel2/widget.ui @@ -0,0 +1,45 @@ + + + Widget + + + + 0 + 0 + 522 + 402 + + + + Widget + + + + + + + + + 连接数据库 + + + + + + + 新增数据行 + + + + + + + 读取数据 + + + + + + + +