自定义博客皮肤VIP专享

*博客头图:

格式为PNG、JPG,宽度*高度大于1920*100像素,不超过2MB,主视觉建议放在右侧,请参照线上博客头图

请上传大于1920*100像素的图片!

博客底图:

图片格式为PNG、JPG,不超过1MB,可上下左右平铺至整个背景

栏目图:

图片格式为PNG、JPG,图片宽度*高度为300*38像素,不超过0.5MB

主标题颜色:

RGB颜色,例如:#AFAFAF

Hover:

RGB颜色,例如:#AFAFAF

副标题颜色:

RGB颜色,例如:#AFAFAF

自定义博客皮肤

-+
  • 博客(85)
  • 收藏
  • 关注

原创 我的创作纪念日

如果统计数据不满意,回头想想为什么你的文章没有吸引力,然后学习提高文章质量的方法。事实上,我敢打赌你目前所知道的 99% 的知识已经在互联网上的一些隐蔽角落(CSDN、掘金、GitHub、知乎、StackOverflow、Reddit、Quora、Dev 等等你能想到的)展现出来了。在这种情况下,你的出发点是自己。你可以写 JavaScript 开发的一个知识点、一个小项目,你自己的学习经历,等等之类的任何东西。关于价值,就我个人而言,它帮助我巩固了我的知识,同时也是一种在业余时间娱乐自己的方式。

2023-08-02 15:05:40 241

原创 【嵌入式Qt开发入门】Qt如何网络编程——建立TCP通信服务端(附项目代码)

TCP 简介TCP 协议(Transmission Control Protocol)全称是传输控制协议是一种面向连接的、可靠的、 基于字节流的传输层通信协议。TCP 通信必须先建立 TCP 连接,通信端分为客户端和服务端。服务端通过监听某个端口来监听是否有客户端连接到来,如果有连接到来,则建立新的 socket 连接;客户端通过 ip 和 port 连接服务端,当成功建立连接之后,就可进行数据的收发了。

2023-07-13 15:13:56 1943 1

原创 【嵌入式Qt开发入门】Qt如何网络编程——获取本机的网络信息

Qt 网络模块为我们提供了编写TCP/IP客户端和服务器的类。它提供了较低级别的类,例如代表低级网络概念的 QTcpSocket,QTcpServer 和 QUdpSocket,以及诸如 QNetworkRequest, QNetworkReply 和 QNetworkAccessManager 之类的高级类来执行使用通用协议的网络操作。它 还提供了诸如QNetworkConfiguration,QNetworkConfigurationManager和QNetworkSession等类, 实现承载管理。

2023-07-12 15:03:46 1211

原创 【嵌入式Qt开发入门】Qt如何使用多线程——继承QObject的线程

我们可以结合程序的注释,一步步去理解这种线程的写法。这里不同于继承 QThread 类的线程 run(),继承 QThread 的类只有 run()在新线程里。而继承 QObject 的类,使用 moveToThread()可以把整个继承的 QObject 类移至线程里执行,所以可以有 doWork1(),doWork2()等耗时的操作,但是这些耗时的操作都应该作为槽函数,由主线程去调用。首先,声明一个 Worker 的类继承 QObject 类,这里是参考 Qt 的 QThread 类的帮助文档的写法。

2023-07-11 17:35:39 1035

原创 【嵌入式Qt开发入门】Qt如何使用多线程——初识QThread

我们写的一个应用程序,应用程序跑起来后一般情况下只有一个线程,但是可能也有特殊情况。比如我们前几篇的例程都跑起来后只有一个线程,就是程序的主线程。线程内的操作都是顺序执行的。但试着想一下,我们的程序顺序执行,假设我们的用户界面点击有某个操作是比较耗时的。您会发现界面点击完了,点击界面对应的操作还没有完成,所以就会冻结界面,不能响应,直到操作完成后,才返回到正常的界面里,对用户的体验也会造成极其糟糕的影响。这种情况我们一般是创建一个单独的线程来执行这个比较耗时的操作。比如我们使用摄像头拍照保存照片。

2023-07-10 15:49:28 497

原创 【嵌入式Qt开发入门】如何使用Qt进行绘制实时图表——QChart 图表

