个人认为,事件机制是Qt最难以理解且最为精妙的一部分。事件主要分为两种:
在与用户交互时发生。比如按下鼠标(mousePressEvent),敲击键盘(keyPressEvent)等。
系统自动发生,比如计时器事件(timerEvent)等。
在发生事件时(比如说上面说的按下鼠标),就会产生一个QEvent对象(这里是QMouseEvent,为QEvent的子类),这个QEvent对象会传给当前组件的event函数。如果当前组件没有安装事件过滤器(这个后面会提到),则会被event函数发放到相应的xxxEvent函数中(这里是mousePressEvent函数)。
需要区分的是:事件与信号并不相同。
比如:鼠标单击按钮,鼠标事件(QMouseEvent),而按钮本身发射clicked()信号。一般而言我们只需要关注单击信号,不用考虑鼠标事件。但是当我们要对该按钮做额外操作,不想通过信号处理,此时事件就是一个很好的选择。关闭事件(QCloseEvent)是一个常用的事件。
一,事件Qt 中所有事件类都继承于 QEvent。在事件对象创建完毕后,Qt 将这个事件对象传递给 QObje ...
Qt中有两种方法来使用定时器,一种是定时器事件,另一种是使用信号和槽。
常使用信号和槽(代码看起来比较整洁)但是当使用多个定时器的时候最好用定时器事件来处理。
定时器方式一:定时器事件需要: #include
方式:
利用对void timerEvent(QTimerEvent* e)事件的重写。
启动定时器 int QObject::startTimer ( int interval ) ;
开启一个定时器,返回值为int类型。他的参数interval是毫秒级别。当开启成功后会返回这个定时器的ID, 并且每隔interval 时间后会进入timerEvent 函数。直到定时器被杀死(killTimer)
timerEvent的返回值是定时器的唯一标识。可以和e->timerId比较
void killTimer(int id); //停止 ID 为 id 的计时器,ID 由 startTimer()函数返回
实例:在两个label中自动计数,一个间隔为1秒,一个为2秒。
在头文件中先声明void timerEvent(QTimerEvent* ...
一, 最简单的多线程QtConcurrent::run()
其函数原型如下:
12QFuture<T> QtConcurrent::run(Function function, ...)QFuture<T> QtConcurrent::run(QThreadPool *pool, Function function, ...)
参数function需要外部函数:(或者lambda函数),后面也可跟外部函数的参数。
1extern void func(QString str);
QtConcurrent :: run()也接受指向成员函数的指针。第一个参数必须是一个const引用或一个指向该类实例的指针。const成员函数一般传递 常量引用 (const reference),而非常量成员函数一般传递 指针 (pointer)
在VS环境中需要引用: #include”QtConcurrent/qtconcurrentrun.h”
简单的说,QtConcurrent::run()函数会在一个单独的线程中执行,并且该线程取自全局QThreadP ...
一、知识回顾1,为什么需要多线程?
从计算机底层来说: 线程可以比作是轻量级的进程,是程序执行的最小单位,线程间的切换和调度的成本远远小于进程。另外,多核 CPU 时代意味着多个线程可以同时运行,这减少了线程上下文切换的开销。
从当代互联网发展趋势来说: 现在的系统动不动就要求百万级甚至千万级的并发量,而多线程并发编程正是开发高并发系统的基础,利用好多线程机制可以大大提高系统整体的并发能力以及性能。
再深入到计算机底层来探讨:
单核时代:在单核时代多线程主要是为了提高 CPU 和 IO 设备的综合利用率。举个例子:当只有一个线程的时候会导致 CPU 计算时,IO 设备空闲;进行 IO 操作时,CPU 空闲。我们可以简单地说这两者的利用率目前都是 50%左右。但是当有两个线程的时候就不一样了,当一个线程执行 CPU 计算时,另外一个线程可以进行 IO 操作,这样两个的利用率就可以在理想情况下达到 100%了。
多核时代: 多核时代多线程主要是为了提高 CPU 利用率。举个例子:假如我们要计算一个复杂的任务,我们只用一个线程的话,CPU 只会一个 CPU 核心被利用到,而创建多个 ...
Qt 提供了两种读写纯文本文件的基本方法:
用 QFile 类的 IODevice 读写功能直接进行读写
利用 QFile 和 QTextStream 结合起来,用流(Stream)的方法进行文件读写。
一、文件读操作(1)使用QFile类
Qt封装了QFile类,方便我们对文件进行操作,可以按照如下的步骤进行:
使用QFile加载文件对象
打开文件 file.open(打开方式)
操作文件
关闭文件 file.close()
实例:点击读写文件按钮,读取文件内容到textEdit中
1️⃣设置 ui 界面
2️⃣在widget.cpp中编辑代码(QFileDialog类是打开文件)
1234567891011121314151617//点击选取文件按钮,弹出文件对话框 connect(ui->pushButton,&QPushButton::clicked,[=](){ QString path = QFileDialog::getOpenFileName(this,"打开文件","C:/Users/WFD/Deskto ...
一、信号和槽机制分析 信号(Signal)就是在特定情况下被发射的事件,例如PushButton 最常见的信号就是鼠标单击时发射的 clicked() 信号,一个 ComboBox 最常见的信号是选择的列表项变化时发射的 CurrentIndexChanged() 信号。
GUI 程序设计的主要内容就是对界面上各组件的信号的响应,只需要知道什么情况下发射哪些信号,合理地去响应和处理这些信号就可以了。
槽(Slot)就是对信号响应的函数。槽就是一个函数,与一般的C++函数是一样的,可以定义在类的任何部分(public、private 或 protected),可以具有任何参数,也可以被直接调用。槽函数与一般的函数不同的是:槽函数可以与一个信号关联,当信号被发射时,关联的槽函数被自动执行。
信号与槽关联是用 QObject::connect() 函数实现的,其基本格式是:
12QObject::connect(sender, SIGNAL(signal()), receiver, SLOT(slot()));connect(发出信号的对象,发出的信号,接收信号的对象,接收到信 ...
一、QT基本框架创建一个项目,先看下main.cpp这个文件
注意:
每个Qt程序有且只能有一个QApplication对象,没有会报错。
Qt里面的头文件和类名是一致的,知道头文件就知道类名,反之亦然
Qt头文件是没有.h的,基本都是以大写的Q开头
根据以上的分析,我们可以得出Qt的程序框架代码:
123456789#include <QApplication> int main(int argc, char *argv[]){ QApplication a(argc, argv); /* 在这里写你的代码 */ return a.exec(); }
widget.h和widget.cpp分析
打开头文件里面的widget.h,和sources里面的widget.app,可以看到以下代码:
最上面的MyfirstQt.pro,是管理项目的文件,用来存储项目设置。
后缀为“.pro”的文件是项目的管理文件,文件名就是项目的名称,如本项目中的 MyfirstQt.pr ...
QT多线程QMLQML(Qt Meta-Object Language) 是 Qt框架 中用于构建用户界面(UI)的声明式编程语言。它专注于界面设计与用户交互,与C++后端逻辑结合,适用于开发跨平台、动态且现代化的应用程序(如桌面、移动及嵌入式应用)。以下是其核心特性与作用:
ECMAScript
Qt 对象系统
Qt Quick 标准库
用于定义和创建动态可视化界面
Qt Quick 是一种基于 Qt 的用户界面设计技术。它允许开发人员使用 QML(Qt Meta-Object Language)语言和 JavaScript 以声明式的方式创建动态的、高效的、流畅的用户界面。Qt Quick 技术不同于传统的基于部件(widget-based)的用户界面设计,其设计哲学是将界面的各个元素抽象出来,然后通过组合这些元素来实现各种不同的界面和交互效果。
多线程的实现:信号和槽api函数 成员函数、2.2 信号槽 2.3静态函数
派生QThread类对象的方法(重写Run函数)
启动事件循环:当一个程序调用 exec()(3456例如 QApplication::exec())后 ...
本教程是在硅基流动获取API,并在Cherry Studio上面使用
一、注册硅基流动SiliconCloud 基于华为云昇腾云服务,首发推出了 DeepSeek R1 & V3 模型推理服务。注册即赠送 14 元余额,邀请注册还可再获得 14 元余额(2000 万 Tokens)。
邀请链接: 硅基流动统一登录
邀请码: ePZNK3HT
注册完成后,可在模型广场上找到 deepseek-ai/DeepSeek-R1 模型,显示 671B 的满血版。
但这个页面不必理会,点击左侧API密钥,如下图所示,点击新建API密钥(注意保护隐私),密钥描述随便填。
建完API密钥后就来到第二步了。
二、下载Cherry Studio用户可以选择需要的软件来调用接口。推荐使用「CherryStudio」软件,支持 Windows、Mac 和 Linux 客户端。
Cherry Studio 官网下载链接: https://docs.cherry-ai.com/cherrystudio/download?login=from_csdn
安装完成之后,运行「CherrySt ...
linux
未读Linux系统调用accept原理 accept 函数是网络编程中用于接受客户端连接请求的关键系统调用。当一个 socket 被设置为监听模式后,它会在其对应的队列中积累来自客户端的连接请求。accept 函数的作用是从这个队列中取出一个已经建立的连接,并返回一个新的 socket 文件描述符,该描述符与客户端的连接相关联。
当没有连接请求时,accept 会阻塞调用它的进程或线程,直到有新的连接请求到达。这个过程涉及到操作系统内核中的网络协议栈,具体来说,是 TCP 协议栈的处理机制。当 accept 被调用时,内核会检查监听 socket 的完全连接队列,如果队列为空,则进程或线程进入阻塞状态;如果队列中有待处理的连接,则 accept 返回一个新的 socket,进程或线程继续执行。
非阻塞IO模式在非阻塞 I/O 模式下,当 accept 函数没有准备好返回时(即没有连接请求可以接受),它不会阻塞调用它的进程或线程,而是立即返回一个错误。这种模式允许程序在等待连接时继续执行其他任务,从而提高程序的响应性和效率。
设置socket为非阻塞模式要将 socket 设 ...