Windows编程[下]

Windows编程[下]

  • 一、线程
    • 1. 内核对象
    • 2.多线程群聊服务器
    • 3.多线程群聊客户端
    • 4.线程同步之事件对象
      • 常用函数和参数解释
  • 二、进程
  • 三、Qt
    • 1.第一个Qt项目
    • 2.Qt助手的使用
    • 3.QPushButton简介
    • 4.Qt对象树
      • 对象树的基本概念
      • 使用对象树模式的好处
      • 对象树的问题
    • 5.信号与槽
      • 5.1 自定义信号和槽(不带参数版本)
      • 5.2 自定义信号和槽(带参数版本和重载)
      • 5.3 信号和槽的扩展
        • 5.3.1 信号和槽的参数匹配
        • 5.3.2 多对多连接
        • 5.3.3 信号连接信号
        • 5.3.4 使用lambda表达式
    • 6.QTextEdit控件
      • 信号
    • 7.QMainWindow
      • 7.1 添加菜单栏
      • 7.2 添加工具栏
      • 7.3 添加状态栏
      • 7.4 中心部件、铆接部件
    • 8.Qt乱码解决
    • 9.Ui设计器
      • 9.1 添加资源文件
      • 9.2 对话框(模态、非模态)
      • 9.3 QMessageBox对话框
      • 9.4 基本对话框

一、线程

1. 内核对象

在 Windows 操作系统中,内核对象(Kernel Objects)是系统资源的抽象,用于管理和协调系统的底层功能。内核对象可以被应用程序、系统进程和操作系统自身使用。这些对象的创建、使用和管理通常通过 Windows API 完成。下面详细介绍内核对象及其特点:

内核对象的特点:

  1. 资源管理:内核对象用于管理各种系统资源,如内存、进程、线程、文件、设备等。
  2. 安全性:内核对象具有安全属性,允许系统定义哪些用户或进程可以访问或操作这些对象。
  3. 引用计数:内核对象通常具有引用计数机制,确保在不再需要时自动释放资源。
  4. 句柄访问:用户模式进程通过句柄(Handle)来访问内核对象,而内核模式下则直接操作内核对象。

以下是一些常见的内核对象及其用途:

  1. 进程(Process)和线程(Thread)对象:用于管理和调度系统中的进程和线程。
  2. 文件(File)对象:用于管理文件系统中的文件和目录。
  3. 同步对象:
    • 互斥体(Mutex):用于在线程间同步访问共享资源。
    • 信号量(Semaphore):用于控制同时访问资源的线程数量。
    • 事件(Event):用于线程间的信号通知。
    • 等待链(Waitable Timer):用于定时操作。
  4. I/O 完成端口(I/O Completion Port)对象:用于高效处理异步 I/O 操作。
  5. 设备(Device)对象:用于与硬件设备交互。
  6. 节(Section)对象:用于共享内存的进程间通信。
  7. 注册表(Registry)对象:用于管理系统配置和应用程序的设置信息。

内核对象的使用计数与生命周期:

  1. 所有者:内核对象的所有者是操作系统内核,而非进程。这意味着即使进程退出,内核对象也不一定会销毁。
  2. 使用计数:操作系统内核通过内核对象的使用计数(Reference Count)来跟踪当前有多少个进程正在使用某个内核对象。初次创建内核对象时,使用计数为 1。当一个进程获取该内核对象的访问权之后,使用计数加 1。如果内核对象的使用计数减少为 0,操作系统内核就会销毁该内核对象。这就是说,内核对象在当前进程中创建,但在当前进程退出时,内核对象有可能被另外一个进程访问。

2.多线程群聊服务器

服务器:

  • 对于每一个上线的客户端,都开辟一个线程去维护。

  • 将收到的消息转发给全部客户端

image-20240703160533412

image-20240703160632713

image-20240703160746003

image-20240703160813806

3.多线程群聊客户端

客户端:

  • 请求连接(上线)
  • 发送消息:等待用户从控制台输入,然后发送给服务端
  • 等待服务端发送消息,收到数据后输出到控制台
  • 等待用户关闭(下线) -> q

image-20240703160847812

image-20240703160912226

image-20240703160929908

image-20240703160946824

image-20240703161001598

image-20240703160426081

image-20240703160457987

4.线程同步之事件对象

什么是事件对象?

事件对象就像一个小信号灯,可以用来控制多个程序(线程)之间的协调工作。想象一下,有一个红绿灯可以让不同的线程知道什么时候可以继续,什么时候需要等待。

事件对象是一种同步原语,它可以用来协调线程之间的操作。

