Qt/C++概念学习笔记

/**************************************************Qt**************************************************/
        在 Qt 中,QMainWindow、QWidget和QDialog都是非常重要的类,它们都继承自QObject,但在功能和应用场景上存在一些区别:
1、QMainWindow
    用途:
        通常用于创建应用程序的主窗口,为用户界面提供一个结构化的框架,包含了菜单、工具栏、状态栏等常见的用户界面元素。它适用于开发像文本编辑器、图像编辑器、集成开发环境(IDE)等复杂的桌面应用程序。
    特点:
        内置布局区域:QMainWindow有几个特定的布局区域,如中央部件区域(centralWidget)、顶部菜单栏(menuBar)、工具栏区域(addToolBar)和状态栏(statusBar)。中央部件区域用于放置主要的内容,比如在文本编辑器中,文本编辑框就是中央部件;菜单栏可以添加各种菜单选项,如 “文件”“编辑”“视图” 等;工具栏可以放置常用功能的快捷按钮;状态栏用于显示一些状态信息,如当前文件路径、光标位置等。
        支持多文档界面(MDI):可以通过QMdiArea类实现多文档界面,允许在主窗口内同时打开多个子窗口,方便用户同时处理多个文档或任务,例如一些图形设计软件可以同时打开多个图形文件进行编辑。
        有默认的窗口行为:如最大化、最小化、关闭按钮等,并且可以对这些行为进行自定义设置,还支持窗口状态的保存和恢复,比如记住用户上次关闭窗口时的大小和位置。

2、QWidget
    用途:
        是所有用户界面对象的基类,几乎所有可视化控件(如按钮、标签、文本框等)都直接或间接继承自QWidget。它提供了基本的绘制、事件处理、几何管理等功能,开发者可以通过继承QWidget来创建自定义的控件或容器,用于构建各种复杂的用户界面。
    特点:
        灵活性高:没有预设的布局和特定功能区域,开发者可以自由地在QWidget上添加子控件,并通过布局管理器(如QVBoxLayout、QHBoxLayout、QGridLayout等)来管理子控件的位置和大小,实现各种个性化的界面布局。
        事件处理基础:QWidget提供了丰富的事件处理函数,如paintEvent(用于绘制界面)、mousePressEvent(处理鼠标按下事件)、keyPressEvent(处理键盘按下事件)等,通过重写这些函数,可以实现自定义的交互逻辑。
        可以作为独立窗口或子控件:当QWidget作为独立窗口使用时,它就是一个简单的空白窗口,可以通过设置窗口标志(windowFlags)来改变其外观和行为,如设置为模态窗口、无框架窗口等;同时,它也可以作为其他QWidget的子控件,形成嵌套的界面结构。

3、QDialog
    用途:
        主要用于创建对话框窗口,用于与用户进行临时交互,比如显示提示信息、让用户输入额外的信息、确认操作等。常见的对话框有消息对话框(QMessageBox)、文件对话框(QFileDialog)、颜色对话框(QColorDialog)等,这些对话框类都继承自QDialog。
    特点:
        模态和非模态:可以设置为模态对话框,即当对话框显示时,用户必须先对对话框进行操作(如点击确定、取消按钮),才能操作其他窗口;也可以设置为非模态对话框,用户可以在对话框显示的同时,继续操作其他窗口。
        有标准按钮和返回值:通常包含一些标准按钮,如 “确定”“取消”“应用” 等,并且可以通过exec函数以模态方式显示对话框,并获取用户点击按钮后的返回值,方便判断用户的操作意图,例如:
        用于临时交互:对话框的生命周期通常较短,主要用于完成特定的交互任务后就关闭,不像主窗口那样长期存在并作为应用程序的主要操作界面。
        
4、 信号与槽(消息/信号机制)
    信号与槽是一种独特的对象间通信机制,主要用于实现事件驱动编程。
    信号(Signal):当对象的内部状态因某些操作而发生改变时,就会发出信号。信号的本质是特殊的函数,无需用户编写具体实现,由 moc(Meta-Object Compiler)自动生成。它不包含复杂逻辑,仅用于触发相应操作。
    槽(Slot):槽实际上就是普通的 C++ 成员函数(一段响应代码),不过它可以和信号关联起来。当与之关联的信号被发出时,这个槽函数就会被调用。槽函数可以像普通函数一样被手动调用。
    应用场景:
        GUI 事件处理:比如按钮的点击事件会发出clicked()信号,我们可以将其与某个槽函数连接,在槽函数中处理点击后的操作。
        跨对象通信:不同的对象之间可以通过信号与槽进行通信,实现解耦。
        状态变化通知:当对象的状态发生改变时,可以发出信号,通知其他相关对象。

