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
+
+
+ -
+
+
+ -
+
+
+ 连接数据库
+
+
+
+ -
+
+
+ 新增数据行
+
+
+
+ -
+
+
+ 读取数据
+
+
+
+
+
+
+
+