事件对象通常有两种状态:已触发(set)和未触发(reset)。通过设置和重置事件对象的状态,我们可以控制线程的执行。

  • 已触发(set):当事件对象被设置为已触发状态时,所有等待这个事件的线程都会被唤醒,继续执行。
  • 未触发(reset):当事件对象被设置为未触发状态时,所有等待这个事件的线程都会被阻塞,直到事件被触发。

常用函数和参数解释

在 Windows 编程中,我们可以使用一些特定的函数来创建和操作事件对象。这些函数包括 CreateEventSetEventResetEventWaitForSingleObject。让我们逐个来看。

CreateEvent 函数

这个函数用来创建一个事件对象。

HANDLE CreateEvent(
  LPSECURITY_ATTRIBUTES lpEventAttributes,
  BOOL                  bManualReset,
  BOOL                  bInitialState,
  LPCTSTR               lpName
);

参数解释:

  1. lpEventAttributes:这个参数一般设为 NULL,表示使用默认的安全属性。
  2. bManualReset:这个参数决定事件是手动重置还是自动重置。设为 TRUE 表示手动重置(需要我们自己调用 ResetEvent),设为 FALSE 表示自动重置(系统会自动重置)。
  3. bInitialState:这个参数决定事件初始状态是触发(TRUE)还是未触发(FALSE)。大多数情况下设为 FALSE
  4. lpName:事件的名字,可以设为 NULL 表示匿名事件。如果需要多个程序共享同一个事件,可以给它起个名字。

SetEvent 函数

这个函数用来触发事件,相当于把信号灯变成绿色,让等待的线程继续执行。

BOOL SetEvent(
  HANDLE hEvent
);

ResetEvent 函数

这个函数用来重置事件,相当于把信号灯变成红色,阻止线程继续执行。

BOOL ResetEvent(
  HANDLE hEvent
);

WaitForSingleObject 函数

这个函数用来让线程等待事件的触发,相当于在线程面前设置一个信号灯,等待信号灯变绿(事件被触发)。

DWORD WaitForSingleObject(
  HANDLE hHandle,
  DWORD  dwMilliseconds
);

参数解释:

  1. dwMilliseconds:这是等待的时间,单位是毫秒。如果设为 INFINITE,表示一直等到事件被触发。

二、进程

三、Qt

1.第一个Qt项目

image-20240703114327861

创建一个按钮并且弹出对话框。

image-20240703214406324

image-20240703214431757

image-20240703215033570

2.Qt助手的使用

image-20240703222135381

image-20240703222407464

3.QPushButton简介

image-20240703220526247

image-20240703221018040

image-20240703221630741

image-20240703221816917

4.Qt对象树

在 Qt 中,对象树就像是一个家庭树(Family Tree),它表示了对象之间的父子关系。每个对象都可以有一个“父亲”(Parent)和很多“孩子”(Children)。

为什么需要对象树?

对象树帮助我们组织和管理程序中的对象。通过建立父子关系,可以方便地控制对象的生命周期,也就是对象什么时候创建和销毁。

对象树的基本概念

  1. 父对象(Parent):一个对象可以有一个父对象。当父对象被销毁时,它的所有子对象也会被自动销毁。
  2. 子对象(Children):一个对象可以有多个子对象。子对象通常依赖于父对象。

想象你有一个小玩具车(父对象),上面有几个人(子对象)。如果你把玩具车扔掉(销毁父对象),车上的人(子对象)也会跟着被扔掉(销毁)。

使用对象树模式的好处

自动内存管理:

  • 当一个父对象(比如窗口)被销毁时,它的所有子对象(比如按钮、标签、文本框)也会自动被销毁。
  • 这意味着你不需要手动删除每一个子对象,从而减少了编写和维护代码的工作量。

例子解释:

假设你有一个应用程序窗口(Window),窗口里面有一个标签(Label),一个文本输入框(TextEdit),和一个按钮(Button)。这些元素都是窗口的子对象。

  • 传统方法:你需要手动删除标签、文本输入框和按钮,这样非常麻烦。
  • 使用对象树模式:当你关闭窗口时,Qt 会自动删除窗口和所有它的子对象(标签、文本输入框和按钮)。

对象树的问题

如果button创建在栈空间,那么当代码块执行结束后,系统会自动回收,同时点击对话框[X]退出,又会通过对象树析构,造成程序崩溃。

int main(int argc, char *argv[])
{
    QApplication a(argc, argv);
    QPushButton button;
    Widget w;
    button.setParent(&w);
    button.setText("崩溃之源");
    w.show();
    return a.exec();
}

如果这样写,就不会:

