初识——QT
QT安装方法
一、项目创建流程
-
创建项目
-
入口:通过Qt Creator的欢迎页面或菜单栏(文件→新建项目)创建新项目。
-
项目类型:选择「Qt Widgets Application」。
-
路径要求:项目路径需为纯英文且不含特殊字符。
-
构建系统:默认选择 CMake。
-
类配置:默认生成
MainWindow
类(包含UI文件)。
-
-
配置构建套件
-
选择适用于当前平台的构建套件(如MinGW/MSVC)。
-
若CMake配置失败,需检查CMake路径或更新组件。
-
-
运行项目
-
点击「运行」按钮,生成默认窗口界面(含一个空Widget)。
-
二、工程文件解析
-
CMakeLists.txt
-
核心作用:定义项目构建规则、依赖关系及编译选项。
-
关键配置:
cmake_minimum_required(VERSION 3.10) # 指定CMake最低版本 project(qt01 VERSION 0.1 LANGUAGES CXX) # 设置项目名称及语言 set(CMAKE_CXX_STANDARD 17) # 指定C++标准为C++17 find_package(Qt6 REQUIRED COMPONENTS Widgets) # 引入Qt6 Widgets模块 add_executable(qt01 main.cpp) # 定义可执行文件 target_link_libraries(qt01 PRIVATE Qt6::Widgets) # 链接Qt库
-
注意事项:需通过
find_package
引入所需Qt模块(如Widgets、Core等)。
-
-
mainwindow.h
-
功能:声明主窗口类,继承自
QMainWindow
。 -
关键代码:
#include <QMainWindow> namespace Ui { class MainWindow; } // 前向声明UI类 class MainWindow : public QMainWindow {Q_OBJECT // 必须包含Q_OBJECT宏以支持信号与槽 public:MainWindow(QWidget *parent = nullptr);~MainWindow(); private:Ui::MainWindow *ui; // UI对象指针 };
-
-
mainwindow.cpp
-
功能:实现主窗口类的构造函数和析构函数。
-
关键代码:
#include "mainwindow.h" #include "ui_mainwindow.h" MainWindow::MainWindow(QWidget *parent) : QMainWindow(parent), ui(new Ui::MainWindow) {ui->setupUi(this); // 初始化UI(自动生成) } MainWindow::~MainWindow() { delete ui; } // 释放UI对象
-
-
main.cpp
-
功能:应用程序入口,创建主窗口并启动事件循环。
-
关键代码:
#include "mainwindow.h" #include <QApplication> int main(int argc, char *argv[]) {QApplication a(argc, argv); // 管理GUI程序生命周期MainWindow w;w.show(); // 显示窗口return a.exec(); // 进入事件循环 }
-
注意:
a.exec()
是Qt事件循环的核心,负责处理用户输入和窗口事件。
-
-
ui_mainwindow.h
-
功能:由Qt Designer自动生成的UI布局代码,描述窗口中的控件及其属性。
-
三、Qt内存管理机制
-
父子对象关系
-
规则:父对象销毁时自动删除所有子对象。
-
示例:
QWidget *parent = new QWidget; QPushButton *button = new QPushButton(parent); // button的父对象为parent delete parent; // 自动删除button
-
-
智能指针
-
QScopedPointer
:作用域内自动释放内存。 -
QSharedPointer
:引用计数智能指针,共享所有权。
-
四、UI设计与信号槽
-
拖拽控件
-
通过Qt Designer在
.ui
文件中拖拽控件(如按钮、标签)并设置属性(如文本、大小)。 -
示例:设置按钮文本:
ui->pushButton->setText("点我");
-
-
自动连接槽函数
-
命名规则:
on_控件对象名_信号名()
。 -
示例:按钮点击槽函数:
void MainWindow::on_pushButton_clicked() {qDebug() << "按钮被点击"; }
-
五、注意事项
-
路径规范:避免中文和特殊字符,防止构建失败。
-
CMake配置:确保正确引入Qt模块(如Widgets、Core)。
-
内存管理:优先使用父子对象关系或智能指针,避免内存泄漏。
-
UI更新:修改
.ui
文件后需重新构建以生成ui_*.h
文件。
信号与槽机制
一、概述
-
核心作用:Qt的信号与槽机制是用于对象间通信的松耦合方式,替代传统回调函数。当对象状态变化(事件)时发送信号,连接的槽函数自动响应。
-
特点:支持多对多连接(一个信号可绑定多个槽,多个信号可绑定一个槽),支持跨线程通信,参数类型需兼容。
二、信号与槽的定义
-
信号(Signal)
-
声明方式:在类中使用
signals
关键字声明,无返回值(void
),无需实现。 -
示例:
class MyClass : public QObject {Q_OBJECT signals:void mySignal(int value); // 信号声明 };
-
-
槽(Slot)
-
声明方式:在类中使用
public/private/protected slots
声明,是普通成员函数,可带参数和返回值。 -
示例:
class MyClass : public QObject {Q_OBJECT public slots:void mySlot(int data); // 槽声明 };
-
三、信号的发送与槽的调用
-
信号发送:通过
emit
关键字触发信号。emit mySignal(100); // 发送信号
-
槽调用规则:
-
槽函数按连接顺序依次执行。
-
槽可以是私有函数,但通过信号连接仍可调用。
-
四、信号与槽的连接方式
-
手动连接
-
使用
QObject::connect
函数,语法:connect(sender, &SenderClass::signal, receiver, &ReceiverClass::slot);
-
示例:
connect(ui->pushButton, &QPushButton::clicked, this, &MainWindow::handleClick);
-
-
自动连接
-
通过槽函数命名规则
on_对象名_信号名
,需在setupUi
中调用QMetaObject::connectSlotsByName
。 -
示例:
void MainWindow::on_pushButton_clicked() { ... } // 自动连接
-
五、连接类型与规则
-
连接类型(
Qt::ConnectionType
)类型 描述 AutoConnection
默认,根据线程自动选择 Direct
(同线程)或Queued
(跨线程)。DirectConnection
立即执行,槽在发送者线程运行。 QueuedConnection
异步执行,槽在接收者线程事件循环中调用。 BlockingQueuedConnection
同步执行,发送者线程阻塞直到槽完成(需跨线程)。 UniqueConnection
避免重复连接,与上述类型按位或使用。 -
参数规则
-
信号参数数量 ≥ 槽参数数量,且类型兼容。
-
示例:
// 合法:信号参数多于槽 connect(obj1, &ClassA::signal(int, QString), obj2, &ClassB::slot(int)); // 非法:槽参数多于信号 connect(obj1, &ClassA::signal(int), obj2, &ClassB::slot(int, QString));
-
六、自定义信号与槽的条件
-
类必须直接或间接继承
QObject
。 -
类声明中需包含
Q_OBJECT
宏。 -
信号用
signals
声明,槽用slots
声明。
七、元对象编译器(moc)
-
作用:处理 Qt 的扩展语法(如信号与槽),生成元对象代码(
moc_*.cpp
)。 -
必要性:包含
Q_OBJECT
的类必须通过moc
编译,否则信号与槽无法正常工作。
八、关键示例
// 信号与槽定义
class Worker : public QObject {Q_OBJECT
signals:void progressUpdated(int percent);
public slots:void doWork() { // 工作逻辑emit progressUpdated(50); }
};// 连接
Worker worker;
QObject::connect(&worker, &Worker::progressUpdated, this, [](int percent) {qDebug() << "Progress:" << percent;
});
简单示例:
teacher.h:
// teacher.h
#include <QObject>
class Teacher : public QObject {Q_OBJECT
public:explicit Teacher(QObject *parent = nullptr) : QObject(parent) {}signals:void hungry(); // 正确信号声明
};
student.h:
// student.h
#include <QObject>
#include <QDebug>
class Student : public QObject {Q_OBJECT
public:explicit Student(QObject *parent = nullptr) : QObject(parent) {}public slots:void treat(); // 槽函数声明
};
student.cpp:
// student.cpp
#include "student.h"
void Student::treat() {qDebug() << "Student treats teacher"; // 修正输出内容
}
window.h:
// window.h
#include <QWidget>
#include "teacher.h"
#include "student.h"class Window : public QWidget {Q_OBJECT
public:explicit Window(QWidget *parent = nullptr);public slots:void xiake(); // 触发信号的方法private:Teacher *teacher;Student *student;
};
window.cpp:
// window.cpp
#include "window.h"Window::Window(QWidget *parent) : QWidget(parent) {teacher = new Teacher(this);student = new Student(this);// 正确连接信号与槽(注意信号拼写)connect(teacher, &Teacher::hungry, student, &Student::treat);
}void Window::xiake() {emit teacher->hungry(); // 触发信号
}
九、注意事项
-
线程安全:跨线程通信优先使用
QueuedConnection
。 -
命名规范:自动连接槽需严格遵循
on_对象名_信号名
格式。 -
内存管理:避免循环引用,确保对象生命周期可控。
Qt事件处理总结与归纳
一、事件简介
-
概念
-
事件是用户或系统产生的交互操作,通过事件循环处理,用于对象间信息交互。
-
Qt将系统消息转换为
QEvent
对象,所有QObject
子类均可处理事件。
-
-
常见事件类型
-
用户界面事件:鼠标事件(
QMouseEvent
)、键盘事件(QKeyEvent
)、触摸事件(QTouchEvent
)。 -
系统事件:定时器事件(
QTimerEvent
)、窗口事件(QResizeEvent
)、绘图事件(QPaintEvent
)。 -
自定义事件:继承
QEvent
实现,用于特定需求。
-
二、事件处理机制
-
事件分发流程
-
事件队列:操作系统消息被转换为
QEvent
,由QCoreApplication::exec()
驱动的主事件循环处理。 -
事件传递:
-
事件先传递到焦点控件。
-
若未被处理,逐级传递给父控件。
-
-
-
事件处理函数
-
子类可重写
event()
函数或特定事件处理函数(如mousePressEvent()
)。 -
示例:自定义按钮重写鼠标事件:
// 继承QPushButton并重写mousePressEvent void CustomPushButton::mousePressEvent(QMouseEvent *e) {qDebug() << "Custom按钮被按下";QPushButton::mousePressEvent(e); // 调用父类实现,确保信号正常触发 }
-
-
事件过滤器(Event Filter)
-
作用:拦截目标对象的事件,在事件到达前处理。
-
步骤:
-
安装过滤器:
targetObj->installEventFilter(filterObj)
。 -
重写
eventFilter()
:判断事件类型并处理,返回true
拦截事件,false
继续传递。
bool MainWindow::eventFilter(QObject *obj, QEvent *event) {if (obj == ui->pushButton && event->type() == QEvent::MouseButtonPress) {qDebug() << "拦截按钮点击";return true; // 阻止事件传递}return QMainWindow::eventFilter(obj, event); // 默认处理 }
-
-
三、事件与信号的区别
特性 | 事件(QEvent) | 信号(Signal) |
---|---|---|
触发方式 | 由系统或用户操作触发 | 由对象主动发出(如按钮点击触发clicked ) |
处理机制 | 通过事件队列分发,可被过滤或拦截 | 直接调用连接的槽函数 |
灵活性 | 可自定义事件类型和分发逻辑 | 信号与槽通过connect 绑定,不可拦截 |
典型应用 | 底层交互(如鼠标移动、键盘输入) | 逻辑响应(如按钮点击后的业务逻辑) |
四、QEventLoop 的应用
-
作用
-
在局部范围内启动事件循环,用于等待异步操作完成(如定时器、对话框关闭)。
-
-
使用场景
-
等待定时器:
QEventLoop loop; QTimer::singleShot(3000, &loop, &QEventLoop::quit); loop.exec(); // 阻塞3秒后继续执行
-
模态对话框:
QDialog dialog; QEventLoop loop; connect(&dialog, &QDialog::finished, &loop, &QEventLoop::quit); dialog.show(); loop.exec(); // 等待对话框关闭
-
五、常见问题与解决
-
头文件缺失
-
错误:
customepushbutton.h: No such file or directory
。 -
解决:在CMake中添加包含目录:
include_directories(${PROJECT_SOURCE_DIR})
-
-
类型转换错误
-
错误:
invalid conversion from 'QWidget' to 'QPushButton'
。 -
解决:确保自定义控件继承自正确的基类(如
QPushButton
)。
-
-
信号未触发
-
原因:重写事件处理函数时未调用父类实现。
-
解决:在自定义的
mousePressEvent
中调用QPushButton::mousePressEvent(e)
。
-
六、总结
-
事件处理核心:理解事件分发流程、重写事件函数、使用过滤器拦截事件。
-
事件与信号结合:事件处理底层交互,信号驱动业务逻辑,两者互补。
-
开发注意事项:
-
继承控件时确保调用父类事件函数以维持原有逻辑。
-
使用
QEventLoop
避免主线程阻塞,保持界面流畅。 -
合理使用事件过滤器实现复杂交互逻辑。
-
- 这是本人的学习笔记不是获利的工具,小作者会一直写下去,希望大家能多多监督我
- 文章会每攒够两篇进行更新发布(受平台原因,也是希望能让更多的人看见)
- 感谢各位的阅读希望我的文章会对诸君有所帮助
相关文章:

初识——QT
QT安装方法 一、项目创建流程 创建项目 入口:通过Qt Creator的欢迎页面或菜单栏(文件→新建项目)创建新项目。 项目类型:选择「Qt Widgets Application」。 路径要求:项目路径需为纯英文且不含特殊字符。 构建系统…...
几何_平面方程表示_点+向量形式
三维平面方程可以写成: π : n ⊤ X d 0 \boxed{\pi: \mathbf{n}^\top \mathbf{X} d 0} π:n⊤Xd0 📐 一、几何直观解释 ✅ 平面是“法向量 平面上一点”定义的集合 一个平面可以由: 一个单位法向量 n ∈ R 3 \mathbf{n} \in \mat…...
学习alpha
(sign(ts_delta(volume, 1)) * (-1 * ts_delta(close, 1))) 这个先用sign操作符 sign.如果输入NaN则返回NaN 在金融领域,符号函数 sign(x) 与 “基础”(Base)的组合概念可结合具体场景解读,以下从不同金融场景分析其潜在意义&…...
Java - Junit框架
单元测试:针对最小的功能单元(方法),编写测试代码对该功能进行正确性测试。 Junit:Java语言实现的单元测试框架,很多开发工具已经集成了Junit框架,如IDEA。 优点 编写的测试代码很灵活,可以指某个测试方法…...
秒删node_modules[无废话版]
“npm install”命令带来的便利和高效让人感到畅快,但删除依赖包时却可能带来诸多困扰。特别是在项目依赖关系较为复杂的情况下,node_modules文件夹的体积往往会膨胀至数百MB甚至几个GB,手动删除时进度条长时间转圈,令人感到焦虑和…...

kkFileView文件文档在线预览镜像分享
kkFileView为文件文档在线预览解决方案,该项目使用流行的spring boot搭建,易上手和部署,基本支持主流办公文档的在线预览,如doc,docx,xls,xlsx,ppt,pptx,pdf,txt,zip,rar,图片,视频,音频等等 开源项目地址 https://gitee.com/kek…...

实例分割AI数据标注 ISAT自动标注工具使用方法
文章目录 🌕ISAT安装和启动方法🌕下载和使用AI分割模型🌙SAM模型性能排行🌙手动下载sam模型 & sam模型下载路径🌕使用方法🌙从file中导入图片🌙点击左上角的图标进入分割模式🌙鼠标左键点击画面中的人则自动标注🌙点击右键该区域不标注🌙一个人一个人的…...

Qt图表绘制(QtCharts)- 性能优化(13)
文章目录 1 批量替换代替追加1.1 测试11.2 测试21.3 测试3 2 开启OpenGL2.1 测试12.2 测试22.3 测试32.4 测试4 更多精彩内容👉内容导航 👈👉Qt开发 👈👉QtCharts绘图 👈👉python开发 …...
Spring Cloud动态配置刷新:@RefreshScope与@Component的协同机制解析
在微服务架构中,动态配置管理是实现服务灵活部署、快速响应业务变化的关键能力之一。Spring Cloud 提供了基于 RefreshScope 和 Component 的动态配置刷新机制,使得开发者可以在不重启服务的情况下更新配置。 本文将深入解析 RefreshScope 与 Component…...
部署docker上的redis,idea一直显示Failed to connect to any host resolved for DNS name
参考了https://blog.csdn.net/m0_74216612/article/details/144145127 这篇文章,关闭了centos的防火墙,也修改了redis.conf文件,还是一直显示Failed to connect to any host resolved for DNS name。最终发现是腾讯云服务器那一层防火墙没…...

如何在 Windows 10 或 11 上使用命令提示符安装 PHP
我们可以在 Windows 上从其官方网站下载并安装 PHP 的可执行文件,但使用命令提示符或 PowerShell 更方便。 PHP 并不是一种新的或不为人知的脚本语言,它已经存在并被全球数千名网络开发人员使用。它以开源许可并分发,广泛用于 LAMP 堆栈中。然而,与 Linux 相比,它在 Wind…...

RK3588 ADB使用
安卓adb操作介绍 adb(Android Debug Bridge)是一个用于与安卓设备进行通信和控制的工具。adb可以通过USB或无线网络连接安卓设备,执行各种命令,如安装和卸载应用,传输文件,查看日志,运行shell命…...
Vue 3.0双向数据绑定实现原理
Vue3 的数据双向绑定是通过响应式系统来实现的。相比于 Vue2,Vue3 在响应式系统上做了很多改进,主要使用了 Proxy 对象来替代原来的 Object.defineProperty。本文将介绍 Vue3 数据双向绑定的主要特点和实现方式。 1. 响应式系统 1.1. Proxy对象 Vue3 …...

Please install it with pip install onnxruntime
无论怎么安装都是 Please install it with pip install onnxruntime 我python 版本是3.11 ,我换成3.10 解决了...
java -jar命令运行 jar包时如何运行外部依赖jar包
java -jar命令运行 jar包时如何运行外部依赖jar包 场景: 打包发不完,运行时。发现一个问题, java java.lang.NoClassDefFoundError: org/apache/commons/lang3/ArrayUtils 显示此,基本表明,没有这个依赖,如果在开发…...

低损耗高效能100G O Band DWDM 10km光模块 | 支持密集波分复用
目录 前言 一、产品概述 100G QSFP28 O Band DWDM 10km光模块核心特点包括: 二、为何选择O Band DWDM方案? 1.低色散损耗,传输更稳定 2.兼容性强 三、典型应用场景 1.数据中心互联(DCI) 2.企业园区/智慧城市组网 3.电信…...
【解决分辨数字】2021-12-16
缘由用C语言解决分辨数字-编程语言-CSDN问答 int a 0, w 0, aa[6]{};cin >> a;while (a)aa[w] a % 10, a / 10, w;cout << w << endl;while (a<w)cout << aa[a] << ends, aa[5] * 10, aa[5] aa[a];cout << endl << aa[5] <…...
el-tree结合checkbox实现数据回显
组件代码 <el-tree:data"vertiList"show-checkboxnode-key"id":props"defaultProps"ref"treeRefx"class"custom-tree"check-change"handleCheckChange"> </el-tree>获取选择的节点 handleCheckChan…...

第二十六天打卡
全局变量 global_var 全局变量是定义在函数、类或者代码块外部的变量,它在整个程序文件内都能被访问。在代码里, global_var 就是一个全局变量,下面是相关代码片段: print("\n--- 变量作用域示例 ---") global_var …...

阿里云ECS部署Dify
一:在ECS上面安装Docker 关防火墙 sudo systemctl stop firewalld 检查防火墙状态 systemctl status firewalld sudo yum install -y yum-utils device-mapper-persistent-data lvm2 设置阿里镜像源,安装并启动docker [base] nameCentOS-$releas…...
【线段树】P4588 [TJOI2018] 数学计算|普及+
本文涉及知识点 C线段树 [TJOI2018] 数学计算 题目描述 小豆现在有一个数 x x x,初始值为 1 1 1。小豆有 Q Q Q 次操作,操作有两种类型: 1 m:将 x x x 变为 x m x \times m xm,并输出 x m o d M x \bmod M…...

日志与策略模式
什么是设计模式 IT⾏业 ,为了让 菜鸡们不太拖⼤佬的后腿, 于是⼤佬们针对⼀些经典的常⻅的场景, 给定了⼀些对应的解决⽅案, 这个就是 设计模式 日志认识 计算机中的⽇志是记录系统和软件运⾏中发⽣事件的⽂件,主要作⽤是监控运⾏状态、记录异常信 息ÿ…...

Jenkins 最佳实践
1. 在Jenkins中避免调度过载 过载Jenkins以同时运行多个作业可能导致资源竞争、构建速度变慢和系统性能问题。分配作业启动时间可以防止瓶颈,并确保更顺畅的执行。如何实现? 在Cron表达式中使用H:引入抖动(jitter)&a…...

天能股份SAP系统整合实战:如何用8个月实现零业务中断的集团化管理升级
目录 天能股份SAP系统整合案例:技术驱动集团化管理的破局之路 一、企业背景:新能源巨头的数字化挑战 二、项目难点:制造业的特殊攻坚战 1. 生产连续性刚性需求 2. 数据整合三重障碍 3. 资源限制下的技术突围 三、解决方案:S…...
搜索引擎的高级语法
文章目录 精确搜索:双引号站内搜索:site通配符搜索:*减号缩小范围:-文档搜索:filetypeURL搜索: inurl标题搜索:intitle正文搜索:intext参考链接 精确搜索:双引号 “ ” …...

uniapp-商城-59-后台 新增商品(属性的选中,进行过滤展示,filter,some,every和map)
前面讲了属性的添加,添加完成后,数据库中已经存在数据了,这时再继续商品的添加时,就可以进行属性的选择了。 在商品添加过程中,属性选择是一个关键步骤。首先,界面需要展示嵌套的属性数据,用户通…...
linux用户切换
在 Linux 系统中,/etc/shadow 文件存储了用户的加密密码和其他安全相关信息,因此默认只有 root 用户 才有权限读取。当你尝试用普通用户身份查看时,会收到 Permission denied 错误。 如何查看 /etc/shadow 文件? 方法 1ÿ…...

B2C 商城转型指南:传统企业如何用 ZKmall模板商城实现电商化
在数字化浪潮席卷全球的当下,传统企业向电商转型已不再是选择题,而是关乎生存与发展的必答题。然而,缺乏技术积累、开发成本高、运营经验不足等问题,成为传统企业转型路上的 “拦路虎”。ZKmall模板商城以其低门槛、高灵活、强适配…...
鸿蒙OSUniApp 实现的二维码扫描与生成组件#三方框架 #Uniapp
UniApp 实现的二维码扫描与生成组件 前言 最近在做一个电商小程序时,遇到了需要扫描和生成二维码的需求。在移动应用开发中,二维码功能已经成为标配,特别是在电商、社交和支付等场景下。UniApp作为一个跨平台开发框架,为我们提供…...

生成树协议 - STP
目录 BPDU STP选举机制 STP端口状态 STP计时器 STP拓扑变更机制 生成树协议(Spanning Tree Protocol),简写为STP。 STP是二层网络中用于消除环路的协议,通过阻塞冗余链路,使可用链路在拓扑上呈现出无环的树结构&…...