【QT(十)】—— 系统

事件

Qt 事件是程序响应外部 / 内部动作的核心机制,所有事件继承自抽象类 QEvent,由系统 / Qt 框架触发,覆盖用户交互、系统通知、窗口状态变化等场景。

  • 触发来源:既可以是用户操作(鼠标、键盘),也可以是系统 / 程序内部(定时器、窗口重绘、网络状态变化);
  • 处理方式:Qt 提供多种方式响应事件(重写事件函数、事件过滤器等),可拦截、处理或传递事件;
  • 核心作用:是 Qt 程序实现交互、响应状态变化的核心机制,比如点击按钮触发点击事件、窗口缩小触发尺寸变化事件。

这里的QMouseEvent(鼠标事件)、QKeyEvent(键盘事件)、QTimerEvent(定时器事件)等等都是QEvent的子类

常见时间

事件名称 描述
鼠标事件 鼠标左键、鼠标右键、鼠标的移动,鼠标按键的按下和松开
键盘事件 按键类型、按键按下、按键松开
定时器事件 定时时间到达
进入离开事件 鼠标的进入和离开
滚轮事件 鼠标滚轮滚动
绘屏事件 重绘屏幕的某些部分
显示隐藏事件 窗口的显示和隐藏
移动事件 窗口位置的变化
窗口事件 是否为当前窗口
大小改变事件 窗口大小改变
焦点事件 键盘焦点移动
拖拽事件 用鼠标进行拖拽

事件处理

当某一个事件发生时,如要执行哪些操作,如何处理。

这里我们只需要重写对应的成员方法即可,当事件发生时自动调用。

例如:enterEvent(QEvent* event)表示鼠标进入事件,当鼠标进入对应控件时自动调用。

鼠标事件

1. 鼠标进入/离开

鼠标进入 : enterEvent

鼠标离开 : leaveEvent

这里就创建一个类Label,继承自QLabel;重写enterEventleaveEvent方法,当鼠标进入Label控件时,执行enterEvent;当鼠标离开Label控件时,执行leaveEvent方法

cpp 复制代码
// Label类
void Label::enterEvent(QEvent *event)
{
    (void)event;
    qDebug() << "鼠标进入 ";
}
void Label::leaveEvent(QEvent *event)
{
    (void)event;
    qDebug() << "鼠标离开 ";
}

创建Label,重写了对应方法;我们可以通过代码直接创建Label类,然后设置其属性(大小、位置、边框)。

当然也可以通过ui图形化界面创建:

ui图形化界面中,只有QLabel控件;

在拖拽创建出一个QLabel控件后,选择并按下鼠标右键,点击 提升为


这里输入提升的类名称,然后点击添加


选择使用,然后点击提升即可。

2. 鼠标点击/释放/双击

鼠标点击 : mousePressEvent

鼠标释放 : mouseReleaseEvent

鼠标双击 : mouseDoubleClickEvent

这里还是一样,创建Label类继承自QLabel类,在Label重写对应的Event方法。

cpp 复制代码
void Label::mousePressEvent(QMouseEvent *event)
{
    qDebug() << "Mouse Press";
}
void Label::mouseReleaseEvent(QMouseEvent *event)
{
    qDebug() << "Mouse Release";
}
void Label::mouseDoubleClickEvent(QMouseEvent *event)
{
//    qDebug() << "Double Click";
    qDebug() << "(x,y) : (" << event->x() << ", " << event->y() << ")";
    qDebug() << "(globalX,globalY) : (" << event->globalX() << ", " << event->globalY() << ")";
}

(x,y)指的是鼠标相对于当前控件的位置;

(globalX,globalY) 指的是鼠标相对于整个程序窗口的位置。

这里鼠标点击,也是可以区分是 鼠标左键、鼠标右键、鼠标滚轮点击的:

  • Qt::LeftButton : 鼠标左键
  • Qt::RightButton : 鼠标右键
  • Qt::MidButton : 鼠标滚轮

3. 鼠标移动

4. 滚轮事件

键盘事件

对于键盘事件,无非就是键盘中有按键按下。

按键按下 : keyPressEvent