int main(int argc, char *argv[])
{
    QApplication a(argc, argv);
    Widget w;
    QPushButton button;
    button.setParent(&w);
    button.setText("崩溃之源");
    w.show();
    return a.exec();
}

在 C++ 中,对象的销毁顺序与它们的定义顺序相反。也就是说,先定义的对象最后被销毁,后定义的对象先被销毁。

在当前代码中,QPushButton button 的生命周期依赖于 Widget w。当 Widget w 被定义在 button 前面时,它在 button 之后销毁,这样在 button 被销毁时,它的父对象 w 仍然存在,不会产生问题。

在 Qt 中,确保父对象在子对象之前定义是很重要的,这样可以避免在父对象销毁时子对象被二次释放的问题。

5.信号与槽

信号与槽机制是 Qt 框架中的一种独特的通信方式,用于对象之间的消息传递。想象一下,当你按下遥控器的按钮时,电视机会响应这个动作。这里,按下按钮就像是发出一个信号,而电视机的响应就像是槽函数。

**信号(Signal)😗*信号是对象发出的消息。它表示某个事件发生了。信号不做任何处理,只是发出通知。

槽(Slot):槽是一个函数,它会对信号做出反应。当信号发出时,连接到该信号的槽函数就会被调用。

举个例子:

想象你有一个按钮,当你点击这个按钮时,显示一个消息框。这就涉及到一个信号和一个槽:

  • 信号:按钮被点击。
  • :显示消息框的函数。

使用 connect(button, &QPushButton::clicked, this, &MyWidget::showMessage) 函数,将信号与槽函数连接起来。