5、Qt 的 win32 GUI 概念
    Qt 是一个跨平台的 C++ 应用程序框架,最初由挪威 Trolltech 公司开发,用于开发图形用户界面(GUI)应用程序。虽然 Qt 是跨平台的,但它在 Windows 平台上能够与 Win32 API 进行交互,利用 Windows 原生的 GUI 功能。Win32 GUI 是指 Windows 操作系统提供的原生图形用户界面编程接口,它是 Windows 平台上最底层的 GUI 编程接口。Qt 通过抽象层将 Win32 API 封装起来,使开发者可以使用统一的 Qt API 编写代码,而不必关心底层的 Win32 实现细节。

6、Qt 体系结构
    Qt 的体系结构采用了模块化设计,主要由以下几个部分组成:
    核心模块:提供了 Qt 的基础功能,如对象模型、内存管理、字符串处理、容器类、输入 / 输出、网络编程等。
    GUI 模块:负责图形用户界面的实现,包括窗口系统、事件处理、2D 绘图、基本控件等。
    网络模块:提供了网络编程的支持,包括 TCP/IP、UDP、HTTP 等协议的实现。
    数据库模块:支持与各种数据库系统的交互,如 SQLite、MySQL、PostgreSQL 等。
    XML 模块:提供了 XML 文档的解析和生成功能。
    多线程模块:支持多线程编程,提供了线程、互斥锁、信号量等线程同步机制。
    OpenGL 模块:提供了对 OpenGL 图形库的支持,用于实现高性能的 3D 图形渲染。
    WebKit 模块:集成了 WebKit 引擎,使 Qt 应用程序能够显示和处理网页内容。
    其他模块:还包括多媒体、位置信息、传感器、蓝牙、NFC 等功能模块,根据不同的平台和需求可以选择性地使用。
    
7、消息 / 信号机制
    Qt 采用了独特的信号与槽(Signals and Slots)机制来处理对象间的通信,这是 Qt 区别于其他 GUI 框架的一个重要特性。传统的 Win32 GUI 编程使用 Windows 消息机制,当用户与界面交互或系统发生某些事件时,操作系统会发送相应的消息到应用程序的窗口过程函数(Window Procedure),应用程序需要在窗口过程函数中处理这些消息。而 Qt 的信号与槽机制是一种类型安全的对象间通信方式,它比传统的回调函数更加灵活和安全。
    信号(Signals):当对象的内部状态发生改变时,对象会发出信号。信号是由 MOC(Meta-Object Compiler)自动生成的特殊函数,通常在头文件中声明,不需要在源文件中实现。
    槽(Slots):槽是用于接收信号的特殊函数。槽函数的声明和实现与普通的 C++ 成员函数相同,但需要使用 Q_OBJECT 宏和相应的关键字来声明。
    连接(Connect):信号和槽之间需要通过 QObject::connect () 函数进行连接,建立信号与槽之间的关联。当信号被发出时,与之连接的槽函数会被自动调用。
    
8、常见组件
    Qt 提供了丰富的 GUI 组件(也称为控件或部件),用于构建各种用户界面。这些组件可以分为以下几类:
    基本控件:如 QLabel(标签)、QPushButton(按钮)、QLineEdit(单行文本框)、QTextEdit(多行文本框)、QComboBox(下拉列表框)、QCheckBox(复选框)、QRadioButton(单选按钮)等。
    容器控件:如 QWidget(所有界面组件的基类)、QFrame(带有边框的容器)、QGroupBox(带有标题的容器)、QTabWidget(选项卡控件)、QScrollArea(滚动区域)等。
    布局管理器:用于自动管理界面组件的位置和大小,如 QHBoxLayout(水平布局)、QVBoxLayout(垂直布局)、QGridLayout(网格布局)、QFormLayout(表单布局)等。
    高级控件:如 QListWidget(列表控件)、QTreeWidget(树形控件)、QTableWidget(表格控件)、QProgressBar(进度条)、QSlider(滑块)、QCalendarWidget(日历控件)等。
    对话框:如 QMessageBox(消息框)、QFileDialog(文件对话框)、QColorDialog(颜色对话框)、QFontDialog(字体对话框)等。
    自定义控件:Qt 允许开发者通过继承现有控件或直接从 QWidget 派生来自定义控件,以满足特定的界面需求。
    容器组件下面只能有一种布局,但是布局中可以增加其他组件


