湖南火电建设有限公司网站,下载应用市场软件,wordpress nickname,营销方案网站在上面的例子中#xff0c; MyClass 有一个名为mySignal 的信号#xff0c;它带有一个整型参数。 定义槽#xff1a;槽可以是任何普通的成员函数#xff0c;但通常在类定义中用slots 关键字标识。槽可以有返回类型#xff0c;也可以接受参数#xff0c;但它们的参数类型需… 在上面的例子中 MyClass 有一个名为mySignal 的信号它带有一个整型参数。 定义槽槽可以是任何普通的成员函数但通常在类定义中用slots 关键字标识。槽可以有返回类型也可以接受参数但它们的参数类型需要与发出信号的参数类型匹配。例如 在这个例子中我们定义了一个名为mySlot 的槽它接收一个整型参数。 连接信号与槽使用QObject::connect 函数将信号与槽连接起来。当信号被发射时连接到这个信号的槽将被调用。 这行代码连接了myObject 的mySignal 信号到同一个对象的mySlot 槽。 发射信号使用emit 关键字发射信号。当信号被发射时所有连接到这个信号的槽都会被调用。 这将触发所有连接到mySignal 的槽。 自定义信号和槽是Qt编程中非常强大的特性它们使得组件之间的通信变得灵活而松耦合。通过信和槽可以方便地实现各种复杂的事件驱动逻//辑。 QDebug() 是 Qt 框架中用于输出调试信息的一个类。它提供了一种方便的方式来输出文本到标准输出通常是控制台这对于调试 Qt 应用程序非常有用。 QDebug 类可以与 Qt 的信号和槽机制一起使用使得在响应各种事件时能够输出有用的调试信息。 使用 的一个典型方式是通过作符 来输出各种数据类型。例如 函数它返回一个 对象。然后可以使用流操 当执行这些代码时它们会在应用程序的控制台输出相应的文本。这对于检查程序的运行状态、变量的值或者跟踪程序的执行流程非常有帮助。 还可以使用 qDebug() 来输出自定义类型只要为这些类型提供了适当的输出操作符重载。此外Qt 还 提供了 qInfo() , qWarning() , 和 函数用于输出不同级别的信息分别用 于普通信息、警告、关键错误和致命错误。这有助于对日志信息进行级别划分从而更好地控制输出内容。 文件操作类 QFile 是 Qt 框架中用于文件处理的一个类。它提供了读取和写入文件的功能支持文本和二进制文 件。 继承自 QIODevice 因此它可以像其他IO设备一样使用。 主要功能 文件读写 QFile 支持打开文件进行读取或写入操作文件信息可以检索有关文件的信息如大小、修改日期等。文件操作提供了对文件进行重命名、移动、删除等操作的能力。 错误处理 QFile 在操作文件时提供了错误处理机制可以通过相应的函数检查和获取错误信息。 常用方法 open() 打开一个文件。需要指定模式如只读、只写、读写等。 close() 关闭文件。 和 write() 用于读取和写入数据。 exists() 检查文件是否存在。 remove() 删除文件。 copy() 复制文件。 示例代码 以下是使用 的一个简单例子 Widget::Widget(QWidget *parent) : QWidget(parent) , ui(new Ui::Widget) { ui-setupUi(this); } Widget::~Widget() { delete ui; } void Widget::on_btnRead_clicked() { //1. 打开文件 //QFile file(D:/QT/test.txt); QFile file; file.setFileName(D:/QT/test.txt); if(!file.open(QIODevice::ReadOnly | QIODevice::Text)){ qDebug() file open error; } //2. 读取文件 char context[100] {\0}; if( file.read(context,100) -1) return; //3. 输出文件内容 qDebug() context; file.close(); } void Widget::on_btnWrite_clicked() { // 1.打开 QFile file(D:/QT/test2.txt); file.open(QIODevice::WriteOnly | QIODevice::Text); // 2. 写入 file.write(Program 45-QFile001 write something to This File 我是老陈); // 3. 关闭 file.close(); } 3.3.3 QTextStream 的主要特性成一个表格。请看下表 特性类别 说明 字符编码 支持 Unicode可以处理如 UTF-8、UTF-16 等不同编码。通过 setCodec() 方法设置特定编码。 读写文本 用于读写文件、字符串或任何继承自 QIODevice 的对象。 格式化 提供文本格式化功能如数字精度、基数十进制、十六进制等调整。 流操作符 支持使用 和 操作符类似于 C 中的 iostream。 特性类别 说明 换行处理 自动处理不同操作系统间的换行符差异如 Unix 的 \n 和 Windows 的 \r\n 。 错误处理 能够检测和报告在读写过程中出现的错误。 缓冲机制 提供缓冲机制提高读写效率。 字符串操作 可以方便地处理和解析字符串数据。 是一个功能强大的类用于处理文本数据特别是在需要考虑字符编码和文本格式化的情况下。通过这些特性它提供了一种灵活而强大的方式来读写和操作文本。 使用示例 以下是一个更详细的示例展示了如何使用 来读写文件 文件选择对话框 QFileDialog QFileDialog开发流程 使用 的基本步骤通常如下 实例化首先创建一个 对象的实例。 设置模式根据需要设置对话框的模式如打开文件、保存文件等。 设置过滤器如果需要可以设置文件类型过滤器以限制用户可以选择的文件类型。 显示对话框通过调用 方法显示对话框并在用户作出选择后执行相应的操作。 通过 这是使用 方法获取用户选择的文件路径列表然后对这些文件进行相应的处理。 的基本模式。Qt 也允许使用静态方法直接创建和显示对话框例如 QFileDialog::getOpenFileName() 这些方法更简单但提供的自定义选项较少。 QFileDialog 打开开发案例 QFileDialog 保存开发案例 实现文件打开功能 开发流程 为QPushButton对应Open的控件设置槽函数槽函数代码开发 打开文件 读取文件 把文件数据显示在TextEdit控件上 代码实现 打开功能优化 字符编码相关问题解决 在 Qt 中 QTextStream 常用的字符编码主要包括以下几种 编码名称 描述 UTF-8 用于表示 Unicode 文本的变长字符编码广泛用于网络和多语言文本 UTF-16 用于表示 Unicode 文本的定长字符编码 ISO 8859-1 也称为 Latin1用于表示西欧语言字符 GBK 用于表示简体中文字符是 GB2312 的扩展 Big5 用于表示繁体中文字符常用于台湾和香港地区 Windows- 1252 用于表示西欧语言字符是 ISO 8859-1 的超集 ANSI 在 Qt 中ANSI 编码并不是一个明确指定的编码标准因为 ANSI 编码可以指代不同的编码标准这取决于操作系统的语言和区域设置。例如在中文 Windows系统中ANSI 编码通常指的是 GBK 编码而在西欧语言的 Windows 系统中 ANSI 编码可能指的是 ISO 8859-1 或 Windows-1252。 这些编码覆盖了大部分常用的语言字符集可以通过中进行设置。 方法在 检测光标位置并在右下角显示光标位置在程序左上方显示当前打开的文件名称 QComboBox 是 Qt 框架中用于创建下拉列表的一个控件。 它允许用户从一组选项中选择一个选项并可以配置为可编辑使用户能够在其中输入文本。 提供了一系列方法来添加、删除和修改列表中的项支持通过索引或文本检索项并可以通过信号和槽机制来响应用户的选择变化。该 控件广泛应用于需要从多个选项中进行选择的用户界面场景例如表单和设置界面。 功能 描述 API 方法 添加选项 向下拉列表添加单个或多个选项 addItem() , addItems() 获取选项 获取当前选中的文本或索引 currentText() , currentIndex() 设置选项 设置当前选中的项 setCurrentIndex(int) 移除选项 从下拉列表中移除项 removeItem(int) 信号 当选项改变时触发的事件 currentIndexChanged(int) 可编辑性 设置下拉列表是否可编辑 setEditable(bool) 自定义数据 向下拉列表项关联额外的数据 setItemData(int, const QVariant) 清空列表 移除所有选项 clear() 示例代码 这个示例展示了 需要调整和扩展这个示例。 的基本用法包括添加选项、设置为可编辑以及连接信号和槽。您可以根据 记事本支持字符编码 获取用户在QComboBox上选择的字符编码用特定编码打开文件这里注意QComboBox返回QString类型 setCodec参数要求const char*型 QString先转成C的String再转换成const char * 支持打开文件后进行字符编码的重新选择和显示加载 添加行列显示 使用QTextEdit的cursorPositionChanged信号当光标发生移动时候刷新显示 添加文件打开提示 设置当前行高亮 实现策略 获取当前行的光标位置使用的信号和获取行列值是一样的通过ExtraSelection来配置相关属性 在当前行设置该属性 实现该功能需要用到一个API QList 在 Qt 框架中 QList 是一个容器类它在内部实现上类似于一个数组但也提供了一些链表的特性。的设计旨在提供一个在多数情况下既高效又方便的通用列表容器。用于存储元素列表。它提供了 丰富的功能包括添加、移除、访问元素等。 QList 的内部工作原理 数组式存储 QList 在大多数情况下使用连续内存存储其元素类似于数组。这意味着它提供了快速的索引访问通过下标操作符 [] 以及相对高效的迭代性能。 动态调整大小与静态数组不同 QList 可以动态增长和缩减自动管理内存分配。 链表特性虽然 主要基于数组但它也提供了一些链表的操作比如在列表的开始或结束 处添加和移除元素。这些操作通常比在数组中间插入或删除元素更高效。 复制时共享内存 QList 使用一种称为“隐式共享”implicit sharing或“写时复制”copy-on- write的技术。这意味着当你复制一个 时它不会立即复制所有元素而是共享相同的数 据直到你尝试修改其中一个列表此时才进行实际的复制。这使得复制 使用场景 变得非常高效。 当你需要快速的随机访问如通过索引访问元素时 QList 是一个不错的选择。如果你的主要操作是在列表的两端添加或移除元素 QList 也表现得很好。 基本用法 包含头文件首先你需要包含 的头文件。 创建 QList 实例创建一个 对象并指定存储的元素类型。 添加元素使用 或 方法添加元素。 访问元素可以使用下标操作符或 方法访问元素。 遍历列表使用迭代器或范围基的 for 循环遍历列表。 移除元素使用 removeAt 、 removeOne 或 方法移除元素。 3.8.2 ExtraSelection 简介 是一个在 中用来表示额外的文本选择和高亮的结构。 如何工作 ExtraSelection 结构体 QTextEdit::ExtraSelection 是一个结构体包含了两个主要成员和 QTextCharFormat 。 QTextCursor 表示在文本中的一个位置或者区间而 用于定义这个区间的格式比如背景颜色、字体等。 设置 ExtraSelection你可以创建一个或多个 对象为它们设置相应的光标位 置和格式然后通过 的 方法将这些对象应用到文本编辑器中。 这样你可以对文本的特定部分应用特定的格式而不影响其他文本。 高亮当前行要高亮显示当前行你需要在 信号的槽函数中创建一个 对象。使用当前的 对象通过 方法获取来确 定当前行的位置并设置背景颜色为你选择的高亮颜色。 类是 Qt 框架中的一部分用于描述文本字符的格式。这个类提供了丰富的接口来设置和获取文本字符的各种属性如字体、颜色、背景色等。 QTextCharFormat 通常用于富文本处理可 以在像 和 下面列出了 这样的类中使用 的一些常用功能和方法 设置和获取字体样式 使用 方法设置字体。 通过 方法获取当前字体。 设置字体属性 setFontWeight() : 设置字体的粗细。 setFontItalic() : 设置字体是否倾斜。 setFontUnderline() : 设置是否有下划线。 设置文本颜色和背景色 setForeground() : 设置文本的前景色即字体颜色。 setBackground() : 设置文本的背景色。 其他文本属性 setToolTip() : 设置文本的工具提示。 setAnchor() : 设置文本是否为超链接。 setAnchorHref() : 设置超链接的目标 URL。 示例代码 下面是一个简单的示例展示如何在 中使用 来设置特定文本的格式 文件保存功能优化 开发流程 判断当下是否有已经打开的文件如果有打开的文件读取TextEdit的内容 写入新文件 关闭优化 在上节课中关闭部分稍微优化了以下但是还是不够, 我们应该弹出窗口多一个询问 消息对话框 QMessageBox 是 Qt 框架中用于显示消息框的一个类它常用于向用户显示信息、询问问题或者报告错 误。以下是 的一些主要用途 显示信息向用户显示一些信息性的消息。询问用户决策询问用户一个问题并根据其回答做出相应的操作。报告错误向用户报告程序运行中的错误。代码示例 以下是一个简单的 使用示例展示了如何创建一个基本的消息框 在这个例子中我们创建了一个 对象并设置了窗口标题、主要文本、附加信息文本和 图标。还添加了两个按钮OK 和 Cancel并设置了默认按钮。通过 据用户的选择执行不同的操作。 方法显示消息框并根 由于 是为标准对话框设计的其定制能力有限但你可以通过添加自定义按钮来实现一 定程度的定制。例如如果你想要添加一个自定义的按钮可以这样做 在这个例子中通过 方法添加了一个自定义按钮。按钮的角色被设置为 QMessageBox::ActionRole 这意味着它将被放置在对话框的底部与其他标准按钮一起。通过检查用户点击的按钮来确定是否点击了自定义按钮。 3.7.3 代码实现 实现快捷键功能 快捷键开发基础 在 Qt 中实现快捷键功能通常涉及到 Qt 应用程序中为特定功能设置快捷键 类的使用。下面是一个简单的代码示例展示了如何在 在这个示例中当用户按下 Ctrl N 时程序将弹出一个消息框。这是通过创建一个 对象 并将其快捷键序列设置为 来实现的。然后将 信号连接到一个 Lambda 函数 该函数在快捷键被激活时执行。这种方法非常适用于为特定操作提供快速访问路径。 上官记事本添加快捷键 实现字体放大缩小功能 滚动调节字体大小的流程 为TextEdit添加事件过滤器重写窗口的eventFilter函数 eventFilter设置滚轮事件和目标对象实现字体放大缩小的功能函数 本节笔记失误 啥也没有嘿嘿嘿 检测Ctrl键被按下 如 Ctrl、Shift、Alt 等。当与了 Control 键。 是 Qt 中一个静态函数用于返回当前按下的键盘修饰符结合使用时这个函数可以用来检测是否按下 例如以下代码片段检查 Control 键是否被按下 这里 QGuiApplication::keyboardModifiers() 返回当前按下的修饰符而 前按下的修饰符中。 是一个枚举值表示 Control 键。使用位与运算符 检查 Control 键是否在当 记事本添加字体放大缩小 事件 事件处理过程 众所周知Qt是一个基于C的框架主要用来开发带窗口的应用程序不带窗口的也行但不是主流。我们使用的基于窗口的应用程序都是基于事件其目的主要是用来实现回调因为只有这样程序的效率才是最高的。所以在Qt框架内部为我们提供了一些列的事件处理机制当窗口事件产生之后事件会经过 事件派发 - 事件过滤-事件分发-事件处理 几个阶段。Qt窗口中对于产生的一系列事件都有默认的处理动作如果我们有特殊需求就需要在合适的阶段重写事件的处理动作比如信号与槽就是一种 事件event是由系统或者 Qt 本身在不同的场景下发出的。当用户按下/移动鼠标、敲下键盘或者是窗口关闭/大小发生变化/隐藏或显示都会发出一个相应的事件。一些事件在对用户操作做出响应时发出如鼠标/键盘事件等另一些事件则是由系统自动发出如计时器事件。 每一个Qt应用程序都对应一个唯一的 QApplication 应用程序对象然后调用这个对象的exec() 函数这样Qt框架内部的事件检测就开始了 程序将进入事件循环来监听应用程序的事件 。 事件在Qt中产生之后的分发过程是这样的 当事件产生之后Qt使用用应用程序对象调用 notify() 函数将事件发送到指定的窗口 事件在发送过程中可以通过事件过滤器进行过滤默认不对任何产生的事件进行过滤。 当事件发送到指定窗口之后窗口的事件分发器会对收到的事件进行分类: 事件分发器会将分类之后的事件鼠标事件、键盘事件、绘图事件。。。分发给对应的事件处理器函数进行处理每个事件处理器函数都有默认的处理动作我们也可以重写这些事件处理器函 数比如鼠标事件 重写事件案例 程序关闭之前的询问鼠标进入鼠标离开窗口大小改变 #include widget.h #include ui_widget.h #include QDebug #include QMessageBox #include QWheelEvent Widget::Widget(QWidget *parent) : QWidget(parent) , ui(new Ui::Widget) { ui-setupUi(this); } Widget::~Widget() { delete ui; } void Widget::enterEvent(QEvent *event) { qDebug() mouse enter; } void Widget::leaveEvent(QEvent *event) { qDebug() mouse leave; } void Widget::wheelEvent(QWheelEvent *event) { qDebug() event-angleDelta(); } void Widget::closeEvent(QCloseEvent *event) { int ret QMessageBox::warning(this, tr(My Application), tr(close the window\n Do you want to close the window?), QMessageBox::Ok | QMessageBox::No ); switch(ret){ case QMessageBox::Ok: event-accept(); break; case QMessageBox::No: event-ignore(); break; } } void Widget::resizeEvent(QResizeEvent *event) { qDebug() oldSize: event-oldSize() newSize: event-size(); 自定义按键 mybutton.h mybutton.cpp widget.cpp 事件方式实现字体放大缩小 自定义控件MyTextEdit头文件 实现文件 事件过滤器 我们通过继承QTextEdit来重写事件实现Ctrl加滚轮的检测还有一种处理方式叫做事件过滤器 在Qt的事件处理过程中引入事件过滤器Event Filter可以让你在事件达到目标对象之前进行拦截和处理。这是一种强大的机制允许你在不同对象间共享事件处理逻辑或在父对象中集中处理特定事件。下面是加入事件过滤器的步骤 定义事件过滤器: 事件过滤器通常是一个重写了QObject::eventFilter() 方法的对象。这个方法会在事件传递给目标对象之前被调用。 安装事件过滤器: 使用QObject::installEventFilter() 方法安装事件过滤器。这个方法告诉Qt在将事件发送给特定对象之前先通过过滤器对象。例如如果你想在父窗口中过滤子窗口的事件你需要在父窗口的对象上调用installEventFilter() 并将子窗口作为参数传递。 事件过滤器逻辑: 在eventFilter() 方法内部你可以编写自定义逻辑来决定如何处理或忽略事件。如果此方法返回true 则表示事件已被处理不应该继续传递如果返回false 则事件将正常传递给目标对象。事件分发: 当事件发生时Qt首先将事件发送到安装了事件过滤器的对象。在这一步 eventFilter() 方法被调用。 决定是否传递事件: 根据eventFilter() 方法的返回值Qt决定是否继续向目标对象传递事件。如果过滤器返回true 事件处理到此结束如果返回false 事件继续传递到原始目标对象。目标对象处理事件: 如果事件过滤器允许事件继续传递目标对象将像没有事件过滤器存在时那样处理事件。 事件过滤器特别适用于以下情况 当你想在不修改子类代码的情况下改变事件的行为。当多个对象需要共享相同的事件处理逻辑。 当你需要在更高的层级上监控或修改应用程序的事件流。 通过使用事件过滤器Qt应用程序可以获得更大的灵活性和更细粒度的事件处理控制。 鼠标滚轮和字体大小 在 C 中强制类型转换或类型转换是一种将变量从一种类型转换为另一种类型的方法。C 提供了四种强制转换运算符每种都有其特定的用途和适用场景 static_cast 是最常用的类型转换运算符用于无风险的转换如整数到浮点数字符到整 数等。 它在编译时执行不执行运行时类型检查RTTI。 示例 int x static_castint(y); 其中 dynamic_cast 可能是 float 类型。 专门用于处理对象的多态性只能用于指针和引用且涉及对象类必须有虚函数。 它在运行时检查类型的安全性如果转换失败对于指针类型返回 nullptr 对于引用类型抛出异常。 示例 Derived *dp dynamic_castDerived *(bp); 其中是派生类。 const_cast 用于修改类型的 const 或 volatile 属性。 是基类指针 Derived 通常用于去除对象的 const 性质允许修改原本被声明为 const 的变量。示例 const int a 10; int* b const_castint*(a); reinterpret_cast 用于进行低级别的重新解释转换几乎无限制但也是最危险的。 它可以将一种完全不相关的类型转换为另一种类型比如将指针类型转换为整数类型。 示例 long p reinterpret_castlong(object); 其中 是某个类的对象。 3.12 记事本项目总结 类别 功能 描述 UI设计师基本控件操作 Widget 基础的用户界面单元用于构建复杂的用户界面。 QPushButton 用于创建按钮。 QHBoxLayout 水平布局管理器用于水平排列控件。 QVBoxLayout 垂直布局管理器用于垂直排列控件。 TextEdit 多行文本编辑器控件。 Stylesheet 使用样式表来定制控件的外观。 文件操作类 QFile 用于读取和写入文件。 文件选择对话框类 QFileDialog 提供了一个对话框允许用户选择文件或目录。 QT的信号与槽 - 用于对象之间的通信机制。 消息对话框 QMessageBox 用于显示信息、警告、错误等对话框。 快捷键捕获和处理 - 用于捕获和处理键盘快捷键。 Ctrl按键信号捕获和处理 - 专门处理Ctrl按键的信号。 鼠标滚轮信号捕获和处理 - 用于捕获和处理鼠标滚轮动作。 事件处理 event 用于处理不同的事件。 文本字符编码检测 - 用于检测和处理文本的字符编码。 类别 功能 描述 字体放大缩小 - 用于调整字体大小。 QT程序开发流程 - 涉及从设计到部署的整个开发流程。 P4 串口调试助手项目 项目概述 项目功能描述 见下方界面所见即所得 串口通信核心代码开发 代码会放在网盘上 全程高能力输出-代码开发和调试都在视频里 P5 网络调试助手 TCP网络调试助手 项目概述 网络相关的一些基础概念-面试用学习QTcpServer 学习QTcpClient 学习TextEdit特定位置输入文字颜色学习网络通信相关知识点 复习巩固之前 UI 控件 程序运行如下图所 示 开发流程 QTtcp服务器的关键流程 工程建立需要在.pro加入网络权限 创建一个基于 创建并初始化 的服务端涉及以下关键步骤 实例 实例化 QTcpServer 。 调用 处理新连接为 方法在特定端口监听传入的连接。 信号连接一个槽函数。 在槽函数中使用 读取和发送数据 获取 以与客户端通信。 通过连接使用 关闭连接 的 方法发送数据回客户端。 信号来读取来自客户端的数据。 在适当的时候关闭 QTcpSocket 。示例代码可能如下 确保在使用 和 时妥善处理网络错误和异常情况。 QTtcp客户端的关键流程 工程建立需要在.pro加入网络权限 创建一个基于 创建 的Qt客户端涉及以下步骤 实例 实例化 QTcpSocket 。 连接到服务器 使用 发送数据到服务器 方法连接到服务器的IP地址和端口。 使用 方法发送数据。 接收来自服务器的数据 为 关闭连接 信号连接一个槽函数来接收数据。 关闭示例代码如下 连接。 这个客户端尝试连接到指定的服务器地址和端口然后等待和处理来自服务器的数据。记得根据需要管理和处理网络错误和异常情况。 5.1.2 TCP协议 以下内容自省阅读和消化主要在面试之前类似八股文问答实际编程我们不需要关系这么多 QTcpSocket类底下的API已经做好所有的封装。 TCP传输控制协议是一种广泛使用的网络通信协议设计用于在网络中的计算机之间可靠地传输数据。它是互联网协议套件的核心部分通常与IP互联网协议一起使用合称为TCP/IP。以下是TCP协议的一些基本特点 面向连接在数据传输之前TCP 需要在发送方和接收方之间建立一个连接。这包括三次握手过程确保两端都准备好进行数据传输。可靠传输TCP 提供可靠的数据传输服务这意味着它保证数据包准确无误地到达目的地。如果发生数据丢失或错误TCP 会重新发送数据包。顺序控制TCP 保证数据包的传输顺序。即使数据包在网络中的传输顺序被打乱接收方也能按照正确的顺序重组这些数据。流量控制TCP 使用窗口机制来控制发送方的数据传输速率以防止网络过载。这有助于防止接收方被发送方发送的数据所淹没。拥塞控制TCP 还包括拥塞控制机制用来检测并防止网络拥塞。当网络拥塞发生时TCP 会减少其数据传输速率。数据分段大块的数据在发送前会被分割成更小的段以便于传输。这些段会被独立发送并在接收端重新组装。确认和重传接收方对成功接收的数据包发送确认ACK信号。如果发送方没有收到确认它会重传丢失的数据包。终止连接数据传输完成后TCP 连接需要被正常关闭这通常涉及到四次挥手过程。 TCP 适用于需要高可靠性的应用如网页浏览、文件传输、电子邮件等。然而由于它的这些特性TCP在处理速度上可能不如其他协议如UDP那么快速。 TCP协议中的三次握手和四次挥手是建立和终止连接的重要过程。下面是它们的简要描述 三次握手建立连接 三次握手的主要目的是在两台设备之间建立一个可靠的连接。它包括以下步骤 SYN客户端向服务器发送一个SYN同步序列编号报文来开始一个新的连接。此时客户端进入SYN-SENT状态。SYN-ACK服务器接收到SYN报文后回复一个SYN-ACK同步和确认报文。此时服务器进入 SYN-RECEIVED状态。 ACK客户端接收到SYN-ACK后发送一个ACK确认报文作为回应并进入ESTABLISHED已建立状态。服务器在收到这个ACK报文后也进入ESTABLISHED状态。这标志着连接已经建立。 四次挥手断开连接 四次挥手的目的是终止已经建立的连接。这个过程包括以下步骤 FIN当通信的一方完成数据发送任务后它会发送一个FIN结束报文来关闭连接。发送完FIN 报文后该方进入FIN-WAIT-1状态。 ACK另一方接收到FIN报文后发送一个ACK报文作为回应并进入CLOSE-WAIT状态。发送FIN 报文的一方在收到ACK后进入FIN-WAIT-2状态。 FIN在等待一段时间并完成所有数据的发送后CLOSE-WAIT状态的一方也发送一个FIN报文来请求关闭连接。ACK最初发送FIN报文的一方在收到这个FIN报文后发送一个ACK报文作为最后的确认并进入 TIME-WAIT状态。经过一段时间后确保对方接收到了最后的ACK报文该方最终关闭连接。 在这两个过程中三次握手主要确保双方都准备好进行通信而四次挥手则确保双方都已经完成通信并同意关闭连接。 5.1.4 Socket Socket 不是一个协议而是一种编程接口API或机制用于在网络中实现通信。Socket 通常在应用层和传输层之间提供一个端点使得应用程序可以通过网络发送和接收数据。它支持多种协议主要是 TCP 和 UDP。 以下是 Socket 的一些基本特点 类型有两种主要类型的 Sockets —— TCP Socket面向连接可靠和 UDP Socket无连接不可靠。 应用在各种网络应用中广泛使用如网页服务器、聊天应用、在线游戏等。 编程语言支持大多数现代编程语言如 Python, Java, C, 等都提供 Socket 编程的支持。 功能提供了创建网络连接、监听传入的连接、发送和接收数据等功能。 QT: 在QT组件中QTcpSocket用来管理和实现TCP Socket通信QUdpSocket用来管理和实现 UDP Socket通信 总之Socket 是实现网络通信的基础工具之一它抽象化了网络层的复杂性为开发者提供了一种相对简单的方式来建立和管理网络连接。 UI设计 UI设计过程教学视频展示都是大家熟悉的内容了 网络通信核心代码 是 Qt 网络模块的一部分用于构建 TCP 服务器。它提供了一种机制来异步监听来自客户端的连接。一旦接受了一个连接服务器就可以与客户端进行数据交换。 创建TCP服务端的核心代码 主要步骤如下 创建 实例启动服务器并开始监听指定端口。 监听连接请求调用 方法使服务器监听特定的 IP 地址和端口。 接受连接当客户端尝试连接时 QTcpServer 产生一个信号。你需要实现一个槽slot来响应这个信号并接受连接。 处理客户端连接每个连接的客户端都关联一个示例代码 对象用于数据交换。 代码解释 创建监听端口使用 对象在主函数中直接创建了一个 方法监听所有接口上的 12345 端口。 对象。 处理新连接通过连接 信号当有新客户端连接时会调用相应的槽函数。 读取数据为每个连接的客户端创建发送数据向客户端发送响应消息。 对象并连接 信号以接收数据。 客户端断开连接时的处理使用 这个代码示例展示了如何使用 信号确保客户端在断开连接时被适当地清理。 创建一个基本的 TCP 服务器而无需通过继承来扩展类。这 种方式通常更简单适用于不需要复杂处理的基本应用场景。 创建TCP客户端的核心代码 为了使客户端代码更具模块化和响应性可以使用 Qt 的信号与槽机制。这种方法允许客户端以事件驱动的方式响应网络事件如连接建立、数据接收等。下面是一个使用信号与槽的 TCP 客户端示例。 示例代码 代码解释 创建 类这个类继承自 QObject 允许使用信号与槽机制。 连接信号和槽在构造函数中将 的 和 信号分别连接到 和 连接到服务器使用 槽。 方法开始连接过程。 处理连接建立一旦连接建立 onConnected 槽被触发客户端向服务器发送一条消息。 接收数据当数据可读时 onReadyRead 槽被触发客户端读取并打印来自服务器的数据。断开连接在接收数据后客户端断开与服务器的连接。 这个客户端示例展示了如何使用 Qt 的信号与槽机制来处理 TCP 连接。这种方式使得代码更加清晰易于维护并且能更好地处理异步事件。 TCP服务端项目开发 核心代码 for (const QNetworkInterface interface : interfaces) { for (const QNetworkAddressEntry entry : interface.addressEntries()) { if (entry.ip().protocol() QAbstractSocket::IPv4Protocol) { ui-comboBoxIpAddr-addItem(entry.ip().toString()); } } } } // 主窗口析构函数 MainWindow::~MainWindow() { // 释放用户界面资源 delete ui; } // “开始监听”按钮的点击事件处理函数 void MainWindow::on_pushButtonListen_clicked() { // 侦听指定 IP 地址和端口 tcpServer-listen(QHostAddress(ui-comboBoxIpAddr-currentText()), ui-lineEditPort-text().toInt()); // 更新按钮状态 ui-pushButtonListen-setEnabled(false); ui-pushButtonListenStop-setEnabled(true); } // 新 TCP 连接的处理函数 void MainWindow::mnewConnectionHandler() { // 获取下一个待处理的连接 QTcpSocket *tmpSocket tcpServer-nextPendingConnection(); // 向文本浏览器中添加客户端信息 ui-textBrowserRev-append(服务器: 客户端IP地址是 tmpSocket- peerAddress().toString() 客户端端口号是 QString::number(tmpSocket- peerPort())\n); // 连接套接字的状态变化和数据接收信号到相应槽函数 connect(tmpSocket, SIGNAL(stateChanged(QAbstractSocket::SocketState)), this, SLOT(mstateChanged(QAbstractSocket::SocketState))); connect(tmpSocket, SIGNAL(readyRead()), this, SLOT(mreadData())); } // 套接字状态改变时的槽函数 void MainWindow::mstateChanged(QAbstractSocket::SocketState state) { // 获取发送信号的套接字对象 QTcpSocket *tmp (QTcpSocket *)sender(); // 根据套接字的不同状态进行不同处理 switch(state){ case QAbstractSocket::UnconnectedState: // 客户端断开连接 ui-textBrowserRev-append(服务器有客户端断开连接); tmp-deleteLater(); break; case QAbstractSocket::ConnectedState: // 客户端连接 ui-textBrowserRev-append(服务器有新客户端接入); break; default: break; } } // “停止监听”按钮的点击事件处理函数 void MainWindow::on_pushButtonListenStop_clicked() { // 更新按钮状态 ui-pushButtonListen-setEnabled(true); ui-pushButtonListenStop-setEnabled(true); // 停止监听端口 tcpServer-close(); } // 接收到数据时的槽函数 void MainWindow::mreadData() { // 获取发送信号的套接字对象 QTcpSocket *tmp (QTcpSocket *)sender(); setTextColor(0,0,0); // 设置文本颜色为红色 cursor.insertText(客户端 tmp-readAll()\n); } // “发送”按钮的点击事件处理函数 void MainWindow::on_pushButtonSend_clicked() { // 查找所有的子 QTcpSocket 对象 QListQTcpSocket* socketList tcpServer-findChildrenQTcpSocket*(); // 向每个连接的客户端发送数据 foreach(QTcpSocket *tmp, socketList){ tmp-write(ui-textEditSnd-toPlainText().toUtf8()); setTextColor(255,0,0); // 设置文本颜色为红色 cursor.insertText(服务端ui-textEditSnd- toPlainText().toUtf8()\n); }; } // 设置文本颜色的函数 void MainWindow::setTextColor(int r, int g, int b) { QTextCharFormat textFormat; textFormat.setForeground(QBrush(QColor(r, g, b))); // 根据提供的 RGB 值设置颜色 // 应用格式到光标 cursor.setCharFormat(textFormat); } TCP客户端项目开发 核心代码 #include mainwindow.h #include ui_mainwindow.h // 主窗口的构造函数 MainWindow::MainWindow(QWidget *parent) : QMainWindow(parent) , ui(new Ui::MainWindow) { ui-setupUi(this); // 设置 UI ui-centralwidget-setLayout(ui-verticalLayoutGlobal); // 设置中央小部件的布局 this-setWindowTitle(网络调试助手客户端-上官QT案例); // 设置窗口标题 ui-pushButtonDiscon-setEnabled(false); // 初始时禁用断开连接按钮 cursor ui-textBrowser-textCursor(); // 获取文本浏览器的文本光标 tcpSocket new QTcpSocket(this); // 创建一个新的 QTcpSocket connect(tcpSocket, SIGNAL(readyRead()), this, SLOT(mreadDataFromServer())); // 连接信号与槽 } // 析构函数 MainWindow::~MainWindow() { delete ui; // 删除 UI } // 当点击发送按钮时调用 void MainWindow::on_pushButtonSend_clicked() { tcpSocket-write(ui-textEditSend-toPlainText().toUtf8()); // 将文本编辑器中的文本发送到服务器 setTextColor(255,0,0); // 设置文本颜色为红色 cursor.insertText(客户端 ui-textEditSend-toPlainText().toUtf8()\n); // 在文本浏览器中插入红色文本 } // 从服务器读取数据 void MainWindow::mreadDataFromServer() { setTextColor(0,0,0); // 设置文本颜色为黑色 cursor.insertText(服务端 tcpSocket-readAll()\n); // 在文本浏览器中插入黑色文本 } // 当点击断开连接按钮时调用 void MainWindow::on_pushButtonDiscon_clicked() { tcpSocket-close(); // 关闭套接字连接 // 更新 UI 状态 项目总结 TCPServer类关于监听连接发送接受的API TCPServer在网络通信中常用的信号 TCPScoket在QT实现Socket常用的API TCPScoket在QT实现Socket常用的信号 EditText的内容读取方法内容写入方法在特定行写入特点颜色的方法 TCPServer 、 TCPScoket 和 的信息整合到一个表格中 类别 功能 API/方法 描述 TCPServer 监听 bool listen(const QHostAddress address, quint16 port) 在指定的 IP 地址和端口上开始监听传入的连接。 连接 void close() 停止服务器监听传入的连接。 类别 功能 API/方法 描述 QTcpSocket *nextPendingConnection() 返回下一个待处理连接的 QTcpSocket 指针。 TCPServer 信号 newConnection() 当有新连接时发出。 TCPScoket 连接 void connectToHost(const QString host, quint16 port) 连接到指定的主机和端口。 发送 qint64 write(const QByteArray data) 向连接的套接字写入数据。 接收 QByteArray readAll() 读取可用的所有数据。 断开 void disconnectFromHost() 断开与主机的连接。 TCPScoket 信号 connected() 成功连接到主机时发出。 disconnected() 从主机断开连接时发出。 readyRead() 当有可读数据时发出。 bytesWritten(qint64 bytes) 成功写入数据时发出。 EditText 读取内容 String getText() 获取 EditText 的内容。 写入内容 void setText(String text) 设置 EditText 的内容。 使用光标改变文本颜色 void changeTextColor(int start, int end, int color) 使用光标 cursor 改变 EditText 中从 start 位置到 end 位置的文本颜色为 color 。 P6 自定义控件 QPaintEvent绘图事件 是 Qt 框架中一个重要的事件类专门用于处理绘图事件。当 Qt 视图组件需要重绘自己 的一部分时就会产生 事件。这通常发生在以下几种情况 窗口第一次显示时当窗口或控件第一次出现在屏幕上时系统会生成一个通知窗口进行自身的绘制。 事件 窗口大小改变时当用户改变窗口的大小时窗口的内容通常需要重新绘制以适应新的尺寸。窗口部分被遮挡后又重新显示时如果窗口被其他窗口遮挡然后又重新露出来被遮挡的部分通常需要重新绘制。 手动请求重绘通过调用 的 或 在 Qt 应用程序中通常通过重写 的例如 方法可以手动触发重绘事件。方法来处理绘制逻辑。 在 方法中您可以创建一个 对象并使用它来执行绘制操作。 QPainter 可以绘 制各种基本图形如线条、矩形、椭圆等还可以绘制文本和图像。重写 自定义绘制的标准做法。 是在 Qt 中进行 QPainter画家 概述 是 Qt 库中用于在屏幕上进行绘画的类。它提供了各种绘制功能比如画线、画图形、画文本 等。 以下是一些基本的用法示例 1. 初始化 QPainter首先您需要一个 QPaintDevice 比如一个 或 QPixmap 然后使 用它来初始化 对象。 设置画笔和画刷您可以设置画笔用于描边和画刷用于填充的颜色、样式等。 绘制图形使用 的方法来绘制线条、矩形、圆形、文本等。 结束绘制完成绘制后 QPainter 对象会在其析构函数中自动结束绘制。 请注意 QPainter 的使用依赖于 Qt 的事件循环因此通常在 的 或者类似的事 件处理函数中使用它。如果您在 Qt 应用程序中使用 QPainter 请确保您遵循 Qt 的事件驱动机制。 渐变色 线性渐变 是 Qt 框架中用于创建线性渐变的类。线性渐变是一种从一个颜色平滑过渡到另一个颜色的效果其变化沿着两个点之间的直线进行。这种渐变在图形用户界面设计中非常常见用于添加深度、立体感或动态效果。 基本用法 要使用 QLinearGradient 你需要执行以下几个基本步骤 创建 对象指定渐变的起点和终点坐标。设置颜色停靠点在渐变线上定义颜色和相应的位置。 使用渐变创建 QBrush 用中进行绘制。 示例代码 以下是一个创建和使用 对象来创建一个 QBrush 然后用它在 的示例代码 在这个例子中 QLinearGradient 创建了一个从红色到蓝色的渐变其方向是从小部件的左上角 (0, 0) 到右下角 (100, 100)。 注意事项 的颜色变化是沿着两个指定点之间的直线进行的。通过改变这些点的位置你可以控制渐变的方向和长度。 方法的第一个参数是一个介于 0.0 和 1.0 之间的浮点数表示颜色在渐变线上的位置。0.0 通常对应于起点1.0 对应于终点。 你可以设置多个颜色停靠点来创建更复杂的渐变效果。例如你可以在 0.0 处设置一种颜色在 0.5 处设置另一种颜色在 1.0 处再设置一种颜色。 使用 创建的 可以用于填充任何形状包括矩形、椭圆、多边形等。 为了获取更好的视觉效果可以启用 的抗锯齿选项 QPainter::Antialiasing 。 请注意当窗口小部件的大小发生变化时渐变的效果可能也会随之改变除非你相应地调整渐变的起点和终点坐标或使用其他方法来适应大小变化。 径向渐变 是 Qt 框架中用于创建径向渐变的类。径向渐变是一种从中心点向外部辐射的颜色渐变通常在中心点有一种颜色而向外围渐渐变化为另一种颜色。这种渐变非常适合用于模拟光源、阴影或创建圆形的立体感。 基本用法 要使用 QRadialGradient 你需要执行以下几个基本步骤 创建 对象指定渐变的中心点、半径以及焦点可选。设置颜色停靠点在径向渐变中定义颜色和对应的位置。 使用渐变创建 QBrush 利用 对象创建一个 QBrush 然后用 它在 示例代码 中进行绘制。 以下是一个创建和使用 的示例代码 在这个例子中 QRadialGradient 创建了一个从中心的黄色向外围的黑色渐变。渐变的中心和半径都设置在 (50, 50, 50)。 注意事项 方法的第一个参数是一个介于 0.0 和 1.0 之间的浮点数表示颜色在径向渐变中的位置。0.0 通常对应于中心点1.0 对应于边缘。 通过添加多个颜色停靠点你可以创建更复杂的径向渐变效果。 方法允许你设置焦点位置这是渐变颜色开始变化的点可以与中心点不同。 使用 创建的 可以用于 填充任何形状如矩形、椭圆、多边形等。为了获得更好的视觉效果可以启用 的抗锯齿选项 QPainter::Antialiasing 。 当绘制较大区域时可以通过调整渐变的半径和中心点来控制渐变效果的扩展。 非常适用于创建像按钮、指示灯或其他需要有深度感和立体感的界面元素。 圆锥形渐变 是 Qt 框架中用于创建圆锥形渐变的类。圆锥渐变是一种渐变效果其中颜色沿着圆锥的轮廓变化类似于旋转颜色轮。这种渐变以其中心点为基点颜色沿圆周分布可以创建出富有动感的视觉效果。 基本用法 要使用 QConicalGradient 你通常需要做以下几个步骤 创建 对象指定渐变的中心点和起始角度。 设置颜色停靠点为渐变添加不同的颜色和对应的位置角度。 使用渐变创建 QBrush 使用这个渐变对象来创建一个 QBrush 然后应用到图。 示例代码 中进行绘 下面是一个如何创建和使用 的简单示例 在这个例子中 QConicalGradient 被用来创建一个从红色到蓝色再回到红色的渐变。渐变的中心设置在点 (100, 100)并且从 0 度开始旋转。 注意事项 的颜色是沿着圆周分布的其中 和你可以通过添加多个颜色停靠点来创建更复杂的渐变效果。 在圆周上是相同的位置。 在使用时角度是按照顺时针方向测量的起始点0度通常在三点钟方向。 为了达到最佳的渲染效果可以启 用 的抗锯齿渲染提 示 非常适合用于创建旋转或动态效果的图形例如加载指示器、进度条或任何需要圆周颜色变化的场景。 坐标转移 在 Qt 框架中 painter.translate(rect().center()) 这行代码的作用是移动 QPainter 的坐标系统 原点到当前绘制区域即由 解释一下各个部分 返回的矩形的中心。 painter : 这是一个 QPainter 对象实例用于在 Qt 窗口或者图像上进行绘制。 translate() : 这是 QPainter 类中的一个方法用于改变坐标系统的原点。它接受一个 QPoint 或 QPointF 作为参数这个点指定了新的原点位置。 rect() : 这通常是指一个控件如 QWidget的矩形区域返回一个 QRect 或 QRectF 对象表示该控件的大小和位置。 rect().center() : 这个方法返回当前矩形即控件的区域的中心点是一个 QPoint 或 QPointF 对象。 总之 painter.translate(rect().center()) 这行代码将 QPainter 的绘图原点移动到控件的中心。这在进行中心对称绘制或者需要以控件中心为基准进行绘图时特别有用。 画雷达案例 delete ui; } void Widget::paintEvent(QPaintEvent *event) { QPainter painter(this); // 抗锯齿 painter.setRenderHint(QPainter::Antialiasing,true); // 把背景色刷成黑色 QBrush brush(Qt::black); painter.setBrush(brush); painter.drawRect(rect()); // 平移坐标轴到窗口正中间 painter.translate(rect().center()); // 最小圆的半径 int rEve height()/2/7; //800 600 600/7 int dataTmp rEve * 7; //用height()/2 导致突出上面那行代码除不尽 // 设置画笔绿色像素4 QPen pen(Qt::green,4); painter.setPen(pen); painter.setBrush(Qt::NoBrush); //不要画刷否则只能看到最外面的圈 for(int i1; i 7; i){ painter.drawEllipse(QPoint(0,0),rEve*i,rEve*i); //依次画出7个圆形 } painter.drawLine(-rEve*7,0,rEve*7,0); painter.drawLine(0,-rEve*7,0,rEve*7); //设置锥形渐变 QConicalGradient conGradient(0,0,-startAngle); conGradient.setColorAt(0,QColor(0,255,0,200)); conGradient.setColorAt(0.1,QColor(0,255,0,100)); conGradient.setColorAt(0.2,QColor(0,255,0,0)); conGradient.setColorAt(1,QColor(0,255,0,0)); //直接用渐变色指定画刷 painter.setBrush(conGradient); painter.setPen(Qt::NoPen); //去除扇形区域边框 //画出扇形启动角度是startAngle,由定时器来修改 painter.drawPie(QRect(-dataTmp,-dataTmp,dataTmp*2,dataTmp*2), -startAngle*16,70*16); } 仪表表盘 初步完成 mark 0; } } update(); }); timer-start(50); } Widget::~Widget() { delete ui; } void Widget::paintEvent(QPaintEvent *event) { QPainter painter(this); painter.setRenderHint(QPainter::Antialiasing,true); //底色弄成黑色 painter.setBrush(Qt::black); painter.drawRect(rect()); //坐标系 平移到中心 painter.translate(rect().center()); QRadialGradient radialGradient(0, 0, height()/2); // 中心和半径 (50, 50, 50) // 设置颜色停靠点 radialGradient.setColorAt(0.0, QColor(255,0,0,50)); // 中心颜色 radialGradient.setColorAt(1.0, QColor(255,0,0,250)); // 外围颜色 // 使用这个渐变创建 QBrush QBrush brush(radialGradient); painter.setBrush(brush); // 画大圆 painter.drawEllipse(QPoint(0,0),height()/2,height()/2); painter.setBrush(Qt::NoBrush); // 画小圆 painter.setPen(QPen(Qt::white,3)); painter.drawEllipse(QPoint(0,0),60,60); //当前值 painter.setFont(QFont(华文宋体,25)); // painter.drawText(0,0,QString::number(currentValue)); painter.drawText(QRect(-60,-60,120,120),Qt::AlignCenter,QString::number(currentV alue)); //画刻度 //1. 算出一个刻度需要旋转的角度 double angle 270*1.0 / 50;//270*1.0的作用是扩大变量类型把int型阔成double,保留小 数 //2. 设置第一个刻度的位置 painter.setFont(QFont(华文宋体,15)); painter.save();//保存当前坐标位置此时此刻是在原点x在3点钟方向 painter.rotate(135); for(int i0;i50;i){ if(i % 10 0){ 稍微美化 稍微修改后依然存在数字方向的问题 } Widget::~Widget() { delete ui; } void Widget::paintEvent(QPaintEvent *event) { QPainter painter(this); painter.setRenderHint(QPainter::Antialiasing,true); //底色弄成黑色 painter.setBrush(Qt::black); painter.drawRect(rect()); //坐标系 平移到中心 painter.translate(rect().center()); // 画大圆 painter.drawEllipse(QPoint(0,0),height()/2,height()/2); painter.setBrush(Qt::NoBrush); // 画小圆 painter.setPen(QPen(Qt::white,3)); painter.drawEllipse(QPoint(0,0),60,60); //当前值 painter.setFont(QFont(华文宋体,25)); // painter.drawText(0,0,QString::number(currentValue)); painter.drawText(QRect(-60,-60,120,120),Qt::AlignCenter,QString::number(currentV alue)); //画刻度 //1. 算出一个刻度需要旋转的角度 double angle 240*1.0 / 60;//270*1.0的作用是扩大变量类型把int型阔成double,保留小 数 //2. 设置第一个刻度的位置 painter.setFont(QFont(华文宋体,15)); painter.save();//保存当前坐标位置此时此刻是在原点x在3点钟方向 painter.rotate(150); for(int i0;i60;i){ if(i % 5 0){ //画字 if(150 angle * i 270){ painter.rotate(180); painter.drawText(-(height()/2 - 20 - 10), 8,QString::number(i*4)); painter.rotate(-180); }else{ painter.drawText(height()/2 - 20 - 45, 8,QString::number(i*4)); } //画长的刻度线 painter.drawLine(height()/2 - 20, 0, height()/2 - 3 ,0); }else{//画短的刻度线 优化数字显示后代码整理 void Widget::initCanvas(QPainter painter) { painter.setRenderHint(QPainter::Antialiasing,true); //底色弄成黑色 painter.setBrush(Qt::black); painter.drawRect(rect()); //坐标系 平移到中心 QPoint cent(rect().width()/2, rect().height()*0.6); painter.translate(cent); } void Widget::drawMiddleCircle(QPainter painter, int radius) { // 画小圆 painter.setPen(QPen(Qt::white,3)); painter.drawEllipse(QPoint(0,0),radius,radius); } void Widget::drawCurrentSpeed(QPainter painter) { //当前值 painter.setFont(QFont(华文宋体,20)); // painter.drawText(0,0,QString::number(currentValue)); painter.drawText(QRect(-60,-60,120,120),Qt::AlignCenter,QString::number(currentV alue)); } void Widget::drawScale(QPainter painter, int radius) { //画刻度 //1. 算出一个刻度需要旋转的角度 angle 240*1.0 / 60;//270*1.0的作用是扩大变量类型把int型阔成double,保留小数 //保存当前坐标位置此时此刻是在原点x在3点钟方向 painter.save(); painter.setPen(QPen(Qt::white,5)); //2. 设置第一个刻度的位置 painter.rotate(startAngle); for(int i0;i60;i){ if(i % 5 0){ //画长的刻度线 painter.drawLine(radius - 20, 0, radius - 3 ,0); }else{//画短的刻度线 painter.drawLine(radius - 8, 0, radius - 3 ,0); } //画完后旋转 painter.rotate(angle); } painter.restore(); } void Widget::drawScaleText(QPainter painter, int radius) { //写刻度文字 painter.setFont(QFont(华文宋体,18)); int r radius - 46; for(int i0; i60; i){ if(i % 5 0){ //保存坐标系 painter.save(); //算出平移点弧度角度*3.1415/180 int delX qCos( (210-angle*i)*M_PI/180) * r;//QT中sin认的是弧度 int delY qSin(qDegreesToRadians(210-angle*i)) * r; //平移坐标系 painter.translate(QPoint(delX,-delY)); //旋转坐标系 painter.rotate(-120angle*i);//angle4,30*4120的时候实参是0120 //写上文字 painter.drawText(-25,-25,50,30,Qt::AlignCenter,QString::number(i*4)); //恢复坐标系 painter.restore(); } } } void Widget::drawPointLine(QPainter painter,int lenth) { //画指针线 //坐标轴先回到原点 painter.restore(); painter.save(); painter.rotate(startAngle angle * currentValue); painter.drawLine(60,0,lenth,0); } void Widget::drawSpeedPie(QPainter painter, int radius) { painter.restore(); QRect rentangle(-radius,-radius,radius*2,radius*2); painter.setPen(Qt::NoPen); painter.setBrush(QColor(235,152,50,150)); painter.drawPie(rentangle,(360-startAngle)*16,-angle*currentValue*16);//angle 前面取 负数为了让它顺时针方向画 } void Widget::startSpeed() { timer new QTimer(this); currentValue 0; connect(timer, QTimer::timeout,[](){ if(mark 0){ currentValue; if(currentValue 60){ mark 1; } } if(mark 1){ 画一个指针 在Qt中使用 QPainter 来绘制一个类似指南针的指针你通常会遵循以下步骤 创建一个QWidget或QMainWindow的子类这是你绘图的画布。 重写 paintEvent 方法这个方法是Qt中绘制自定义图形的关键地方。 使用QPainter在paintEvent 中创建一个QPainter 对象并用它来绘制你的指针。绘制指针可以通过绘制一个线条或者一个具有特定形状的多边形来创建指针比如一个三角形。 旋转指针如果你想让指针能够像指南针那样旋转你可以使用QPainter 的旋转功能。下面是一个简单的例子展示如何在Qt中绘制一个静态的指针 这个代码片段创建了一个自定义的QWidget它在中间绘制了一个三角形作为指针。你可以通过添加更多的逻辑来使指针动态旋转比如根据数据改变指针的方向。在实际应用中指针的样式、大小和颜色都可以根据你的需要进行自定义。 内环 完结 painter.drawRect(rect()); //坐标系 平移到中心 QPoint cent(rect().width()/2, rect().height()*0.6); painter.translate(cent); } void Widget::drawMiddleCircle(QPainter painter, int radius) { // 画小圆 painter.setPen(QPen(Qt::white,3)); painter.drawEllipse(QPoint(0,0),radius,radius); } void Widget::drawCurrentSpeed(QPainter painter) { //当前值 painter.setPen(Qt::white); QFont font(Arial,30); font.setBold(true); painter.setFont(font); // painter.drawText(0,0,QString::number(currentValue)); painter.drawText(QRect(-60,-60,120,70),Qt::AlignCenter,QString::number(currentVa lue*4)); QFont font2(Arial,13); font.setBold(true); painter.setFont(font2); painter.drawText(QRect(-60,-60,120,160),Qt::AlignCenter,Km/h); } void Widget::drawScale(QPainter painter, int radius) { //画刻度 //1. 算出一个刻度需要旋转的角度 angle 240*1.0 / 60;//270*1.0的作用是扩大变量类型把int型阔成double,保留小数 //保存当前坐标位置此时此刻是在原点x在3点钟方向 painter.save(); painter.setPen(QPen(Qt::white,5)); //2. 设置第一个刻度的位置 painter.rotate(startAngle); for(int i0;i60;i){ if( i 40){ painter.setPen(QPen(Qt::red,5)); } if(i % 5 0){ //画长的刻度线 painter.drawLine(radius - 20, 0, radius - 3 ,0); }else{//画短的刻度线 painter.drawLine(radius - 8, 0, radius - 3 ,0); } //画完后旋转 painter.rotate(angle); } painter.restore(); painter.setPen(QPen(Qt::white,5)); } void Widget::drawScaleText(QPainter painter, int radius) { //写刻度文字 QFont font(Arial,15); font.setBold(true); painter.setFont(font); int r radius - 49; for(int i0; i60; i){ if(i % 5 0){ //保存坐标系 painter.save(); //算出平移点弧度角度*3.1415/180 int delX qCos( (210-angle*i)*M_PI/180) * r;//QT中sin认的是弧度 int delY qSin(qDegreesToRadians(210-angle*i)) * r; //平移坐标系 painter.translate(QPoint(delX,-delY)); //旋转坐标系 painter.rotate(-120angle*i);//angle4,30*4120的时候实参是0120 //写上文字 painter.drawText(-25,-25,50,30,Qt::AlignCenter,QString::number(i*4)); //恢复坐标系 painter.restore(); } } } void Widget::drawPointLine(QPainter painter,int lenth) { //画指针线 painter.save(); painter.setBrush(Qt::white); painter.setPen(Qt::NoPen); static const QPointF points[4] { QPointF(0,0.0), QPointF(200.0,-1.1), QPointF(200.0,1.1), QPointF(0,15.0), }; painter.rotate(startAngle angle * currentValue); painter.drawPolygon(points, 4); // painter.drawLine(60,0,lenth,0); //坐标轴先回到原点 painter.restore(); } void Widget::drawSpeedPie(QPainter painter, int radius) { QRect rentangle(-radius,-radius,radius*2,radius*2); painter.setPen(Qt::NoPen); painter.setBrush(QColor(255,0,0,80)); painter.drawPie(rentangle,(360-startAngle)*16,-angle*currentValue*16);//angle 前面取 负数为了让它顺时针方向画 } void Widget::startSpeed() { timer new QTimer(this); currentValue 0; connect(timer, QTimer::timeout,[](){ if(mark 0){ currentValue; if(currentValue 61){ mark 1; } } if(mark 1){ currentValue--; if(currentValue 0){ mark 0; } } update(); }); timer-start(50); } void Widget::drawEllipseInnerBlack(QPainter painter, int radius) { painter.setBrush(Qt::black); painter.drawEllipse(QPoint(0,0),radius,radius); } void Widget::drawEllipseInnerShine(QPainter painter, int radius) { QRadialGradient radialGradient(0,0,radius); radialGradient.setColorAt(0.0, QColor(255,0,0,200)); // 中心颜色 radialGradient.setColorAt(1.0, QColor(0,0,0,100)); // 外围颜色 painter.setBrush(radialGradient); painter.drawEllipse(QPoint(0,0),radius,radius); } void Widget::drawEllipseOutterShine(QPainter painter, int radius) { QRect rentangle(-radius,-radius,radius*2,radius*2); painter.setPen(Qt::NoPen); QRadialGradient radiaGradient(0,0,radius); radiaGradient.setColorAt(1,QColor(255,0,0,200)); radiaGradient.setColorAt(0.97,QColor(255,0,0,120)); radiaGradient.setColorAt(0.9,QColor(0,0,0,0)); radiaGradient.setColorAt(0,QColor(0,0,0,0)); painter.setBrush(radiaGradient); painter.drawPie(rentangle,(360-150)*16,-angle*61*16);//angle前面取 负数为了让它顺时针方向画 } void Widget::drawLogo(QPainter painter, int radius) { QRect rectangle(-65,radius*0.38,130,50); painter.drawPixmap(rectangle,QPixmap(:/icon.png)); } void Widget::paintEvent(QPaintEvent *event) { QPainter painter(this); int rad height()/2; //初始化画布 initCanvas(painter); //画小圆 drawMiddleCircle(painter,60); //画刻度 drawScale(painter, rad); //画刻度文字 drawScaleText(painter, rad); //指针 drawPointLine(painter, rad-58); //画扇形 drawSpeedPie(painter, rad25); //画渐变内圈圆 drawEllipseInnerShine(painter,110); //画黑色内圈 drawEllipseInnerBlack(painter, 80); //画当前速度 drawCurrentSpeed(painter); //画外环发光圈 drawEllipseOutterShine(painter,rad25); //画一个汽车logo drawLogo(painter, rad); } 汽车表盘参考样式 P7 天气预报项目 项目概述 stylesheet界面美化 Json数据解析 HTTP通信 自定义控件绘制温度多控件 代码整合调试能力 stylesheet样式 设置边框弧度 设置某方向边框弧度 设置背景颜色 父控件影响 父控件指定某类控件的样式子控件都要遵守此样式进行显示除非子控件内部有做相关修改 窗体无状态栏-关闭 设置无状态栏 设置左键弹窗关闭功能 窗口跟随移动 代码实现 实现的逻辑 天气预报数据接口 第一种 数据返回 {message:success感谢又拍云(upyun.com)提供CDN赞 助,status:200,date:20240122,time:2024-01-22 11:20:56,cityInfo: {city:北京市,citykey:101010100,parent:北 京,updateTime:07:16},data: {shidu:30%,pm25:4.0,pm10:14.0,quality:优,wendu:-16,ganmao:各类 人群可自由活动,forecast:[{date:22,high:高温 -3℃,low:低温 -11℃,ymd:2024-01-22,week:星期 一,sunrise:07:30,sunset:17:20,aqi:24,fx:西北风,fl:3 级,type:晴,notice:愿你拥有比阳光明媚的心情},{date:23,high:高温 1℃,low:低温 -9℃,ymd:2024-01-23,week:星期 二,sunrise:07:29,sunset:17:22,aqi:37,fx:西北风,fl:3 级,type:晴,notice:愿你拥有比阳光明媚的心情},{date:24,high:高温 4℃,low:低温 -7℃,ymd:2024-01-24,week:星期 三,sunrise:07:29,sunset:17:23,aqi:74,fx:北风,fl:2 级,type:晴,notice:愿你拥有比阳光明媚的心情},{date:25,high:高温 5℃,low:低温 -8℃,ymd:2024-01-25,week:星期 四,sunrise:07:28,sunset:17:24,aqi:86,fx:西北风,fl:2级,type:多 云,notice:阴晴之间谨防紫外线侵扰},{date:26,high:高温 5℃,low:低温 -7℃,ymd:2024-01-26,week:星期 五,sunrise:07:27,sunset:17:25,aqi:79,fx:北风,fl:2 级,type:晴,notice:愿你拥有比阳光明媚的心情},{date:27,high:高温 6℃,low:低温 -4℃,ymd:2024-01-27,week:星期 六,sunrise:07:26,sunset:17:26,aqi:53,fx:西北风,fl:2 级,type:晴,notice:愿你拥有比阳光明媚的心情},{date:28,high:高温 4℃,low:低温 -5℃,ymd:2024-01-28,week:星期 日,sunrise:07:26,sunset:17:28,aqi:52,fx:北风,fl:1级,type:多 云,notice:阴晴之间谨防紫外线侵扰},{date:29,high:高温 1℃,low:低温 -6℃,ymd:2024-01-29,week:星期 一,sunrise:07:25,sunset:17:29,aqi:22,fx:东北风,fl:1 级,type:晴,notice:愿你拥有比阳光明媚的心情},{date:30,high:高温 3℃,low:低温 -6℃,ymd:2024-01-30,week:星期 二,sunrise:07:24,sunset:17:30,aqi:34,fx:东风,fl:2 级,type:阴,notice:不要被阴云遮挡住好心情},{date:31,high:高温 4℃,low:低温 -4℃,ymd:2024-01-31,week:星期 三,sunrise:07:23,sunset:17:31,aqi:48,fx:东南风,fl:2 级,type:阴,notice:不要被阴云遮挡住好心情},{date:01,high:高温 8℃,low:低温 -3℃,ymd:2024-02-01,week:星期 四,sunrise:07:22,sunset:17:32,aqi:42,fx:西风,fl:1 级,type:阴,notice:不要被阴云遮挡住好心情},{date:02,high:高温 7℃,low:低温 -3℃,ymd:2024-02-02,week:星期 五,sunrise:07:21,sunset:17:34,aqi:59,fx:东南风,fl:1 级,type:阴,notice:不要被阴云遮挡住好心情},{date:03,high:高温 2℃,low:低温 -4℃,ymd:2024-02-03,week:星期 六,sunrise:07:20,sunset:17:35,aqi:41,fx:南风,fl:2级,type:小 雪,notice:小雪虽美赏雪别着凉},{date:04,high:高温 2℃,low:低温 -5℃,ymd:2024-02-04,week:星期 日,sunrise:07:19,sunset:17:36,aqi:45,fx:西北风,fl:1级,type:多 云,notice:阴晴之间谨防紫外线侵扰},{date:05,high:高温 3℃,low:低温 -5℃,ymd:2024-02-05,week:星期 一,sunrise:07:18,sunset:17:37,aqi:48,fx:北风,fl:1级,type:多云,notice:阴晴之间谨防紫外线侵扰}],yesterday:{date:21,high:高温 -5℃,low:低温 -10℃,ymd:2024-01-21,week:星期 日,sunrise:07:31,sunset:17:19,aqi:26,fx:西北风,fl:4级,type:晴,notice:愿你拥有比阳光明媚的心情}}} 第二种 数据返回 {cityid:101230101,date:2024-01-22,week:星期 一,update_time:11:29,city:福州,cityEn:fuzhou,country:中 国,countryEn:China,wea:阴,wea_img:yin,tem:8.7,tem1:7,tem2: -1,win:东北风,win_speed:2 级,win_meter:4km\/h,humidity:78%,visibility:10km,pressure:1019, air:21,air_pm25:21,air_level:优,air_tips:各类人群可多参加户外活动多呼吸一下清新的空气。,alarm:[{alarm_type:降温,alarm_level:蓝 色,alarm_title:福建省福州市发布降温蓝色预警,alarm_content:福州市气象台2024年01月 22日09时44分继续发布降温蓝色预警信号受寒潮影响今天到24日我市气温继续下降日最低气温过程降幅可达912℃今天到24日夜晨气温较低过程最低气温晋安区山区可达-30℃有结冰其余地区13℃有霜或霜冻22日傍晚到23日上午部分乡镇将出现小雪或雨夹雪。请注意防范预警信息来源国家预警信息发布中心},{alarm_type:降温,alarm_level:蓝色,alarm_title:福建省福州市发布降温蓝色预警,alarm_content:福州市气象台2024年01月22日09时44分继续发布降温蓝色预警信 号受寒潮影响今天到24日我市气温继续下降日最低气温过程降幅可达912℃今天到24日夜晨气温较低过程最低气温晋安区山区可达-30℃有结冰其余地区13℃有霜或霜冻22日傍晚到23日上午部分乡镇将出现小雪或雨夹雪。请注意防范预警信息来源国家预警信息发布中心}, {alarm_type:降温,alarm_level:蓝色,alarm_title:福建省福州市发布降温蓝色预 警,alarm_content:福州市气象台2024年01月21日09时29分发布降温蓝色预警信号受寒潮影响今天到23日我市气温持续下降日最低气温过程降幅可达912℃2224日夜晨气温较低过程日最低气温晋安区北部可达-30℃有霜或霜冻和结冰其余地区13℃有霜或霜冻请注意防范预警信息来源国家预警信息发布中心},{alarm_type:降温,alarm_level:蓝色,alarm_title:福建省福州市发布降温蓝色预警,alarm_content:福州市气象台2024年01月21日09时29分发布降温蓝色预警信号受寒潮影响今天到23日我市气温持续下降日最低气温过程降幅可达912℃2224日夜晨气温较低过程日最低气温晋安区北部可达-30℃有霜或霜冻和结冰其余地区13℃有霜或霜冻请注意防 范预警信息来源国家预警信息发布中 心}],rain_pcpn:2.8,uvIndex:2,uvDescription:低,wea_day:小雨,wea_day_img:yu,wea_night:小 雨,wea_night_img:yu,sunrise:06:50,sunset:17:36,hours: [{hours:10:00,wea:小雨,wea_img:yu,tem:9,win:东北 风,win_speed:2级,vis:13,aqinum:21,aqi:优}, {hours:11:00,wea:小雨,wea_img:yu,tem:7,win:东北 风,win_speed:2级,vis:12.92,aqinum:22,aqi:优}, {hours:12:00,wea:小雨,wea_img:yu,tem:7,win:东北 风,win_speed:2级,vis:13.02,aqinum:21,aqi:优}, {hours:13:00,wea:雾,wea_img:wu,tem:7,win:东北风,win_speed:2 级,vis:13.02,aqinum:20,aqi:优}, {hours:14:00,wea:雾,wea_img:wu,tem:5,win:东北风,win_speed:2 级,vis:12.92,aqinum:21,aqi:优},{hours:15:00,wea:小 雨,wea_img:yu,tem:4,win:东北风,win_speed:2 级,vis:12.78,aqinum:24,aqi:优},{hours:16:00,wea:小 雨,wea_img:yu,tem:3,win:东北风,win_speed:2 级,vis:12.21,aqinum:24,aqi:优},{hours:17:00,wea:中 雨,wea_img:yu,tem:2,win:东北风,win_speed:2 级,vis:11.77,aqinum:27,aqi:优},{hours:18:00,wea:中 雨,wea_img:yu,tem:1,win:东北风,win_speed:2 级,vis:11.42,aqinum:26,aqi:优},{hours:19:00,wea:小 雨,wea_img:yu,tem:1,win:东北风,win_speed:2 级,vis:10.77,aqinum:24,aqi:优},{hours:20:00,wea:小 雨,wea_img:yu,tem:1,win:东北风,win_speed:2 级,vis:10.13,aqinum:23,aqi:优},{hours:21:00,wea:小 雨,wea_img:yu,tem:1,win:东北风,win_speed:2 级,vis:9.3,aqinum:23,aqi:优},{hours:22:00,wea:小 雨,wea_img:yu,tem:1,win:东北风,win_speed:2 级,vis:9.11,aqinum:24,aqi:优},{hours:23:00,wea:小 雨,wea_img:yu,tem:1,win:东北风,win_speed:1 级,vis:9.11,aqinum:27,aqi:优}, {hours:00:00,wea:雾,wea_img:wu,tem:2,win:东北风,win_speed:1 级,vis:8.91,aqinum:27,aqi:优},{hours:01:00,wea:小 雨,wea_img:yu,tem:2,win:东北风,win_speed:1 级,vis:8.91,aqinum:28,aqi:优},{hours:02:00,wea:小 雨,wea_img:yu,tem:2,win:东北风,win_speed:1 级,vis:8.91,aqinum:30,aqi:优},{hours:03:00,wea:小 雨,wea_img:yu,tem:2,win:东北风,win_speed:1 级,vis:8.91,aqinum:28,aqi:优},{hours:04:00,wea:小 雨,wea_img:yu,tem:2,win:北东北风,win_speed:1 级,vis:9.28,aqinum:28,aqi:优}, {hours:05:00,wea:阴,wea_img:yin,tem:2,win:东北 风,win_speed:1级,vis:9.83,aqinum:28,aqi:优}, {hours:06:00,wea:多云,wea_img:yun,tem:3,win:东北 风,win_speed:1级,vis:10.7,aqinum:28,aqi:优}, {hours:07:00,wea:晴,wea_img:qing,tem:4,win:东北 风,win_speed:1级,vis:11,aqinum:28,aqi:优}, {hours:08:00,wea:晴,wea_img:qing,tem:5,win:东北 风,win_speed:1级,vis:11.59,aqinum:28,aqi:优}, {hours:09:00,wea:晴,wea_img:qing,tem:6,win:东北 风,win_speed:1级,vis:12.41,aqinum:27,aqi:优}, {hours:10:00,wea:晴,wea_img:qing,tem:7,win:东北 风,win_speed:1级,vis:13.43,aqinum:27,aqi:优}, {hours:11:00,wea:晴,wea_img:qing,tem:8,win:东北 风,win_speed:1级,vis:14.42,aqinum:27,aqi:优}, {hours:12:00,wea:晴,wea_img:qing,tem:8,win:东北 风,win_speed:1级,vis:15.58,aqinum:25,aqi:优}, {hours:13:00,wea:晴,wea_img:qing,tem:9,win:东北 风,win_speed:1级,vis:16.85,aqinum:24,aqi:优}],aqi: {update_time:10:47,air:21,air_level:优,air_tips:各类人群可多参加户外活动多呼吸一下清新的空 气。,pm25:14,pm25_desc:优,pm10:21,pm10_desc:优,o3:42,o3_desc :,no2:17,no2_desc:,so2:5,so2_desc:,co:0.8,co_desc:,ko uzhao:不用佩戴口罩,yundong:适宜运动,waichu:适宜外出,kaichuang:适宜开 窗,jinghuaqi:不需要打开}} 未来7天 数据返回 {cityid:101230101,city:福州,cityEn:fuzhou,country:中 国,countryEn:China,update_time:2024-01-22 11:47:00,data:[{day:22日 星期一,date:2024-01-22,week:星期 一,wea:阴,wea_img:yin,wea_day:小雨,wea_day_img:yu,wea_night:小 雨,wea_night_img:yu,tem:8.7,tem1:7,tem2:-1,humidity:79%,vis ibility:11km,pressure:1019,win:[无持续风向,无持续风向],win_speed:3 级,win_meter:2km\/h,sunrise:06:50,sunset:17:36,air:21,air_level :优,air_tips:各类人群可多参加户外活动多呼吸一下清新的空气。,alarm: {alarm_type:降温,alarm_level:蓝色,alarm_title:福建省福州市发布降温蓝色预 警,alarm_content:福州市气象台2024年01月22日09时44分继续发布降温蓝色预警信号受寒潮影 响今天到24日我市气温继续下降日最低气温过程降幅可达912℃今天到24日夜晨气温较低过程最低气温晋安区山区可达-30℃有结冰其余地区13℃有霜或霜冻22日傍晚到23日上午部分乡镇将出现小雪或雨夹雪。请注意防范预警信息来源国家预警信息发布中心},hours:[{hours:08 时,wea:阴,wea_img:yin,tem:7,win:无持续风向,win_speed:3级}, {hours:09时,wea:小雨,wea_img:yu,tem:6,win:东北风,win_speed: 3级},{hours:10时,wea:小雨,wea_img:yu,tem:6,win:东北风,win_speed:3级},{hours:11时,wea:小 雨,wea_img:yu,tem:6,win:东北风,win_speed:3级},{hours:12 时,wea:小雨,wea_img:yu,tem:6,win:东北风,win_speed:3级}, {hours:13时,wea:小雨,wea_img:yu,tem:6,win:东北风,win_speed: 3级},{hours:14时,wea:小雨,wea_img:yu,tem:6,win:东北风,win_speed:3级},{hours:15时,wea:小 雨,wea_img:yu,tem:5,win:东北风,win_speed:3级},{hours:16 时,wea:小雨,wea_img:yu,tem:5,win:东北风,win_speed:3级}, {hours:17时,wea:小雨,wea_img:yu,tem:4,win:东北风,win_speed: 3级},{hours:18时,wea:小雨,wea_img:yu,tem:4,win:东北风,win_speed:3级},{hours:19时,wea:小 雨,wea_img:yu,tem:4,win:东北风,win_speed:3级},{hours:20 时,wea:小雨,wea_img:yu,tem:4,win:东北风,win_speed:3级}, {hours:21时,wea:小雨,wea_img:yu,tem:3,win:东北风,win_speed: 3级},{hours:22时,wea:小雨,wea_img:yu,tem:3,win:东北风,win_speed:3级},{hours:23时,wea:小 雨,wea_img:yu,tem:3,win:东北风,win_speed:3级},{hours:00 时,wea:雨夹雪,wea_img:yu,tem:1,win:东北风,win_speed:3级}, {hours:01时,wea:雨夹雪,wea_img:yu,tem:0,win:东北风,win_speed:3级},{hours:02时,wea:雨夹 雪,wea_img:yu,tem:0,win:东北风,win_speed:3级},{hours:03 时,wea:雨夹雪,wea_img:yu,tem:0,win:东北风,win_speed:3级}, {hours:04时,wea:雨夹雪,wea_img:yu,tem:0,win:东北风,win_speed:3级},{hours:05时,wea:雨夹 雪,wea_img:yu,tem:1,win:东北风,win_speed:3级},{hours:06 时,wea:小雨,wea_img:yu,tem:2,win:东北风,win_speed:3级}, {hours:07时,wea:小雨,wea_img:yu,tem:2,win:东北风,win_speed: 3级}],index:[{title:紫外线指数,level:最弱,desc:辐射弱涂擦SPF8-12防晒护 肤品。},{title:减肥指数,level:较不宜,desc:有降水推荐您在室内进行休闲运 动。},{title:血糖指数,level:极不易发,desc:无需担心过敏可放心外出享受生 活。},{title:穿衣指数,level:冷,desc:建议着棉衣加羊毛衫等冬季服装。}, {title:洗车指数,level:不宜,desc:有雨雨水和泥水会弄脏爱车。},{title:空气污染扩散指数,level:良,desc:气象条件有利于空气污染物扩 散。}],uvIndex:2,uvDescription:低},{day:23日星期二,date:2024-01- 23,week:星期二,wea:多云转晴,wea_img:yun,wea_day:多 云,wea_day_img:yun,wea_night:晴,wea_night_img:qing,tem:10,tem1: 10,tem2:2,humidity:63,visibility:,pressure:,win:[无持续风向,无持续风向],win_speed:3 级,win_meter:,sunrise:06:50,sunset:17:37,air:31,air_level:优, air_tips:,alarm: {alarm_type:,alarm_level:,alarm_content:},hours:[{hours:08 时,wea:小雨,wea_img:yu,tem:3,win:东北风,win_speed:3级}, {hours:09时,wea:多云,wea_img:yun,tem:4,win:东北风,win_speed: 3级},{hours:10时,wea:多云,wea_img:yun,tem:5,win:东北风,win_speed:3级},{hours:11时,wea:多 云,wea_img:yun,tem:7,win:北风,win_speed:3级},{hours:12 时,wea:多云,wea_img:yun,tem:8,win:东北风,win_speed:3级}, {hours:13时,wea:多云,wea_img:yun,tem:8,win:东北风,win_speed: 3级},{hours:14时,wea:晴,wea_img:qing,tem:9,win:东风,win_speed:3级},{hours:15 时,wea:晴,wea_img:qing,tem:9,win:东风,win_speed:3级}, {hours:16时,wea:晴,wea_img:qing,tem:8,win:东风,win_speed:3 级},{hours:17时,wea:晴,wea_img:qing,tem:7,win:东风,win_speed:3级},{hours:18 时,wea:晴,wea_img:qing,tem:6,win:东风,win_speed:3级}, {hours:19时,wea:晴,wea_img:qing,tem:6,win:东北风,win_speed: 3级},{hours:20时,wea:晴,wea_img:qing,tem:5,win:东北风,win_speed:3级},{hours:21 时,wea:晴,wea_img:qing,tem:4,win:东北风,win_speed:3级}, {hours:22时,wea:晴,wea_img:qing,tem:4,win:东北风,win_speed: 3级},{hours:23时,wea:晴,wea_img:qing,tem:4,win:东北风,win_speed:3级},{hours:00 时,wea:晴,wea_img:qing,tem:4,win:东北风,win_speed:3级}, {hours:01时,wea:晴,wea_img:qing,tem:3,win:东北风,win_speed: 3级},{hours:02时,wea:晴,wea_img:qing,tem:3,win:东北风,win_speed:3级},{hours:03 时,wea:晴,wea_img:qing,tem:2,win:东南风,win_speed:3级}, {hours:04时,wea:晴,wea_img:qing,tem:2,win:西南风,win_speed: 3级},{hours:05时,wea:晴,wea_img:qing,tem:2,win:北风,win_speed:3级},{hours:06 时,wea:晴,wea_img:qing,tem:2,win:北风,win_speed:3级}, {hours:07时,wea:晴,wea_img:qing,tem:3,win:北风,win_speed:3 级}],index:[{title:紫外线指数,level:中等,desc:涂擦SPF大于15、PA防晒护肤 品。},{title:减肥指数,level:较适宜,desc:气温较低在户外运动请注意增减衣 物。},{title:血糖指数,level:极不易发,desc:无需担心过敏可放心外出享受生 活。},{title:穿衣指数,level:较冷,desc:建议着厚外套加毛衣等服装。}, {title:洗车指数,level:较不宜,desc:路面有积水车子易被溅上泥水。}, {title:空气污染扩散指数,level:中,desc:易感人群应适当减少室外活 动。}],uvIndex:5,uvDescription:中等},{day:24日星期三,date:2024- 01-24,week:星期 三,wea:晴,wea_img:qing,wea_day:晴,wea_day_img:qing,wea_night: 晴,wea_night_img:qing,tem:11,tem1:11,tem2:4,humidity:46,vis ibility:,pressure:,win:[无持续风向,无持续风向],win_speed:3 级,win_meter:,sunrise:06:50,sunset:17:38,air:34,air_level:优, air_tips:,alarm: {alarm_type:,alarm_level:,alarm_content:},hours:[{hours:08 时,wea:晴,wea_img:qing,tem:3,win:西北风,win_speed:3级}, {hours:09时,wea:晴,wea_img:qing,tem:5,win:西风,win_speed:3 级},{hours:10时,wea:晴,wea_img:qing,tem:7,win:南风,win_speed:3级},{hours:11 时,wea:晴,wea_img:qing,tem:9,win:东风,win_speed:3级}, {hours:12时,wea:晴,wea_img:qing,tem:9,win:东风,win_speed:3 级},{hours:13时,wea:晴,wea_img:qing,tem:10,win:东风,win_speed:3级},{hours:14 时,wea:晴,wea_img:qing,tem:10,win:东风,win_speed:3级}, {hours:15时,wea:晴,wea_img:qing,tem:10,win:东风,win_speed: 3级},{hours:16时,wea:晴,wea_img:qing,tem:9,win:东风,win_speed:3级},{hours:17 时,wea:晴,wea_img:qing,tem:9,win:东风,win_speed:3级}, {hours:18时,wea:晴,wea_img:qing,tem:8,win:东风,win_speed:3 级},{hours:19时,wea:晴,wea_img:qing,tem:8,win:东风,win_speed:3级},{hours:20 时,wea:晴,wea_img:qing,tem:8,win:东北风,win_speed:3级}, {hours:21时,wea:晴,wea_img:qing,tem:7,win:东北风,win_speed: 3级},{hours:22时,wea:晴,wea_img:qing,tem:5,win:东北风,win_speed:3级},{hours:23 时,wea:晴,wea_img:qing,tem:4,win:北风,win_speed:3级}, {hours:00时,wea:晴,wea_img:qing,tem:4,win:东南风,win_speed: 3级},{hours:01时,wea:晴,wea_img:qing,tem:4,win:西南风,win_speed:3级},{hours:02 时,wea:晴,wea_img:qing,tem:4,win:北风,win_speed:3级}, {hours:03时,wea:晴,wea_img:qing,tem:5,win:北风,win_speed:3 级},{hours:04时,wea:晴,wea_img:qing,tem:5,win:西北风,win_speed:3级},{hours:05 时,wea:晴,wea_img:qing,tem:5,win:西北风,win_speed:3级}, {hours:06时,wea:晴,wea_img:qing,tem:5,win:西北风,win_speed: 3级},{hours:07时,wea:晴,wea_img:qing,tem:5,win:西北 风,win_speed:3级}],index:[{title:紫外线指数,level:强,desc:涂擦SPF大于15、PA防晒护肤品。},{title:减肥指数,level:较适宜,desc:气温较低在户外运 动请注意增减衣物。},{title:血糖指数,level:极不易发,desc:无需担心过敏可放心外 出享受生活。},{title:穿衣指数,level:较冷,desc:建议着厚外套加毛衣等服装。}, {title:洗车指数,level:适宜,desc:天气较好适合擦洗汽车。},{title:空气污染扩散指数,level:中,desc:易感人群应适当减少室外活 动。}],uvIndex:6,uvDescription:强},{day:25日星期四,date:2024-01- 25,week:星期四,wea:晴转多 云,wea_img:yun,wea_day:晴,wea_day_img:qing,wea_night:多 云,wea_night_img:yun,tem:13,tem1:13,tem2:5,humidity:51,visi bility:,pressure:,win:[无持续风向,无持续风向],win_speed:3 级,win_meter:,sunrise:06:50,sunset:17:39,air:31,air_level:优, air_tips:,alarm: {alarm_type:,alarm_level:,alarm_content:},hours:[{hours:08 时,wea:晴,wea_img:qing,tem:6,win:西北风,win_speed:3级}, {hours:11时,wea:晴,wea_img:qing,tem:11,win:东南风,win_speed: 3级},{hours:14时,wea:晴,wea_img:qing,tem:12,win:东风,win_speed:3级},{hours:17 时,wea:晴,wea_img:qing,tem:13,win:东北风,win_speed:3级}, {hours:20时,wea:晴,wea_img:qing,tem:8,win:东北风,win_speed: 3级},{hours:23时,wea:晴,wea_img:qing,tem:7,win:西风,win_speed:3级},{hours:02时,wea:多 云,wea_img:yun,tem:5,win:北风,win_speed:3级},{hours:05 时,wea:多云,wea_img:yun,tem:5,win:北风,win_speed:3 级}],index:[{title:紫外线指数,level:强,desc:涂擦SPF大于15、PA防晒护肤 品。},{title:减肥指数,level:较适宜,desc:气温较低在户外运动请注意增减衣 物。},{title:血糖指数,level:极不易发,desc:无需担心过敏可放心外出享受生 活。},{title:穿衣指数,level:较冷,desc:建议着厚外套加毛衣等服装。}, {title:洗车指数,level:适宜,desc:天气较好适合擦洗汽车。},{title:空气污染扩散指数,level:中,desc:易感人群应适当减少室外活 动。}],uvIndex:6,uvDescription:强},{day:26日星期五,date:2024-01- 26,week:星期 五,wea:晴,wea_img:qing,wea_day:晴,wea_day_img:qing,wea_night: 晴,wea_night_img:qing,tem:15,tem1:15,tem2:6,humidity:53,vis ibility:,pressure:,win:[无持续风向,无持续风向],win_speed:3 级,win_meter:,sunrise:06:49,sunset:17:39,air:30,air_level:优, air_tips:,alarm: {alarm_type:,alarm_level:,alarm_content:},hours:[{hours:08 时,wea:多云,wea_img:yun,tem:6,win:西北风,win_speed:3级}, {hours:11时,wea:多云,wea_img:yun,tem:10,win:东南风,win_speed:3级},{hours:14 时,wea:晴,wea_img:qing,tem:14,win:东风,win_speed:3级}, {hours:17时,wea:晴,wea_img:qing,tem:12,win:东北风,win_speed: 3级},{hours:20时,wea:晴,wea_img:qing,tem:10,win:东风,win_speed:3级},{hours:23 时,wea:晴,wea_img:qing,tem:8,win:东风,win_speed:3级}, {hours:02时,wea:晴,wea_img:qing,tem:6,win:西北风,win_speed: 3级},{hours:05时,wea:晴,wea_img:qing,tem:7,win:南 风,win_speed:3级}],index:[{title:紫外线指数,level:强,desc:涂擦SPF大于15、PA防晒护肤品。},{title:减肥指数,level:较适宜,desc:天气凉在户外运动 请注意增减衣物。},{title:血糖指数,level:极不易发,desc:无需担心过敏可放心外 出享受生活。},{title:穿衣指数,level:较冷,desc:建议着厚外套加毛衣等服装。}, {title:洗车指数,level:适宜,desc:天气较好适合擦洗汽车。},{title:空气污染扩散指数,level:中,desc:易感人群应适当减少室外活 动。}],uvIndex:6,uvDescription:强},{day:27日星期六,date:2024-01- 27,week:星期六,wea:多云,wea_img:yun,wea_day:多云,wea_day_img:yun,wea_night:多 云,wea_night_img:yun,tem:16,tem1:16,tem2:8,humidity:53,visi bility:,pressure:,win:[无持续风向,无持续风向],win_speed:3 级,win_meter:,sunrise:06:49,sunset:17:40,air:36,air_level:优, air_tips:,alarm: {alarm_type:,alarm_level:,alarm_content:},hours:[{hours:08 时,wea:晴,wea_img:qing,tem:8,win:西北风,win_speed:3级}, {hours:11时,wea:多云,wea_img:yun,tem:12,win:东南风,win_speed:3级},{hours:14时,wea:多 云,wea_img:yun,tem:15,win:东北风,win_speed:3级},{hours:17 时,wea:多云,wea_img:yun,tem:14,win:东风,win_speed:3级}, {hours:20时,wea:多云,wea_img:yun,tem:13,win:东风,win_speed: 3级},{hours:23时,wea:多云,wea_img:yun,tem:12,win:东南风,win_speed:3级},{hours:02时,wea:多 云,wea_img:yun,tem:8,win:西北风,win_speed:3级},{hours:05 时,wea:多云,wea_img:yun,tem:8,win:南风,win_speed:3 级}],index:[{title:紫外线指数,level:弱,desc:辐射较弱涂擦SPF12-15、 PA护肤品。},{title:减肥指数,level:较适宜,desc:天气凉在户外运动请注意增减衣 物。},{title:血糖指数,level:极不易发,desc:无需担心过敏可放心外出享受生 活。},{title:穿衣指数,level:较冷,desc:建议着厚外套加毛衣等服装。}, {title:洗车指数,level:适宜,desc:天气较好适合擦洗汽车。},{title:空气污染扩散指数,level:中,desc:易感人群应适当减少室外活 动。}],uvIndex:5,uvDescription:中等},{day:28日星期日,date:2024- 01-28,week:星期日,wea:多云,wea_img:yun,wea_day:多云,wea_day_img:yun,wea_night:多 云,wea_night_img:yun,tem:17,tem1:17,tem2:10,humidity:62,vis ibility:,pressure:,win:[无持续风向,无持续风向],win_speed:3 级,win_meter:,sunrise:06:49,sunset:17:41,air:33,air_level:优, air_tips:,alarm: {alarm_type:,alarm_level:,alarm_content:},hours:[{hours:08 时,wea:多云,wea_img:yun,tem:10,win:西北风,win_speed:3级}, {hours:11时,wea:多云,wea_img:yun,tem:13,win:东南风,win_speed:3级},{hours:14时,wea:多 云,wea_img:yun,tem:16,win:东风,win_speed:3级},{hours:17 时,wea:多云,wea_img:yun,tem:15,win:东风,win_speed:3级}, 软件开发网络通信架构 BS架构/CS架构 在计算机网络和软件开发中CS架构Client-Server Architecture客户端-服务器架构和BS架构 Browser-Server Architecture浏览器-服务器架构是两种主要的应用程序架构。 CS架构客户端-服务器架构 CS架构是一种典型的两层结构包括客户端和服务器两个部分。在这种架构中客户端和服务器通过网络进行通信每部分都有明确的职责。 客户端 用户界面通常在客户端呈现。 可以是桌面应用程序、移动应用或专用软件。 负责向服务器发送请求接收和处理服务器响应。 服务器 管理数据和业务逻辑。 处理来自客户端的请求并发送回响应。 通常承载在远程系统上如数据库服务器、应用服务器等。 特点 需要为每种操作系统或平台单独开发客户端。高效的数据处理和响应能力。 在客户端设备上占用资源如内存和处理能力。 BS架构浏览器-服务器架构 BS架构是一种基于Web的三层或多层架构主要通过Web浏览器作为客户端访问服务器上的应用程序。 浏览器客户端 使用标准Web浏览器如Chrome、Firefox等作为客户端。 无需安装额外的软件使用HTML、CSS和JavaScript显示内容。 服务器 和CS架构中的服务器类似处理业务逻辑和数据存储。通过Web服务如HTTP服务器提供页面和数据。 特点 跨平台兼容性强可以在任何支持Web浏览器的设备上运行。客户端无需安装专用软件容易维护和更新。 可能依赖网络性能因为所有操作都在服务器上进行。 对比 部署和维护BS架构易于部署和维护而CS架构通常需要在每个客户端单独安装和更新。 性能CS架构可以更有效地利用客户端的计算资源适合高性能要求的应用。BS架构依赖于服务器的性能和网络延迟。 安全性CS架构中数据经常在客户端和服务器之间传输可能需要更复杂的安全措施。BS架构中敏感数据主要存储在服务器端。 用户体验CS架构通常能提供更丰富的用户界面和交互功能。BS架构的用户体验受限于Web技术的能力。 在实际应用中选择哪种架构取决于具体的业务需求、目标用户群、性能要求以及开发和维护的成本。 HTTP基本概念 HTTP超文本传输协议是一种用于分布式、协作式和超媒体信息系统的应用层协议。它是万维网 WWW的数据通信的基础。了解HTTP的基本概念对于理解现代网络通信至关重要。以下是HTTP的一些核心概念 请求和响应 HTTP是一个基于请求-响应模式的协议。客户端通常是Web浏览器向服务器发送一个HTTP请求然后服务器返回一个HTTP响应。请求包含请求的资源如网页而响应包含请求的资源的内容。 HTTP方法 HTTP定义了一系列的方法来表明对资源的不同操作最常用的包括 GET: 用于请求资源。 POST: 用于提交数据给服务器例如表单数据。 PUT: 用于上传文件或内容。 DELETE: 用于请求删除资源。 HEAD: 用于获取资源的元信息而不是资源本身。 状态码 服务器对请求的响应中包含一个状态码它表示请求的成功或失败以及失败的原因。常见的状态码包括 200 OK: 请求成功。 404 Not Found: 请求的资源未找到。 500 Internal Server Error: 服务器内部错误。 301 Moved Permanently: 请求的资源已永久移动到新位置。 URL统一资源定位符 URL是Web上资源的地址。它指定了资源的位置以及用于访问资源的协议例如http://。 HTTP头 HTTP请求和响应包含头部信息这些信息包括元数据如内容类型、内容长度、服务器信息、客户端信息等。例如 Content-Type 头部指示响应中的媒体类型如text/htmlapplication/json。 无状态协议 HTTP是一个无状态协议这意味着服务器不会保留任何请求的数据状态。然而通过使用如 Cookies这样的机制可以在多个请求之间维持状态。 安全性HTTPS HTTPS是HTTP的安全版本它在HTTP和TCP层之间增加了一个加密层通常是SSL/TLS。这提供了数据传输的加密和更好的安全性。 RESTful API RESTful是一种使用HTTP协议的Web服务设计风格它利用HTTP的方法来实现API的不同操作。在 RESTful架构中每个URL代表一个资源并使用HTTP的方法如GET, POST来处理这些资源。 Session和Cookies 由于HTTP本身是无状态的Cookies和会话Session被用来在多个请求之间存储用户数据从而为用户提供连贯的体验。 这些概念构成了HTTP的基础是理解和使用HTTP协议的关键。每个概念都有它的具体细节和使用场景了解这些有助于更好地在网络应用开发中应用HTTP。 QT的HTTP编程 Qt中的HTTP编程主要涉及使用Qt的网络模块来进行HTTP请求和处理HTTP响应。Qt提供了一系列类来处理网络通信其中最常用的类是QNetworkAccessManager 、 QNetworkRequest 、 QNetworkReply 以及相关的支持类。 以下是一个基本的HTTP编程示例展示了如何使用Qt发送一个简单的HTTP GET请求并处理响应 步骤 1: 包含必要的头文件 步骤 2: 发送HTTP请求 创建一个QNetworkAccessManager 对象并使用它发送HTTP请求。 QNetworkAccessManager 对象会异步地处理请求并返回一个QNetworkReply 对象。 在这个例子中我们使用QNetworkAccessManager 的get 方法发送了一个HTTP GET请求到http://exa mple.com。然后我们连接了QNetworkReply 对象的finished 信号到一个lambda函数该函数在收到HTTP响应时被调用。 注意事项 异步处理: QNetworkAccessManager 的请求是异步的。这意味着get 方法会立即返回而HTTP响应将在稍后通过信号处理。 错误处理: 应该检查QNetworkReply 对象是否有错误并相应地处理。 内存管理: QNetworkReply 对象需要被正确地管理以避免内存泄漏。通常情况下使用 QObject::deleteLater 来安排删除它是一个好方法。 JSON数据 概述 JSONJavaScript Object Notation是一种轻量级的数据交换格式。它易于人阅读和编写同时也易于机器解析和生成。JSON是基于JavaScript的一个子集尽管它是独立于语言的且有多种语言支持。 JSON常用于网络应用程序中的数据传输尤其是在Web应用程序中与后端服务器通信。 使用JSON的原因总结如下 原因 描述 易于阅读和编写 JSON的结构简单、清晰对人类来说易于阅读和编写。 轻量级数据格式 相较于XML等标记语言JSON更轻量使用更少的符号数据体积更小。 易于解析和生成 大多数编程语言都提供了解析和生成JSON的内置支持或库。 跨语言支持 JSON是独立于语言的被广泛支持和使用在多种编程语言中。 原因 描述 网络友好 JSON格式适合Web环境易于通过网络传输是Web API的常用格式。 数据互操作性 作为一种标准化格式JSON提高了不同系统间的数据互操作性。 BS/CS开发过程中会使用不同的编程语言JSON作为数据传输的标准化格式方便程序员协议约定和数据处理以下是不同编程语言处理JSON的方案 语言/平台 JSON处理库/接口 特点/描述 C Jansson 提供JSON的编码、解码和处理功能 C nlohmann/json 现代C从C11开始的JSON库易于使用 Java Jackson 强大的JSON处理库支持JSON的序列化和反序列化 Gson Google提供的JSON序列化/反序列化库 Python json Python标准库中的JSON处理模块 Qt QJsonDocument Qt框架中用于JSON处理的类 QJsonObject 用于表示JSON对象的Qt类 QJsonArray 用于表示JSON数组的Qt类 Android org.json Android SDK自带的JSON处理类提供基础JSON操作功能 iOS JSONSerialization Apple提供的用于JSON处理的类部分Swift和Objective-C标准库中 QT生成JSON数据 在Qt中生成JSON数据并将其保存到文件的一个基本示例涉及使用 QJsonDocument 、 QJsonObject 和 QJsonArray 类。以下是创建一个简单JSON对象并将其保存到文件的示例代码。 说明 创建JSON对象使用QJsonObject 来构建JSON对象并使用键值对填充数据。 创建JSON数组使用QJsonArray 来创建一个数组并添加元素。组合JSON结构将JSON数组添加到JSON对象中。 生成JSON文档通过QJsonDocument 来处理JSON数据可以选择格式化缩进或压缩形式。 保存到文件创建QFile 对象打开文件写入JSON数据并关闭文件。 这个例子展示了Qt中处理JSON的基础流程包括创建、填充数据、转换为字符串以及写入文件。您可以根据需要调整这个流程来适应更复杂的JSON结构或数据。 在JSON中数组可以包含多种类型的元素包括对象。当您在Qt中处理JSON数组其中的元素是对象时您可以使用QJsonArray 和QJsonObject 来创建和处理这些数据结构。以下是一个示例展示了如何创建一个包含多个对象的JSON数组并将该数组添加到一个JSON对象中。 示例代码 rootObj[tmp] 3; //Json数组 QJsonArray jsonArray; jsonArray.append(data1); jsonArray.append(data2); jsonArray.append(data3); jsonArray.append(100); rootObj[testArry] jsonArray; QJsonObject alarmObj; alarmObj[alamType] 雪灾; alarmObj[alamLeve] 黄色; alarmObj[alamTitle] 福州市警告老陈多穿点衣服; rootObj[alam] alarmObj; QJsonObject day0; day0[day] 星期一; day0[wea] 晴; day0[tem] 5.7; QJsonObject day1; day1[day] 星期二; day1[wea] 晴; day1[tem] 7; QJsonObject day2; day2[day] 星期三; day2[wea] 多云; day2[tem] 17; QJsonArray dayArray; dayArray.append(day0); dayArray.append(day1); dayArray.append(day2); rootObj[days] dayArray; //通过QJsonDocument把JSON数据转换成QByteArray QJsonDocument jsonDoc(rootObj); QByteArray jsonArry jsonDoc.toJson(); QFile file(D:/QT/test.json); file.open(QIODevice::WriteOnly); file.write(jsonArry); file.close(); } Widget::~Widget() { delete ui; } QT解析JSON数据 在Qt中解析JSON数据通常涉及到使用 QJsonDocument 、 QJsonObject 和QJsonArray 类。这些类提供了处理JSON数据的必要工具使您能够从JSON字符串中提取信息、遍历JSON对象或数组并访问具体的数据项。以下是一个基本的示例展示了如何在Qt中解析JSON字符串。 示例解析JSON字符串 假设您有一个JSON字符串例如 以下是如何在Qt中解析这个JSON字符串的步骤 说明 字符串转换为 QJsonDocument 使用QJsonDocument::fromJson 方法将JSON字符串转换为 QJsonDocument 对象。 提取 QJsonObject 如果QJsonDocument 包含一个JSON对象使用 object() 方法获取它。 访问对象数据使用键如name 、age 访问QJsonObject 中的数据。 处理数组如果对象包含一个数组使用QJsonArray 来遍历数组中的元素。 这个示例提供了一个基础框架用于在Qt中解析和处理JSON数据。您可以根据实际需要调整这个过程以适应不同的JSON结构和数据类型。 在Qt中如果你想要将JSON数据解析到一个 QMap 中你可以遍历JSON对象的所有键值对并将它们添加到QMap 里。这个方法特别适合于当你的JSON对象是一个简单的键值对集合时。以下是一个如何实现这一点的示例。 示例将JSON数据解析到QMap中 假设你有以下JSON数据 以下是如何将这些数据解析到QMapQString, QString 中的步骤 说明 从JSON字符串创建 QJsonDocument 使用QJsonDocument::fromJson 来解析JSON字符串。 创建 QMap 定义一个QMapQString, QString 来存储键值对。 遍历JSON对象使用keys() 方法获取所有键然后遍历这些键将对应的值添加到QMap 中。 打印 QMap 内容遍历QMap 并打印键值对。 这个示例展示了如何将JSON对象的键值对解析到 QMap 中。这种方法适用于键值对类型的简单JSON对象。对于更复杂的JSON结构可能需要更详细的解析逻辑。 解析如下JSON int tempretrue jsonRoot[tmp].toInt(); qDebug() strW; qDebug() strCityId; qDebug() QString::number(tempretrue); //第五步判读是否是一个数组 if(jsonRoot.contains(testArry) jsonRoot[testArry].isArray()){ qDebug() array; //如果是数组转换成JSON数组 QJsonArray testArray jsonRoot[testArry].toArray(); //遍历数组访问每一项 for(QJsonValue val : testArray){ //QJsonValue的type函数返回数据类型根据不同的数据类型处理数据 // QJsonValue::Type t val.type(); switch (val.type()) { case QJsonValue::Double: qDebug() QString::number(val.toDouble()); break; case QJsonValue::String: qDebug() val.toString(); break; case QJsonValue::Object: break; } } } //第六步判断某个键对应的值是否是一个json对象 if(jsonRoot.contains(alam) jsonRoot[alam].isObject()){ //转成Json对象后处理 QJsonObject alamObj jsonRoot[alam].toObject(); qDebug() alamObj[alamLeve].toString(); qDebug() alamObj[alamTitle].toString(); qDebug() alamObj[alamType].toString(); } if(jsonRoot.contains(days) jsonRoot[days].isArray()){ QJsonArray dayArray jsonRoot[days].toArray(); for(QJsonValue val : dayArray){ //if(val.type() QJsonValue::Object ){ if(val.isObject()){ QJsonObject obj val.toObject(); qDebug() obj[day].toString(); qDebug() QString::number(obj[tem].toDouble()); qDebug() obj[wea].toString(); } } } } } Widget::~Widget() { delete ui; } 天气类型和图标 //根据keys,设置icon的路径 mTypeMap.insert(暴雪,:/res/type/BaoXue.png); mTypeMap.insert(暴雨,:/res/type/BaoYu. png); mTypeMap.insert(暴雨到大暴雨,:/res/type/BaoYuDaoDaBaoYu.png); mTypeMap.insert(大暴雨,:/res/type/DaBaoYu.png); mTypeMap.insert(大暴雨到特大暴雨,:/res/type/DaBaoYuDaoTeDaBaoYu.png); mTypeMap.insert(大到暴雪,:/res/type/DaDaoBaoXue.png); mTypeMap.insert(大雪,:/res/type/DaXue.png); mTypeMap.insert(大雨,:/res/type/DaYu.png); mTypeMap.insert(冻雨,:/res/type/DongYu.png); mTypeMap.insert(多云,:/res/type/DuoYun.png); mTypeMap.insert(浮沉,:/res/type/FuChen.png); mTypeMap.insert(雷阵雨,:/res/type/LeiZhenYu.png); mTypeMap.insert(雷阵雨伴有冰雹,:/res/type/LeiZhenYuBanYouBingBao.png); mTypeMap.insert(霾,:/res/type/Mai.png); mTypeMap.insert(强沙尘暴,:/res/type/QiangShaChenBao.png); mTypeMap.insert(晴,:/res/type/Qing.png); mTypeMap.insert(沙尘暴,:/res/type/ShaChenBao.png); mTypeMap.insert(特大暴雨,:/res/type/TeDaBaoYu.png); mTypeMap.insert(undefined,:/res/type/undefined.png); mTypeMap.insert(雾,:/res/type/Wu.png); mTypeMap.insert(小到中雪,:/res/type/XiaoDaoZhongXue.png); mTypeMap.insert(小到中雨,:/res/type/XiaoDaoZhongYu.png); mTypeMap.insert(小雪,:/res/type/XiaoXue.png); mTypeMap.insert(小雨,:/res/type/XiaoYu.png); mTypeMap.insert(雪,:/res/type/Xue.png); mTypeMap.insert(扬沙,:/res/type/YangSha.png); mTypeMap.insert(阴,:/res/type/Yin.png); mTypeMap.insert(雨,:/res/type/Yu.png); mTypeMap.insert(雨夹雪,:/res/type/YuJiaXue.png); mTypeMap.insert(阵雪,:/res/type/ZhenXue.png); mTypeMap.insert(阵雨,:/res/type/ZhenYu.png); mTypeMap.insert(中到大雪,:/res/type/ZhongDaoDaXue.png); mTypeMap.insert(中到大雨,:/res/type/ZhongDaoDaYu.png); mTypeMap.insert(中雪,:/res/type/ZhongXue.png); mTypeMap.insert(中雨,:/res/type/ZhongYu.png); P8 Ubuntu搭建QT开发环境 安装Ubutnu22 下载和安装Vmware 使用我们提供的安装包或者使用如下地址进行下载 官方下载网址 https://download3.vmware.com/software/WKST-1700-WIN/VMware-workstation-fu ll-17.0.0-20800274.exe 支持正版 如果你的电脑已经安装低版本的VMware千万不要卸载直接覆盖安装更新到17的版本 下载和安装Ubuntu22 使用我们提供的镜像 安装的过程看视频教程安装之后打开如下图所示 常用功能配置 先掌握如下命令 查看命令所在目录 查看当前目录下的所有文件和文件夹创建文件夹 复制拷贝文件 复制拷贝文件夹 删除文件 rm 文件名 如果删除文件夹 加 -rf选项 特别有用善于使用tab键能自动补全文件名或者命令名不会造成输入错误 网络配置 正常电脑就一台虚拟机通过以上安装后就能正常上网 多虚拟机情况桥接模式冲突配置不稳定选择NAT共享主机网络上网获取IP地址通过命令 ip addr 共享文件配置 windows需要传文件给虚拟机 可以通过共享文件夹的方式可以通过网络的方式 编译环境 默认情况系统不带编译环境通过以下命令安装环境 安装VMware Tool 和windows系统的文本复制黏贴打通共享文件夹 配置支持ubuntu远程登录 安装Ubuntu环境下的QT 下载安装UbuntuQT 下载QT通过如下命令 wget https://download.qt.io/archive/qt/5.12/5.12.9/qt-opensource-linux-x64-5.12.9.run 但是速度非常慢 直接去官网下载或者提供我们使用的安装包把它通过共享文件夹拉倒Ubuntu中使用 安装QT 通过如下命令启动QT的安装程序在此之前和Windows一样先让Ubuntu断网配置选择需要安装的项目如下和Windows差不多 运行QT 通过如下命令 /opt/Qt5.12.9/Tools/QtCreator/bin/qtcreator.sh 这里的“”符号代表后台运行不占用控制命令终端 Ubuntu中文支持 配置Ubuntu的中文环境 配置apt下载的服务器源选择阿里 更新源 sudo apt-get update 在setting设置那边打开RegionLanguage设置 选择语言安装在窗口中选择Chinese(simplified) 勾选Chinese重启 配置Ubuntu支持中文输入 安装拼音输入法 sudo apt-get install fcitx-sunpinyin 设置输入法 点击应用到整个系统关闭重启 拷贝我分享的so文件到QT相关路径让QT支持输入中文非常重要用系统自带的不行。 P9 加餐课