connect函数的参数依次是:

  • 发射信号的对象(button
  • 信号(&QPushButton::clicked
  • 接收信号的对象(this
  • 槽函数(&MyWidget::showMessage

在父类中找到按钮支持的信号类型。

image-20240704205326333

image-20240704205411024

image-20240704215540783

5.1 自定义信号和槽(不带参数版本)

假设我们写一个表白的信号与槽,boy类有一个表白信号,girl有一个回应的槽。

image-20240704222428385

image-20240704222444848

image-20240704222523891

image-20240704224109371

5.2 自定义信号和槽(带参数版本和重载)

这里我们love函数传递一个QString参数给女孩对象,女孩对象也使用这个传递过来的参数。

image-20240704231606150

image-20240704231630553

image-20240704232526723

image-20240704232541999

5.3 信号和槽的扩展

5.3.1 信号和槽的参数匹配

在Qt的信号和槽机制中,信号和槽的参数匹配需要遵循一定的规则:

  1. 参数数量:信号的参数数量可以多于槽函数的参数数量,但不能少于槽函数的参数数量。也就是说,信号的参数可以被槽函数部分接收。例如,如果一个信号有三个参数,而槽函数只有两个参数,那么信号的前两个参数会传递给槽函数,第三个参数会被忽略。
  2. 参数类型:信号和槽函数对应参数的类型必须兼容。这意味着信号的参数类型必须能够隐式转换为槽函数的参数类型。

image-20240707085927177

image-20240707090102874

5.3.2 多对多连接

Qt允许一个信号连接多个槽函数,也允许一个槽函数连接多个信号。

5.3.3 信号连接信号

在Qt中,一个信号也可以连接到另一个信号。这种机制允许我们将信号链式传递,从而简化复杂的信号处理逻辑。

5.3.4 使用lambda表达式

Qt 5引入了对C++11 lambda表达式的支持,使得我们可以使用lambda表达式作为槽函数。这特别有用,可以将不具备参数的信号连接到具备参数的槽函数,或者进行更复杂的信号处理逻辑。

image-20240707093738230

6.QTextEdit控件

image-20240707110408025

image-20240707111419368

信号

image-20240707112015509

7.QMainWindow

QMainWindow 是 Qt 框架中用于创建主窗口的类,提供了一个标准化的应用程序主窗口框架。QMainWindow 继承自 QWidget,但添加了一些特定于主窗口的功能,如菜单栏、工具栏、状态栏和停靠窗口等。

一个典型的 QMainWindow 由以下几个主要部分组成:

  1. 菜单栏(Menu Bar):通常位于窗口顶部,用于组织和显示菜单项。
  2. 工具栏(Tool Bar):通常位于菜单栏下方,用于放置常用操作按钮。
  3. 状态栏(Status Bar):通常位于窗口底部,用于显示应用程序的状态信息。
  4. 中心窗口部件(Central Widget):主窗口的核心部分,通常用于显示主要内容。
  5. 停靠窗口(Dock Widgets):可以停靠在主窗口的四周,用于显示辅助工具或信息。

7.1 添加菜单栏

image-20240707115120440

7.2 添加工具栏

image-20240707141437843

image-20240707141555200

7.3 添加状态栏

image-20240707143619124

7.4 中心部件、铆接部件

image-20240707145658836

8.Qt乱码解决

image-20240707142357039

image-20240707143515787

9.Ui设计器

image-20240707153645853

image-20240707153731706

image-20240707154130808

9.1 添加资源文件

image-20240707161549744

image-20240707162822584

image-20240707163148099

9.2 对话框(模态、非模态)

标准对话框可以类比为我们在日常生活中购买的智能手机中的内置应用,比如相机、短信、电话等。用户只需要调用这些内置功能即可,无需再去开发新的相机应用。Qt中的标准对话框就是这样的“内置应用”,它们已经提供了基本的功能,开发者只需调用即可。

常见的标准对话框:

  1. QColorDialog:选择颜色的对话框。
  2. QFileDialog:选择文件或目录的对话框。
  3. QFontDialog:选择字体的对话框。
  4. QInputDialog:允许用户输入一个值,并将其返回的对话框。
  5. QMessageBox:模态对话框,用于显示信息、询问问题等。

这些对话框几乎可以满足所有应用程序中常见的交互需求,因此没有必要在每个程序中都重新实现这些对话框。

image-20240707170028431

9.3 QMessageBox对话框

image-20240708042933542

image-20240708043122029

image-20240708043341294

image-20240708043619191

image-20240708043639199

image-20240708043655424

9.4 基本对话框

image-20240708045042070

image-20240708045359384

image-20240708045413755

image-20240708050439438

image-20240708050021385

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mfbz.cn/a/782530.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

通用的职位招聘小程序ui模板

蓝色简单的校园招聘,行业招聘,职位招聘手机小程序页面模板。包含:职位列表、职位详情、基本信息填写、登录、个人主页、消息页面等功能 通用的职位招聘小程序ui模板

InvalidVersionSpecError: Invalid version spec: =2.7解决方案

大家好,我是爱编程的喵喵。双985硕士毕业,现担任全栈工程师一职,热衷于将数据思维应用到工作与生活中。从事机器学习以及相关的前后端开发工作。曾在阿里云、科大讯飞、CCF等比赛获得多次Top名次。现为CSDN博客专家、人工智能领域优质创作者。喜欢通过博客创作的方式对所学的…

驾校管理系统的全面革新与升级

智慧驾校系统是一款专为现代驾校量身定制的综合性管理平台,它深度融合了云计算、大数据、物联网及人工智能等前沿技术,旨在为驾校打造一个高效、智能、便捷的运营生态系统。该系统通过数字化、信息化的手段,彻底革新了传统驾校的管理模式,不仅极大地提升了驾校的运营效率,…

初识Spark

一、简介 官网:Apache Spark™ - Unified Engine for large-scale data analytics Apache的顶级项目,用于大规模数据处理的统一分析引擎。 支持语言:Java、Scala、Python和R (源码为Scala) 高级工具: 1、SparkSQL用于SQL和结构…

ARM汇编与机器码、汇编指令

文章目录 1. CISC与RISC指令集 2. ARM汇编指令 3. 汇编与机器码 4. 汇编指令格式 5. MOV指令 6. BL指令 7. B指令 8. ADD/SUB指令 9. LDR/STR指令 1. CISC与RISC指令集 根据指令的复杂度,所有CPU可以分为两类: CISC(Complex Instr…

破局 AI 2.0 时代:利用 AI 提升自我核心竞争力

文章目录 破局 AI 2.0 时代:利用 AI 提升自我核心竞争力1. AI 2.0 时代1.1 特点1.2 发展1.3 影响 2. AI 2.0 时代的机遇 & 挑战2.1 AI 对行业市场的冲击2.2 挑战变为机遇2.3 不同场景下的 AI 效能提升2.3.1 自动化办公任务2.3.2 提升学习效率2.3.3 创意生成与内…

SpringBoot彩蛋之定制启动画面

写在前面 在日常开发中,我们经常会看到各种各样的启动画面。例如以下几种 ① spring项目启动画面 ② mybatisplus启动画面 ③若依项目启动画面 还有很多各式各样好看的启动画面,那么怎么定制这些启动画面呢? 一、小试牛刀 ① 新建一个Spr…

【分布式系统三】监控平台Zabbix对接grafana(截图详细版)

目录 一.安装grafana并启动 二.浏览器访问 三.导入zabbix数据,对接grafana 四.如何导入模版 以前两篇博客为基础 【分布式系统】监控平台Zabbix介绍与部署(命令截图版)-CSDN博客 【分布式系统】监控平台Zabbix自定义模版配置-CSDN博客 …

前端面试题(CSS篇五)

一、设备像素、css 像素、设备独立像素、dpr、ppi 之间的区别? 设备像素指的是物理像素,一般手机的分辨率指的就是设备像素,一个设备的设备像素是不可变的。 css像素和设备独立像素是等价的,不管在何种分辨率的设备上,…

网络连接线相关问题

问题1; 直通线为什么两头都是T568B?是否可以两台T5568A?或者任意线序,只需两头一致? 不行,施工规范规定。(原因;网线最长距离100m,实际用起来要把网线包管,走…

Kafka第四篇——生产数据总体概括,源码解析分区策略,数据收集器,Sender发送线程,key值

目录 流程图以及总体概述 拦截器 分区器以及分区计算策略 为啥进行分区计算? producer生产者怎么知道有哪些分区? 分区计算 如何自定义实现分区器? 想说的在图里啦!宝宝!💡 ​编辑 如果key值忘记传递了呢&a…

前端后花园周刊vol.18-React Native 称唯一推荐的社区框架是Expo

⚡️行业动态 React Native 团队推荐使用 Expo 框架构建应用程序 React Native 发文称:唯一推荐的社区框架是Expo,Expo 的开发者从 React Native 早期就开始支持 React Native 生态系统,相信 Expo 提供的开发者体验是同类中最好的。 &…

vscode调试教程

VSCode调试 VSCode Debuggers VSCode使用launch.json进行细粒度的控制,可以启动程序或将其附加到复杂的调试场景中 打开Run and Debug视图Ctrl Shift D 点击create a launch.json file,选择C(GDB/LLDB) 会在工作目录自动创建.vscode/launch.json文…

简单的基追踪一维信号降噪方法(MATLAB 2018)

基追踪法是基于冗余过完备字典下的一种信号稀疏表示方法。该方法具有可提高信号的稀疏性、实现阈值降噪和提高时频分辨率等优点。基追踪法采用表示系数的范数作为信号来度量稀疏性,通过最小化l型范数将信号稀疏表示问题定义为一类有约束的极值问题,进而转…

【linux服务器】大语言模型实战教程:LLMS大模型部署到个人服务器或嵌入式开发板(保姆级教学)

🎬 鸽芷咕:个人主页 🔥 个人专栏: 《C干货基地》《粉丝福利》 ⛺️生活的理想,就是为了理想的生活! 引言 说到大语言模型相信大家都不会陌生,大型语言模型(LLMs)是人工智能文本处理的主要类型,也现在最流行的人工智能…

julia系列17: tsp问题代码整理

1. 常用库和基础函数 这里是优化版的函数: using TSPLIB,LKH,Distances,PyPlot MaxNum 10000 tspreadTSPLIB(:att48) dist [round.(Int,euclidean(tsp.nodes[i,:],tsp.nodes[j,:])) for i in 1:tsp.dimension,j in 1:tsp.dimension]; pos(tsp::TSP,t::Vector{In…

Games101学习笔记 Lecture17 Materials and Appearances

Lecture17 Materials and Appearances 材质 BRDF一、Diffuse/Lambertian Material二、Glossy Material三、Ideal reflective/ refractive Material (BSDF)1.镜面反射2.镜面折射3.菲涅尔项 Fresnel 四、Microfacet BRDF 微表面五、Isotropic / Anisotropic Materials (BRDFs)An…

python - 文件 / 永久存储:pickle / 异常处理

一.文件 利用help(open)可以看到open()函数的定义: >>> help(open) Help on built-in function open in module _io:open(file, moder, buffering-1, encodingNone, errorsNone, newlineNone, closefdTrue, openerNone) 默认打开模式是’rt’&#xff0…

王者荣耀与和平精英的语音识别不准确怎么办?分享一次意想不到的解决经历!

文章目录 📖 介绍 📖🏡 演示环境 🏡📒 完整经历 📒🔍 问题初现 🔍🔎 排查之路:从绝望到希望的转折 🔎🎉 顿悟时刻:原来是“她”的恶作剧 🎉⚓️ 相关链接 ⚓️📖 介绍 📖 作为一位打字速度惊人的玩家,我向来自豪于能在王者荣耀和和平精英等游戏…

Three.js机器人与星系动态场景(四):封装Threejs业务组件

实际在写业务的时候不会在每个组件里都写几十行的threejs的初始化工作。我们可以 将通用的threejs的场景、相机、render、轨道控制器等进行统一初始化。同时将非主体的函数提到组件外部,通过import导入进组件。将业务逻辑主体更清晰一些。下面的代码是基于reactthre…