要想使用 Qt Charts,我们的 Qt 版本得使用 Qt 5.7 之后的版本。其实 Qt Charts 并不是 Qt 5.7 才有的,是在 Qt 5.7 以前只有商业版本的 Qt 才有 Qt Charts。我们能免费下载的 Qt 版本都是社区(开源)版本。Qt Charts 很方便的绘制我们常见的曲线图、折线图、柱状图和饼状图等图表。不用自己花精力去了解第三方组件的使用了或者开发第三方组件。Qt 的帮助文档里已经有说明 Qt Charts 主要部件的使用方法。

2023-07-06 15:48:15 3377 4

原创 【嵌入式Qt开发入门】如何使用Qt进行绘图——QPainter 绘图

绘图与图表在嵌入式里有的比较多,尤其是图表,我们常在股票里看到的“图表折线/曲线 图/饼状图等”都可以用 Qt 的图表来实现。绘图和图表的内容本章主要介绍绘图和图表的基本操作,以简单的例子呈现绘图与图表的用法,目的就是快速入门绘图与图表,关于绘图与图表详解最好是看 Qt 官方的帮助文档。

2023-07-05 17:33:26 1707

原创 【嵌入式Qt开发入门】如何使用Qt进行文本读写——QFile读写文本

在很多时候我们需要读写文本文件进行读写,比如写个 Mp3 音乐播放器需要读 Mp3 歌词里的文本,比如修改了一个 txt 文件后保存,就需要对这个文件进行读写操作。本文介绍简单的文本文件读写,内容精简,让大家了解文本读写的基本操作。

2023-07-04 16:59:58 1615

原创 【嵌入式Qt开发入门】如何创建并连接信号与槽

1. 槽可以是任何成员函数、普通全局函数、静态函数2. 槽函数和信号的参数和返回值要一致根据上面的槽特点,由于我们声明了信号 void pushButtonTextChanged();所以我们声明的槽函数必须是无返回值类型 void,和无需参数。所以声明槽的代码如下。此外我们还声明一个 QPushButton 对象 pushButton。对象 pushButton 可以写成简写 btn。这个根据个人习惯即可!简写的名称建议不要让人看不懂即可!同时还声明一个按钮点击的槽。

2023-07-03 18:56:51 305

原创 【嵌入式Qt开发入门】初识信号与槽

槽就是一个函数,与一般的 C++函数是一样的,可以定义在类的任何部分(public、private 或 protected),可以具有任何参数,也可以被直接调用。槽函数与一般的函数不同的是:槽函数可以与一个信号关联,当信号被发射时,关联的槽函数被自动执行。信号(Signal)就是在特定情况下被发射的事件,例如 PushButton 最常见的信号就是鼠标单击时发射的 clicked() 信号,一个 ComboBox 最常见的信号是选择的列表项变化时发射的 CurrentIndexChanged() 信号。

2023-06-30 17:35:26 288

原创 【嵌入式Qt开发入门】使用 UI 设计器(mainwindow.ui)开发程序

本文我们继续学习如何使用 Qt Designer 开发程序,Qt Designer 是属于 Qt Creator 的一个功能而已,大家不要搞混了。Qt Designer 也叫 UI 设计师或者 UI 设计器,这都是指的同一 个东西。下面简单介绍如何使用 UI 设计器开发程序,以连接信号与槽为例,简单的介绍这个开发流程。最后我们思考一下这种开发方式的好处以及不便之处。

2023-06-29 09:45:00 1086

原创 【嵌入式Qt开发入门】第一个 Qt 程序

前文已经在Linux环境下安装好了Qt,下面我们来简单写一个程序,按照惯例,还是从“Hello, world!”开始。

2023-06-28 09:45:00 537

原创 【嵌入式Qt开发入门】初识Qt——Linux下安装Qt

理论上我们选择 Qt 的版本越新越好,这是当然的,不过我们还是要确定一个版本是必须的, 因为日后写好的程序要长期运行在一个确定的版本里,避免随意升级带来其他兼容性问题,或者重复重复移植等工作。简单的来说,Qt 可以做很多东西,好比如 Windows 下的软件也有很多是 Qt 开发的,这里我很喜欢它的可移植性,一份代码可以无需任何修改或者小修改就可以在其他平台上运行。执行安装指令后,将会弹出 Qt 的安装界面,这与 Windows 下的 Qt 安装步骤一样,安装选择目录时,默认安装目录即可。