这里只要键盘有按键被按下,就会执行KeyPressEvent方法;

这里可以调用key方法获取当前是哪一个按键被按下(然后做相对应的判断,处理)

cpp 复制代码
void MainWindow::keyPressEvent(QKeyEvent *event)
{
    if(event->key() == Qt::Key_A)
        qDebug() << "按键 A 被按下";
}

组合按键

在开发过程当中,不止要处理键盘中某一个按键按下,同时也可以用组合按键(Ctrl + A

Qt当中,对于常用的功能键也进行了封装。

Qt::KeyboardModifier中定义了处理键盘事件时对应的修改键。

枚举值 描述
Qt::NoModifier 无修改键
Qt::ShiftModifier Shift 键
Qt::ControlModifier Ctrl 键
Qt::AltModifier Alt 键
Qt::MetaModifier Meta 键(在 Windows 上指 Windows 键,在 macOS 上指 Command 键)
Qt::KeypadModifier 使用键盘上的数字键盘进行输入时,Num Lock 键处于打开状态
Qt::GroupSwitchModifier 用于在输入法组之间切换
cpp 复制代码
void MainWindow::keyPressEvent(QKeyEvent *event)
{
    if(event->key() == Qt::Key_A && event->modifiers() == Qt::KeyboardModifier::ControlModifier)
        qDebug() << "Ctrl + A 被按下";
}

定时器事件

定时器事件:timerEvent

这个定时器事件和QTimer类非常类似,在使用时都需要调用开始方法、使用完成后也都需要调用终止方法。

定时器事件:

  • startTimer:开始计时,需要指定时间(多久触发一次);返回一个timeId这里可以同时存在多个定时器,触发同一个timerEvent方法,通过timeId区分
  • killTimer:结束定时器

示例:创建两个QLCDNumber,同时开始计数(一个每秒增加1,另一个每两秒增加1),计数增加到10为止

cpp 复制代码
MainWindow::MainWindow(QWidget *parent)
    : QMainWindow(parent)
    , ui(new Ui::MainWindow)
{
    ui->setupUi(this);
    timer_id1 = startTimer(1000);
    timer_id2 = startTimer(2000);
}
void MainWindow::timerEvent(QTimerEvent *event)
{
    if(event->timerId() == timer_id1)
    {
        int value = ui->lcdNumber_1->value();
        if(value >= 10)
        {
            killTimer(timer_id1);
            return;
        }
        ui->lcdNumber_1->display(QString::number(value+1));
    }
    if(event->timerId() == timer_id2)
    {
        int value = ui->lcdNumber_2->value();
        if(value >= 10)
        {
            killTimer(timer_id2);
            return;
        }
        ui->lcdNumber_2->display(QString::number(value+1));
    }
}

窗口事件

对于窗口事件主要就是:窗口移动、改变大小

窗口移动moveEvent

改变大小resizeEvent

当窗口位置发生改变时,执行moveEvent方法;

当窗口大小发生改变时,就会执行resizeEvent方法。

cpp 复制代码
void MainWindow::moveEvent(QMoveEvent *event)
{
    qDebug() << "old pos : " << event->oldPos();
    qDebug() << "new pos : " << event->pos();
}
void MainWindow::resizeEvent(QResizeEvent *event)
{
    qDebug() << "old size : " << event->oldSize();
    qDebug() << "new size : " << event->size();
}

文件

关于文件相关操作,Qt 提供了 QFile类(对系统调用进行封装)

QFile的父类是QFileDeviceQFileDevice又继承自QIODevice类。

  • QFile:普通文件读写,支持文本流(QTextStream)、二进制流(QDataStream);
  • QSaveFile :关键 / 大文件保存,通过 commit() 提交生效,出错时 cancelWriting() 保护原文件;
  • QTemporaryFile :临时数据存储,open() 自动生成唯一文件,对象销毁即删除文件;
  • QTcpSocket/QUdpSocket:网络通信,TCP 强调可靠传输,UDP 强调高效;
  • QSerialPort:串口设备交互(如单片机、传感器),需配置串口参数;
  • QBluetoothSocket:蓝牙设备通信(如电脑与手机),支持 RFCOMM/L2CAP 协议;
  • QProcess:调用外部程序(如执行系统命令、启动第三方软件),可捕获程序输出;
  • QBuffer:内存中模拟文件 I/O,无需创建物理文件,直接操作 QByteArray。

QFile文件操作,简单来说就打开文件、读文件、写文件、关闭文件。

  • 打开文件

open方法,打开文件,在调用时必须传参指明打开方式(QIODevice::OpenMode

例如这里的ReadOnly(只读)、WriteOnly(只写)、ReadWrite(读写)、Append(追加)。

  • 读文件

对于读文件,可以指定char*缓冲区,也可以通过返回值获取读取到的数据。

Qt 提供了readreadAll(读取全部)、readLine(按行读取)

QByteArray:字节数组,可以直接使用QByteArray类型构造QString类型。

QString类型调用 toUtf8方法,就可以转化为QByteArray类型。

  • 写文件

写文件也是,可以传递QByteArray类型的数据、也可以传递char*数组进行写入。

  • 关闭文件

在文件使用后,调用close方法即可关闭文件。

示例:使用QFile类完成简单的记事本

在界面输入框中输入文本就行修改,根据打开、保存菜单项进行文件的读取、写入操作

打开文件,就是将指定文件的内容读取到程序中,并设置到输入框中。

保存文件,就是将输入框中的内容写入到指定文件中。

cpp 复制代码
MainWindow::MainWindow(QWidget *parent)
    : QMainWindow(parent)
    , ui(new Ui::MainWindow)
{
    ui->setupUi(this);
    this->setWindowTitle("LH记事本");
    QMenuBar* menubar = this->menuBar();
    this->setMenuBar(menubar);
    QMenu* menu = new QMenu("文件");
    menubar->addMenu(menu);
    QAction* action1 = new QAction("打开");
    QAction* action2 = new QAction("保存");
    menu->addAction(action1);
    menu->addSeparator();
    menu->addAction(action2);
    connect(action1,&QAction::triggered,this,[=](){
        // 获取文件路径
        QString path = QFileDialog::getOpenFileName();
        // 打开文件
        QFile* file = new QFile(path);
        file->open(QIODevice::ReadOnly);
        if(!file->isOpen())
        {
            QMessageBox::critical(this,"打开失败","打开指定文件失败");
            return;
        }
        // 读取文件内容
        QString text = file->readAll();
        // 设置到输入框中
        ui->textEdit->setText(text);
        // 关闭文件
        file->close();
        delete file;
    });
    connect(action2,&QAction::triggered,this,[=](){
        // 保存文件
        // 1. 获取文件路径
        QString path = QFileDialog::getSaveFileName();
        // 2. 打开文件
        QFile* file = new QFile(path);
        file->open(QIODevice::WriteOnly);
        if(!file->isOpen())
        {
            QMessageBox::critical(this,"打开失败","保存文件失败");
            return;
        }
        // 3. 写入文件
        QString text = ui->textEdit->toPlainText();
        file->write(text.toUtf8());
        // 4. 关闭文件
        file->close();
        delete file;
    });
}

QFileInfoQt 提供的一个拥有获取文件和目录信息的类(获取文件名、文件大小、文件修改日期等)

  • isDir() - 检查该文件是否是目录
  • isExecutable() - 检查该文件是否是可执行文件
  • fileName() - 获得文件名
  • completeBaseName() - 获取完整的文件名
  • suffix() - 获取文件后缀名
  • completeSuffix() - 获取完整的文件后缀
  • size() - 获取文件大小
  • isFile() - 判断是否为文件
  • fileTime() - 获取文件创建时间、修改时间、最近访问时间等

多线程

1. QThread 线程

Qt 当中也是支持多线程的,多线程的处理一般都是通过 QThread类 来实现的。

QThread类常用 API

函数名 功能描述
run() 线程的入口函数
start() 通过调用 run() 开始执行线程。操作系统将根据优先级参数调度线程。如果线程已经在运行,这个函数什么也不做
currentThread() 返回一个指向管理当前执行线程的 QThread 的指针
isRunning() 如果线程正在运行则返回 true;否则返回 false
sleep() / msleep() / usleep() 使线程休眠,单位为秒 / 毫秒 / 微秒
wait() 阻塞等待新线程结束,和 pthread_join功能类似
terminate() 终止线程的执行。线程可以立即终止,也可以不立即终止,这取决于操作系统的调度策略。
  • finished() : 当线程结束时会发出该 信号,可以通过该信号来实现线程的清理工作

这里线程的入口函数是 **run**成员函数,那就要通过重写run方法来让线程去执行自定义的函数逻辑。

示例:创建线程,重写run方法执行自定义函数,线程结束后通过finished信号来回收线程

这里线程run方法就让线程每1秒触发一个自定义信号,模拟完成一个计时的效果。

然后通过 开始按钮 ,创建线程开始计时; 通过重置按钮,将LCDNumber中的值设置成0

cpp 复制代码
// Thread
void Thread::run()
{
    // 每一秒触发自定义信号
    for(int i = 0; i<10; i++)
    {
        sleep(1);
        // 触发自定义信号 timing
        emit timing();
    }
}
// Widget
Widget::Widget(QWidget *parent)
    : QWidget(parent)
    , ui(new Ui::Widget)
{
    ui->setupUi(this);
    thread = new Thread(this);
    // 关联槽函数 自定义信号
    connect(thread,&Thread::timing,this,[=](){
        // lcdNumber + 1
        int value = ui->lcdNumber->value();
        ui->lcdNumber->display(QString::number(value + 1));
    });
    // 槽函数 线程结束
    connect(thread,&Thread::finished,this,[=](){
        // 回收线程
        thread->wait();
    });
    // 启动线程
    thread->start();
}
// 按钮关联槽函数
void Widget::on_pushButton_start_clicked()
{
    // 启动线程
    thread->start();
}
void Widget::on_pushButton_reset_clicked()
{
    // 重置lcdNumber的值
    ui->lcdNumber->display(QString::number(0));
}

注意

  • Qt 当中只允许主线程修改ui图形界面,子线程不允许修改ui图形界面。
  • connect() 函数的第5个参数表示 连接的方式,只有在多线程时才有意义。
  • Qt::AutoConnection : 在 Qt 中,会根据信号和槽函数所在的线程自动选择连接类型。如果信号和槽函数在同一线程中,那么使用 Qt::DirectConnection 类型;如果它们位于不同的线程中,那么使用 Qt::QueuedConnection 类型。
  • Qt::DirectConnection : 当信号发出时,槽函数会立即在同一线程中执行。这种连接类型适用于信号和槽函数在同一线程中的情况,可以实现直接的函数调用,但需要注意线程安全性。
  • Qt::QueuedConnection : 当信号发出时,槽函数会被插入到接收对象所属的线程的事件队列中,等待下一次事件循环时执行。这种连接类型适用于信号和槽函数在不同线程中的情况,可以确保线程安全。
  • Qt::BlockingQueuedConnection : 与 Qt::QueuedConnection 类似,但是发送信号的线程会被阻塞,直到槽函数执行完毕,这种连接类型适用于需要等待槽函数执行完毕再继续的场景,但需要注意可能引起线程死锁的风险。
  • Qt::UniqueConnection : 这是一个标志,可以使用位或与上述任何一种连接类型组合使用。

2. 线程安全

有了多线程,就一定会存在 线程安全问题

Qt当中,也对互斥锁、条件变量、信号量、读写锁等进行了封装

  • QMutex:互斥锁;QMutexLocker(自动申请、是否锁的类。在构造函数中申请锁、析构函数中释放锁)
  • QWaitCondition:条件变量
  • QSemaphore: 信号量
  • 读写锁QReadLockerQWriteLockerQReadWriteLock

常用接口

QMutex 常用接口

  • lock() - 锁定互斥锁
  • unlock() - 解锁互斥锁
  • tryLock() - 尝试锁定互斥锁(非阻塞)
  • tryLock(int timeout) - 在指定时间内尝试锁定
  • isRecursive() - 检查是否为递归互斥锁

QMutexLocker 常用接口

  • QMutexLocker(QMutex *mutex) - 构造函数,自动加锁
  • ~QMutexLocker() - 析构函数,自动解锁
  • unlock() - 手动解锁
  • relock() - 重新锁定

QWaitCondition 常用接口

  • wait(QMutex *mutex) - 等待条件满足
  • wait(QMutex *mutex, unsigned long time) - 带超时的等待
  • wakeOne() - 唤醒一个等待线程
  • wakeAll() - 唤醒所有等待线程

QSemaphore 常用接口

  • QSemaphore(int n = 0) - 构造函数
  • acquire(int n = 1) - 获取资源
  • release(int n = 1) - 释放资源
  • tryAcquire(int n = 1) - 尝试获取资源
  • tryAcquire(int n, int timeout) - 带超时的尝试获取
  • available() - 返回可用资源数量

网络

Qt 当中,不仅对线程、互斥锁等进行了封装;

其还封装实现了QUdpSocketQNetworkDatagramQTcpServerQTcpSocket(UDP、TCP 通信相关的类)。

此外,还封装实现了 QNetworkAccessManager QNetworkResuestQNetworkReply类,实现 HTPP网络通信。

要使用网络部功能,就需要引入network模块(在.pro文件中,QT +=后加上对应模块)

1. UDP

对于 UDP通信,核心的类就两个:QUdpSocketQNetworkDatagram

QUdpSocket

核心 方法

  • bind : 绑定端口号
  • receiveDatagram : 读取一个 UDP 数据报,返回一个QNetworkDatagram对象
  • writeDatagram : 发送一个 UDP 数据报,参数是const QNetworkDatagram&

信号

  • readyRead : 在接受到数据并准备就绪后触发。(类似与多路复用的通知机制)

这里,receiveDatagramwriteDatagram都是以数据报(QNetworkDatagram为单位进行读/写操作);当然这里也可以使用char*QByteArray等来进行通信。

QNetworkDatagram

核心 属性

  • destination : 目的主机进程信息(destinationAddress目的IP、destinationPort目的端口号)
  • sender : 对端(数据发送端)信息(senderAddress对端IP、sender对端端口号)

核心 方法

  • data获取数据报中的数据
  • senderAddress、senderPort获取对端IP、端口号
  • setDestination设置目的IP和端口号

回显服务端

这里使用UDP相关接口实现一个服务器端,在接受到报文将报文内容回显到窗口ListWidget控件中,并将信息重发给客户端

cpp 复制代码
Widget::Widget(QWidget *parent)
    : QWidget(parent)
    , ui(new Ui::Widget)
{
    ui->setupUi(this);
    this->setWindowTitle("服务端");
    // 创建UdpSocket
    socket = new QUdpSocket(this);
    // 关联信号槽
    connect(socket,&QUdpSocket::readyRead,this,&Widget::Receive);
    bool b = socket->bind(QHostAddress::Any,8080);
    if(!b)
    {
        QMessageBox::critical(this,"错误","绑定端口号出错");
        return;
    }
}
Widget::~Widget()
{
    delete ui;
}
void Widget::Receive()
{
    // 读取数据
    // 1. 获取报文
    QNetworkDatagram req_datagram = socket->receiveDatagram();
    // 2. 获取请求
    QString request = req_datagram.data();
    // 3. 处理请求,获取应答
    QString response = getResponse(request);
    // 4. 构建应答报文,并返回
    QNetworkDatagram res_datagram;
    res_datagram.setData(response.toUtf8());
    res_datagram.setDestination(req_datagram.senderAddress(),req_datagram.senderPort());
    socket->writeDatagram(res_datagram);
    // 5. 回显内容
    QString text = "[" + req_datagram.senderAddress().toString() + ":" + QString::number(req_datagram.senderPort())
            + "] say# " + request;
    ui->listWidget->addItem(text);
}
QString Widget::getResponse(const QString &request)
{
    return request;
}

回显客户端

有了服务器端,现在来实现客户端:

首先界面设计:

用户在下方输入框中输入内容,然后点击发送按钮向服务器端发送信息。

cpp 复制代码
const QString SERVER_IP = "127.0.0.1";
const quint16 SERVER_PORT = 8080;
Widget::Widget(QWidget *parent)
    : QWidget(parent)
    , ui(new Ui::Widget)
{
    ui->setupUi(this);
    this->setWindowTitle("客户端");
    // 创建套接字
    socket = new QUdpSocket(this);
    // 关联信号槽
    connect(socket,&QUdpSocket::readyRead,this,&Widget::Receive);

}
void Widget::Receive()
{
    // 读取数据
    QNetworkDatagram datagram = socket->receiveDatagram();
    // 回显内容
    ui->listWidget->addItem("服务端 : " + datagram.data());
}
void Widget::on_pushButton_clicked()
{
    // 发送数据
    QString text = ui->lineEdit->text();
    if(text == "")
        return;
    // 构建报文
    QNetworkDatagram datagram;
    datagram.setData(text.toUtf8());
    datagram.setDestination(QHostAddress(SERVER_IP),SERVER_PORT);
    // 发送报文
    socket->writeDatagram(datagram);
    // 回显内容
    ui->listWidget->addItem("客户端 : " + text);
}

2. TCP

对于 TCP 核心的类 : QTcpServerQTcpSocket

QTcpServer

QTcpServer用来监听端口,获取客户端连接。

核心 方法

  • listen : 绑定指定地址和端口号,并设置监听状态。(相当于 bindlisten系统调用)
  • nextPendingConnection : 获取一个已经建立好的连接;相当于accept(返回一个 QTcpSOcket对象)

信号

  • newConnection : 表示有新的客户端建立好连接(有新连接)

QTcpSocket

QTcpSocket 用来建立连接、通信的 TCP套接字

核心 方法

  • readAll : 读取(接受)数据
  • write : 写(发送)数据
  • deleteLader : 销毁一个QTcpSocket连接,暂时吧socket对象标记为无效,在下一个事件循环中析构释放该对象。
  • connectToHost : 向指定主机端口号发起连接请求
  • peerAddress/peerPort : 对端的IP和端口号

核心 信号

  • readyRead : 当有数据是触发该信号
  • disconnected : 当有连接断开时触发该信号

回显服务器

这里就使用QTcpServerQTcpSocket来实现一个回显服务器

cpp 复制代码
Widget::Widget(QWidget *parent)
    : QWidget(parent)
    , ui(new Ui::Widget)
{
    ui->setupUi(this);
    this->setWindowTitle("服务端");
    server = new QTcpServer(this);
    // 关联槽函数
    connect(server,&QTcpServer::newConnection,this,[=](){
        // 获取新连接
        QTcpSocket* socket = server->nextPendingConnection();
        // 关联信号槽 readyRead
        connect(socket,&QTcpSocket::readyRead,this,[=](){
            // 读取数据
            QString request = socket->readAll();
            // 处理数据
            QString response = getResponse(request);
            // 返回
            socket->write(response.toUtf8());
            // 回显内容
            QString text = "[" + socket->peerAddress().toString() + ":" + QString::number(socket->peerPort())
                    + "] say# " + request;
            ui->listWidget->addItem(text);
        });
        // 关联信号槽 newConnection
        connect(socket,&QTcpSocket::disconnected,this,[=](){
            // 释放连接
            socket->deleteLater();
        });
    });
    server->listen(QHostAddress::Any,8080);
}
Widget::~Widget()
{
    delete ui;
}
QString Widget::getResponse(const QString &request)
{
    return request;
}

回显客户端

UDP中实现的界面一样,在输入框中输入内容,然后点击发送按钮发送;

cpp 复制代码
Widget::Widget(QWidget *parent)
    : QWidget(parent)
    , ui(new Ui::Widget)
{
    ui->setupUi(this);
    this->setWindowTitle("客户端");
    socket = new QTcpSocket(this);
    // 发起连接请求
    socket->connectToHost("127.0.0.1",8080);
    connect(socket,&QTcpSocket::readyRead,this,[=](){
        // 读取数据
        QString text = socket->readAll();
        // 显示内容
        ui->listWidget->addItem("服务端 : " + text);
    });
}
Widget::~Widget()
{
    socket->deleteLater();
    delete ui;
}
void Widget::on_pushButton_clicked()
{
    QString text = ui->lineEdit->text();
    if(text == "")
        return;
    socket->write(text.toUtf8());
    // 回显
    ui->listWidget->addItem("客户端 : " + text);
    ui->lineEdit->setText("");
}

3. HTTP

除了UDPTCP这些传输层协议,Qt 还对 HTTP协议进行了封装:

QNetworkAccessManagerQNetworkRequestQNetworkReply

QNetworkAccessManager

该类提供了HTTP中核心的方法

  • get(const QNetworkRequest& ) : 发送一个HTTP GET请求,返回一个QNetworkReply对象
  • post(const QNetworkQeqyest& , const QByteArray& ) : 发送一个HTTP POST请求,返回一个QNetworkReply对象

QNetworkRequest

表示一个 HTTP请求,不包含body

核心 方法

  • QNetworkRequest(const QUrl& ) : 通过一个url来构造 HTTP 请求
  • setHeader(QNetworkRequest::KnownHeaders header, const QVariant& value) : 设置请求header部分

QNetworkRequest::KnownHeaders

QNetworkReply

表示一个 HTTP 响应

方法

  • error : 获取出错状态
  • errorString : 获取出错原因
  • readAll : 读取相应 bady
  • header(QNetworkRequest::KnownHeaders header) : 获取对应header的取值

信号

  • finished : 在客户端接收到完整相应时触发

示例:根据用户输入的url,获取网页(html

cpp 复制代码
Widget::Widget(QWidget *parent)
    : QWidget(parent)
    , ui(new Ui::Widget)
{
    ui->setupUi(this);
    manager = new QNetworkAccessManager(this);

}
Widget::~Widget()
{
    delete manager;
    delete ui;
}
void Widget::on_pushButton_clicked()
{
    // 获取用户输入
    QString text = ui->lineEdit->text();
    if(text == "")
        return;
    QUrl url("http://" + text);
    QNetworkRequest request(url);
    QNetworkReply* response = manager->get(request);
    connect(response,&QNetworkReply::finished,this,[=](){
        // 获取数据
        QString data = response->readAll();
        ui->plainTextEdit->setPlainText(data);
    });
}

音频播放

Qt 当中,也是支持音视频播放的;

音频播放就需要引入 multimedia模块,对应的类 QSound

.pro文件,QT +=后加上对应模块

注意 : Qt当中支持的音频格式有限

QSound类对应的方法很简单:

  • 构造函数:音频文件路径、父元素
  • play : 播放对应音频文件
cpp 复制代码
Widget::Widget(QWidget *parent)
    : QWidget(parent)
    , ui(new Ui::Widget)
{
    ui->setupUi(this);
    QSound* sound = new QSound(":/manbo.wav", this);
    connect(ui->pushButton,&QPushButton::clicked,this,[=](){
       sound->play();
       qDebug() << "manbo";
    });
}

本篇文章到这里就结束了,感谢支持

我的博客即将同步至腾讯云开发者社区,邀请大家一同入驻:https://cloud.tencent.com/developer/support-plan?invite_code=2oul0hvapjsws

相关推荐
uoKent2 小时前
c++中的运算符重载
开发语言·c++
你撅嘴真丑2 小时前
第五章 C++与STL入门
开发语言·c++
Allen_LVyingbo2 小时前
用Python实现辅助病案首页主诊断编码:从数据清洗到模型上线(上)
开发语言·python·github·知识图谱·健康医疗
CoderCodingNo2 小时前
【GESP】C++五级练习题 luogu-P2242 公路维修问题
开发语言·c++·算法
傻啦嘿哟2 小时前
Python家庭支出统计:从Excel到可视化图表的完整指南
开发语言·python·excel
csbysj20202 小时前
Ruby 简介
开发语言
YUJIANYUE2 小时前
asp/php日历式值班查询系统2026版
开发语言·php
FJW0208142 小时前
Python装饰器
开发语言·python
Allen_LVyingbo2 小时前
用Python实现辅助病案首页主诊断编码:从数据清洗到模型上线(下)
开发语言·python·安全·搜索引擎·知识图谱·健康医疗