9、Lambda表达式
    1)基本用法​
        Lambda 是 C++11 匿名函数特性,在 Qt 信号槽中语法简化为:[捕获列表](参数列表) { 函数体 }
        核心部分功能如下:​
            捕获列表:控制外部变量访问,[this]可访问当前类成员(最常用),[=]按值捕获(只读),[&]按引用捕获(可修改)。​
            参数列表:需与信号参数匹配,接收信号传递的数据。​
            函数体:信号触发时执行的逻辑,替代传统槽函数。​
        不带参数的绑定:
            QPushButton *btn = new QPushButton("点击", this);
            // 信号:btn的clicked();槽:Lambda表达式//捕获列表 [] 表示不捕获外部变量,适合逻辑简单的场景。
            connect(btn, &QPushButton::clicked, this, []() {
                qDebug() << "按钮被点击了!";
            });
        带参数的绑定:
            // 假设Teacher类有信号:void hungry(QString food);
            Teacher *teacher = new Teacher(this);
            connect(teacher, &Teacher::hungry, this, [](QString food) {
                qDebug() << "老师想吃:" << food; // 直接处理信号传递的参数
            });
        
    2)核心作用​
        简化代码:无需在.h 和.cpp 中单独声明实现槽函数,直接在connect中写逻辑,减少代码跳转。​
        精准绑定:轻松处理信号重载场景,用static_cast指定信号版本即可,避免函数指针定义的繁琐。​
        灵活适配:通过捕获列表访问外部变量或类成员,适配简单交互逻辑(如按钮点击更新 UI、定时器临时操作)。​
        适用于逻辑简单(单行或少量代码)、无需复用的场景,与传统槽函数互补,提升开发效率。
        
        

        
/**************************************C++*****************************************************/
1、类和对象(类是对象的模板,而对象是类的一个实例)
    类(Class)
        定义:类是一种用户自定义的数据类型,它是对具有相同属性(数据成员)和行为(成员函数)的一组对象的抽象描述。可以把类看作是一个 “模板” 或者 “蓝图”,用于创建对象。
        组成部分:
            数据成员:用于描述类所代表事物的属性,本质上就是类中的变量。比如在描述 “学生” 类时,数据成员可能有 name(姓名)、age(年龄)、studentID(学号)等。
            成员函数:用于描述类所代表事物的行为,本质上是类中的函数。同样以 “学生” 类为例,成员函数可能有 study()(学习)、takeExam()(参加考试) 等。
        访问控制:通过访问修饰符来控制对类成员的访问权限:
            public(公有):类的成员在类外部可以直接访问。
            private(私有):类的成员只能在类内部被访问,类外部无法直接访问,这有助于保护数据的安全性。
            protected(受保护):与 private 类似,区别在于派生类(子类)可以访问基类(父类)中 protected 修饰的成员 。
    对象(Object)
        定义:对象是类的一个实例,是根据类这个 “模板” 创建出来的具体实体。可以把对象理解为按照类的蓝图建造出来的一个个具体的 “产品”。
        特点:每个对象都拥有自己独立的存储空间,用于存储数据成员的值。不同对象之间的数据成员是相互独立的,但它们共享类中成员函数的代码。单个对象被创建时,它们继承了类中所有的变量和功能。

2、C++ 中的类​
    类是 C++ 面向对象编程的核心概念,是对现实事物的抽象描述,它封装了数据(属性)和操作数据的方法(成员函数)。
    类的核心特性包括:​
        封装性:将数据和方法隐藏在类内部,通过访问控制符(public、private、protected)控制外部对类成员的访问,仅暴露必要接口,提高代码安全性和可维护性。​
        继承性:允许一个类(子类)继承另一个类(父类)的属性和方法,子类可在此基础上扩展新功能或重写父类方法,实现代码复用和层级关系构建。​
        多态性:通过虚函数实现,允许子类重写父类的虚函数,使得不同对象调用同一接口时呈现不同行为,增强代码的灵活性和扩展性。
        