2023-06-27 16:34:36 11145 3

原创 【嵌入式Qt开发入门】在Ubuntu下编写C++

在 Ubuntu 上面编写 C++,本文内容主要介绍在 Ubuntu 在终端窗口下使用 vi/vim 编辑一 个 C++源文件。通过编写最简单的示例“Hello,World!带领大家学习如何在 Ubuntu 终端下编辑和编译 C++。这里要求大家会在 Ubuntu 上使用 vi/vim,也就是要求大家有一点 Ubuntu 入门的基础。如果没有这些基础也是可以拷贝 C++的代码到 Windows 上使用像 Dev-C++这种轻量级 C/C++ 集成开发环境(IDE)进行编写和编译。

2023-06-26 16:32:48 1895

原创 【CMake 入门与进阶(14)】 CMake中变量的作用域(附代码)

所以函数内部的代码中,调用 set 之前,引用了变量 ABC,此时它会搜索函数内是否定义了该变量,如果没有,它会向外搜索,结果就找到了外部定义的变量 ABC,所以函数内部的第一条打印信息是"Hello World!从打印信息可知,事实并非我们上面所假设那样,函数内调用 set 去设置变量 ABC,并不是设置了外部变量 ABC 的值,而是在函数新创建了一个变量 ABC,这个与 C 语言是不一样的,跟 Python 很像,如果大家学过 Python 的话应该就知道。所以可知,函数内可以引用函数外部定义的变量。

2023-06-24 08:15:00 422

原创 【CMake 入门与进阶(13)】 CMake如何设置交叉编译(附代码)

通过-DCMAKE_TOOLCHAIN_FILE 选项指定配置文件,-D 是 cmake 命令提供的一个选项,通过该选项可以创建一个缓存变量(缓存变量就是全局变量,在整个工程中都是生效的,会覆盖 CMakeLists.txt 源码中定义的同名变量 ),所以 -DCMAKE_TOOLCHAIN_FILE 其实就是设置了缓存变量 CMAKE_TOOLCHAIN_FILE,它的值就是“=”号后面的内容,cmake 会执行 CMAKE_TOOLCHAIN_FILE 变量所指定的源文件,对交叉编译进行设置;

2023-06-23 11:26:24 7918 4

原创 【CMake 入门与进阶(12)】 CMake中对文件操作(附代码)

cmake 提供了 file()命令可对文件进行一系列操作,譬如读写文件、删除文件、文件重命名、拷贝文件、创建目录等等,本文我们一起来学习这个功能强大的 file()命令。

2023-06-22 10:15:00 1500 1

原创 【CMake 入门与进阶(11)】 CMake宏定义与函数(附代码)

因为在宏定义中,宏的参数和诸如 ARGC、ARGV、ARGN 等这些值并不是变量,它们是字符串替换, 也就是说,当 cmake 执行宏定义时,会先将宏的参数和 ARGC、ARGV、ARGN 等这些值进行字符串替换, 然后再去执行这段宏,其实就像是 C 语言中的预处理步骤,这是与函数不同的地方。上面的代码中,我们定义了一个宏 abc 和一个函数 xyz,它们俩的代码是一样的,都是在内部使用 if() 判断 ARGC 是不是一个变量,如果是打印 true,如果不是打印 false;

2023-06-20 09:51:56 925

原创 【CMake 入门与进阶(10)】 CMake如何定义函数,内部参数及作用域(附代码)

在 cmake 中,通过 function()命令定义的函数类似于一个自定义命令(实际上并不是),当然,事实上,cmake 提供了自定义命令的方式,譬如通过 add_custom_command()来实现,如果大家有兴趣,可以自己去学习下,笔者便不再进行介绍了。事实证明,这样也是可以的,说明通过 function()定义的函数它的使用范围是全局的,并不局限于当前源码、可以在其子源码或者父源码中被使用。那反过来,子源码中定义的函数,在父源码中可以使用吗?但是需要注意的是,return 并不可以用于返回参数。

2023-06-19 11:44:36 1911

原创 【CMake 入门与进阶(10)】 CMakeLists.txt 语法规则_循环语句(附使用代码)

cmake 中除了 if 条件判断之外,还支持循环语句,包括 foreach()循环、while()循环。

2023-06-16 11:08:31 498

原创 【CMake 入门与进阶(9)】 CMakeLists.txt 语法规则_条件判断-续(附使用代码)

本文继续CMakeLists.txt 语法规则的学习,先完成上篇条件判断的学习。

2023-06-15 17:26:30 1497

原创 【CMake 入门与进阶(8)】 CMakeLists.txt 语法规则(附使用代码)

在 cmake 中,可以把 1、ON、YES、TRUE、Y 或非零数字以及 0、OFF、NO、FALSE、N、IGNORE、 NOTFOUND、空字符串或以后缀-NOTFOUND 结尾这些理解为常量,类似于布尔值,而且它们不区分大小写;那它们有什么区别呢?NOT 其实就类似于 C 语言中的取反,在 if(NOT)条件判断中,如果表达式 expression 为真, 则条件判断为假;因为 GG 变量没有定义,所以 GG 表达式为假,但因为前面有 NOT 关键字,进行取反操作,整个 if 条件判断为真。

2023-06-14 20:11:53 683

原创 【CMake 入门与进阶(7)】 CMakeLists.txt 部分常用变量-续(附使用代码)

继续来学习CMakeLists.txt 常用变量。

2023-06-13 18:21:26 612

原创 【CMake 入门与进阶(6)】 CMakeLists.txt 部分常用变量(附使用代码)

从打印信息可知,PROJECT_SOURCE_DIR 指的就是工程的顶层 CMakeLists.txt 源码所在路径,而 PROJECT_BINARY_DIR 指的是我们执行 cmake 命令的所在目录,也是顶层 CMakeLists.txt 源码的 BINARY_DIR。也就是通过CMAKE_INCLUDE_PATH 变量来进行指定 , CMAKE_INCLUDE_PATH 指定了一个目录列表,find_file()、find_path()会去这个目录列表中查找文件。接下来我们进行测试。

2023-06-12 20:25:28 918

原创 【CMake 入门与进阶(5)】 CMakeLists.txt 语法规则基础及部分常用指令-续(附使用代码)

关于cmake常用命令、变量的学习到此结束了,给大家介绍了一些基本、常用的命令,并进行了详细的解释说明,除此之外,还有很多的命令并未提及,将会在后面介绍。

2023-06-09 11:19:40 485

原创 WIN下网络编程——TCP/IP-Socket编程项目实战,构建Qt上位机——工业机器人服务器和客户端连接(附项目代码)

本文记录了笔者参与的一个工业机器人双机协作项目(细节不表),项目中考虑数据传输的稳定性、安全性等,使用TCP/IP通讯,上位机软件使用C++/Qt开发(基于WINDOWS环境下),传输指令数据控制下位机工业机器人,同时反馈下位机信号用于整体装配节拍规划。本文收录于网络编程专栏,因此本文仅记录网络通讯部分代码并解析,本文也是对本专栏所学知识的总结和验证,由于该项目基于WINDOWS环境,与Linux环境下Socket编程会有所不同。话不多说,先贴上代码。主要实现通讯功能的是和两个成员函数,其作用分别是。

2023-06-07 17:20:06 830

原创 【CMake 入门与进阶(4)】 CMakeLists.txt 语法规则基础及部分常用指令-续(附使用代码)

使用 include_directories 命令将当前目录下的 include 文件夹添加到头文件搜索列表中,进入 build 目录下,执行 cmake、make 进行构建、编译,编译过程是没有问题的,不会报错提示头文件找不到;与 include_directories 命令相同,当调用 add_subdirectory 命令加载子源码时,会将 link_directories 命令包含的目录列表以及 link_libraries 命令包含的链接库列表向下传递给子源码(子源码从父源码中继承过来)。

2023-06-06 11:30:09 619

原创 【CMake 入门与进阶(3)】 CMakeLists.txt 语法规则基础及部分常用指令(附使用代码)