3、模板技术(泛型)​
    模板技术是 C++ 实现泛型编程的核心机制,它允许开发者编写与数据类型无关的代码,提高代码复用性和灵活性。
    typename与class的区别:在函数模板中,typename和class完全等价例如template<class T>与template<typename T>功能相同。但typename更直观地表达 “T 是类型” 的含义,推荐优先使用。
    模板主要分为函数模板和类模板:​
        函数模板:定义一个通用函数,支持多种数据类型作为参数,编译器会根据实际调用的参数类型自动生成对应类型的函数实例。​
        类模板:定义一个通用类,类中的成员变量和成员函数可使用模板参数指定类型,适用于实现通用数据结构(如容器类)。
    template<typename T>的详细解释:
        template<typename T>是函数模板(Function Template)的声明语法,它是实现泛型编程的基础,用于定义可以适配多种数据类型的通用函数。
    1)语法构成与含义
        template关键字:这是 C++ 中用于声明模板的关键字,告诉编译器 “接下来定义的是一个模板(而非普通函数或类)”,需要按照模板的规则进行编译处理。
        <typename T>模板参数列表:
            typename:用于声明 “模板类型参数” 的关键字,也可以替换为class(两者在函数模板中功能完全相同),表示 “T 是一个类型占位符”。
            T:这是类型参数的名称(可以自定义,如template<typename Type>或template<typename Data>),它代表 “任意数据类型”,在函数调用时会被具体类型(如int、double、string等)替换。
            例如template<typename T>的字面含义是:“声明一个模板,该模板有一个类型参数 T,T 可以是任意数据类型”。
    2)核心作用:实现泛型编程
        template<typename T>的核心作用是让函数摆脱 “固定数据类型” 的限制,实现 “一份代码适配多种类型”。
        具体体现在:
            类型抽象:将函数中的具体类型(如int)替换为抽象的类型参数T,使函数逻辑与数据类型解耦。例如你的交换函数:
            // 普通函数(仅支持int类型)
                void swapInt(int& a, int& b) { ... }
            // 模板函数(支持所有类型)
                template<typename T>
                void mySwap(T& a, T& b) { ... }
            模板函数mySwap通过T适配int、char、string等各种类型,无需为每种类型单独编写函数。
            编译器自动生成具体函数:当调用模板函数时(如mySwap(x, y)其中x和y是int类型),编译器会自动执行 “模板实例化”:用实际类型(int)替换T,生成针对该类型的具体函数(如void mySwap(int& a, int& b))。这个过程在编译期完成,不影响运行效率。
    3)使用规则与注意事项
        必须位于函数定义之前:template<typename T>必须直接放在模板函数定义的上方,两者之间不能有其他代码。
        例如:
            // 正确写法
            template<typename T>
            void mySwap(T& a, T& b) { ... }

            // 错误写法(中间有其他代码)
            template<typename T>
            int temp; // 不允许,模板声明后必须紧跟模板定义
            void mySwap(T& a, T& b) { ... }

        类型参数的作用域:T的作用范围仅限于当前模板函数,即仅在mySwap函数体内有效,其他函数无法直接使用该T。
        多个类型参数:如果函数需要适配多种不同类型,可以声明多个类型参数,
        例如:
            // 支持两种不同类型的模板
            template<typename T1, typename T2>
            void printPair(T1 a, T2 b) {
                cout << a << " " << b << endl;
            }
            // 调用时自动匹配类型
            printPair(10, "hello"); // T1=int,T2=string
            printPair(3.14, 'A');  // T1=double,T2=char

4、STL(标准模板库)​
    STL 是 C++ 标准库的重要组成部分,基于模板技术实现,提供了一系列通用数据结构和算法,简化了 C++ 编程。STL 的核心优势是代码复用和高效性,开发者无需重复实现基础数据结构和算法,可直接使用经过优化的 STL 组件,大幅提升开发效率。
    STL 主要包含以下组件:​
        容器(Containers):用于存储数据的通用数据结构,分为序列式容器(如vector动态数组、list双向链表、deque双端队列)和关联式容器(如map键值对映射、set集合、unordered_map哈希表)。容器封装了数据存储逻辑,提供统一的访问接口(如push_back()、size()、begin()/end()迭代器)。​
        算法(Algorithms):用于操作容器中数据的通用函数,如排序(sort())、查找(find())、遍历(for_each())、复制(copy())等。算法与容器分离,通过迭代器访问容器元素,支持对不同容器执行相同操作。​
        迭代器(Iterators):连接容器和算法的桥梁,提供类似指针的接口,用于遍历容器元素。不同容器的迭代器具有统一的操作方式(如++移动、*取值),使算法能独立于具体容器类型。​
        函数对象(Function Objects):重载()运算符的类对象,可作为算法的参数(如less<>用于排序比较),实现自定义操作逻辑。​
        
5、T&的含义:引用类型声明
    T&表示 “T 类型的引用”,其中&是引用声明符。引用是 C++ 中一种特殊的变量类型,它相当于变量的 “别名”,与原变量共享同一块内存空间。在函数参数中使用T& a,表示参数a是传入变量的引用。
    具体作用包括:
        直接操作原变量:当函数内部修改a的值时,会直接影响外部传入的原变量,这也是你的交换函数能实现变量值交换的核心原因(如果用T a传值,只会修改副本,原变量不变)。
        避免数据拷贝:对于大型对象(如自定义类、字符串),传引用可以避免参数传递时的拷贝操作,提高程序效率。
        例如在你的交换函数中:
            template<typename T>
            void mySwap(T& a, T& b) { // a和b是传入变量的引用
                T temp = a; // 相当于使用原变量的值
                a = b;      // 直接修改原变量的值
                b = temp;
            }
        当调用mySwap(x, y)时,a是x的别名,b是y的别名,交换a和b本质上就是交换x和y。
    &在 C++ 中有两种主要用法:
        作为引用声明符时,必须紧跟在类型名之后(如int&、T&),表示 “某类型的引用”。
        作为取地址运算符时,用于获取变量的地址(如&x表示变量x的内存地址)。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值