注释# 这是注释信息大多数脚本语言都是使用“#”号进行注释。命令(command)通常在CMakeLists.txt文件中,使用最多的是命令,譬如上例中的 cmake_minimum_required project 都 是命令;命令的使用方式有点类似于 C 语言中的函数,因为命令后面需要提供一对括号,并且通常需要我们提供参数,多个参数使用空格分隔而不是逗号“,”,这是与函数不同的地方。command(参数 1 参数 2 参数 3 ...)

2023-06-05 10:47:37 1411

原创 【CMake 入门与进阶(2)】CMake编译设置——多个源文件编译及生成库文件(附代码)

在工程目录下,我们创建了 src 和 libhello 目录,并将 hello.c 和 hello.h 文件移动到 libhello 目录下,将 main.c 文件移动到 src 目录下,并且在顶层目录、libhello 目录以及 src 目录下都有一个 CMakeLists.txt 文件。add_library 命令用于生成库文件,在本例中我们传入了两个参数,第一个参数表示库文件的名字,需要注意的是,这个名字是不包含前缀和后缀的名字;所以,意味着最终生成的库文件对应的名字会自动添加上前缀和后缀。

2023-06-02 11:27:41 3035 1

原创 【CMake 入门与进阶(1)】一个例子搞懂什么是CMakeLists——从“Hello World”开始(附代码)

开放源代码我们可以直接从 cmake 官网下载到它的源代码;跨平台cmake 并不直接编译、构建出最终的可执行文件或库文件,它允许开发者编写一种与平台 无关的 CMakeLists.txt 文件来制定整个工程的编译流程,cmake 工具会解析 CMakeLists.txt 文件语法规则,再根据当前的编译平台,生成本地化的 Makefile 和工程文件,最后通过 make 工具来编译整个工程;

2023-06-01 16:16:03 692

原创 【Linux CAN应用编程(2)】SocketCAN 应用编程全流程讲解(附代码)

由于 Linux 系统将 CAN 设备作为网络设备进行管理,因此在 CAN 总线应用开发方面,Linux 提供了 SocketCAN 应用编程接口,使得 CAN 总线通信近似于和以太网的通信,应用程序开发接口更加通用,也更加灵活。SocketCAN 中大部分的数据结构和函数在头文件 linux/can.h 中进行了定义,所以,在我们的应用程序中一定要包含头文件。

2023-05-31 10:22:04 3942

原创 【Linux CAN应用编程(1)】初识CAN总线(附全文代码)

CAN 是 Controller Area Network 的缩写(以下称为 CAN),即控制器局域网络,是 ISO 国际标准化的串行通信协议。CAN 总线最初是由德国博世公司(BOSCH)开发,其最初动机就是为了解决现代汽车中庞大的电子控制系统之间的通讯,减少不断增加的信号线。于是,他们设计了一个单一的网络总线,所有的外围器件可以被挂接在该总线上。

2023-05-29 19:35:35 2133

原创 【Linux高级 I/O(7)】初识文件锁——fcntl()方法及其独占性、共享性实验(附全文代码)

如果一个进程对文件的某个区域已经上了一把锁,后来该进程又试图在该区域再加一把锁,那么通常新加的锁将替换旧的锁。如果两个区域出现了重叠,譬如 100~200 字节区间和 150~250 字节区间,150~200 就是它们的重叠部分,一个进程对同一文件的相同区域不可能同时加两把锁,新加的锁会把旧的锁替换掉,譬如先对 100~200 字节区间加写锁、再对 150~250 字节区间加读锁,那么 150~200 字节区间最终是读锁控制的,关于这个问题,大家可以自己去验证、测试。只有当请求的锁可用时,进程才会被唤醒。

2023-05-26 11:30:23 1777

原创 【Linux高级 I/O(6)】初识文件锁—— flock()方法(附代码示例)

想象一下,当两个人同时编辑磁盘中同一份文件时,其后果将会如何呢?在 Linux 系统中,该文件的最后状态通常取决于写该文件的最后一个进程。多个进程同时操作同一文件,很容易导致文件中的数据发生混乱,因为多个进程对文件进行 I/O 操作时,容易产生竞争状态、导致文件中的内容与预想的不一致!对于有些应用程序,进程有时需要确保只有自己能够对某一文件进行 I/O 操作,在这段时间不允许其它进程对该文件进行 I/O 操作。为了向进程提供这种功能,Linux 系统提供了文件锁机制。

2023-05-25 19:36:58 2236

原创 【Linux高级 I/O(6)】存储映射 I/O进阶应用(附代码示例)

通过存储映射 I/O 将文件直接映射到应用程序地址空间中的一块内存区域中,也就是映射区;前文提到过,read()和 write()系统调用在操作磁盘文件时不会直接发起磁盘访问(读写磁盘硬件), 而是仅仅在用户空间缓冲区和内核缓冲区之间复制数据,在后续的某个时刻,内核会将其缓冲区中的数据写入(刷新至)磁盘中,所以由此可知,调用 write()写入到磁盘文件中的数据并不会立马写入磁盘,而是会先缓存在内核缓冲区中,所以就会出现 write()操作与磁盘操作并不同步,也就是数据不同步。

2023-05-24 19:47:52 813

原创 【Linux高级 I/O(5)】初识存储映射 I/O——mmap()和 munmap()(附代码示例)

对于这个问题的答案,我们首先需要了解到,对于 mmap()函数来说, 当文件成功被映射到内存区域时,这段内存区域(映射区)的大小通常是页大小的整数倍,即使参数 length 并不是页大小的整数倍。存储映射 I/O(memory-mapped I/O)是一种基于内存区域的高级 I/O 操作,它能将一个文件映射到进程地址空间中的一块内存区域中,当从这段内存中读数据时,就相当于读文件中的数据(对文件进行 read 操 作),将数据写入这段内存时,则相当于将数据直接写入文件中(对文件进行 write 操作)。

2023-05-23 11:37:34 1787

原创 【Linux高级 I/O(4)】异步 IO实例及其优化(全文代码)

上一小节介绍了异步 I/O 的原理以及使用方法,在一个需要同时检查大量文件描述符(譬如数千个)的应用程序中,例如某种类型的网络服务端程序,与 select()和 poll()相比,异步 I/O 能够提供显著的性能优势。O_ASYNC 标志可用于使能文件描述符的异步 I/O 事件,当文件描述符可执行 I/O 操作时,内核会向异步 I/O 事件的接收进程发送 SIGIO 信号(默认情况下),该标志主要用于异步 I/O。为文件描述符设置异步 I/O 事件的接收进程,也就是设置异步 I/O 的所有者。

2023-05-22 11:44:05 895

原创 【Linux高级 I/O(3)】如何使用阻塞 I/O 与非阻塞 I/O?——poll()函数

如果可以执行 I/O 操作时,应在应用程序中对该文件描述符执行 I/O 操作,以清除文件描述符的就绪态,如果不清除就绪态,那么该状态将会一直存在,那么下一次调用 select()时,文件描述符已经处于就绪态了,将直接返回。当 poll()函数返回时,revents 变量由 poll()函数内部进行设置,用于说明文件描述符 fd 发生了哪些事件(注意,poll()没有更改 events 变量),我们可以对 revents 进行检查,判断文件描述符 fd 发生了什么事件。对于其它标志这里不再进行介绍了。

2023-05-21 10:00:00 771

原创 【Linux高级 I/O(2)】如何使用阻塞 I/O 与非阻塞 I/O?——select()函数

系统调用 select()可用于执行 I/O 多路复用操作,调用 select()会一直阻塞,直到某一个或多个文件描述符成为就绪态(可以读或写)。

2023-05-20 10:00:00 1023

原创 【Linux高级 I/O(1)】如何使用阻塞 I/O 与非阻塞 I/O?

本系列再次回到文件 I/O 相关话题的讨论,将会介绍文件 I/O 当中的一些高级用法,以应对不同应用场合的需求,主要包括:非阻塞 I/O、I/O 多路复用、异步 I/O、存储映射 I/O 以及文件锁。

2023-05-19 10:00:00 573

空空如也

空空如也

TA创建的收藏夹 TA关注的收藏夹

TA关注的人

提示
确定要删除当前文章?
取消 删除