Linux 学习记录49(QT篇)

news2024/11/25 20:23:10

Linux 学习记录49(QT篇)

在这里插入图片描述

本文目录

  • Linux 学习记录49(QT篇)
  • 一、事件处理机制
    • 1. 什么是事件
    • 2. 如何处理事件
      • (1. 当事件发生时
      • (2. QObject类的子类
    • 3. 事件处理函数由来
    • 4. 鼠标和键盘事件
    • 5. 键盘按键示例
  • 二、定时器
    • 1. 定时器事件
    • 2. 代码实现
    • 3. 自制文本闹钟
  • 三、绘制事件(QPaintEvent)
    • 1. 代码实现
  • 四、基于QT的TCP服务器
    • 1. 基于tcp的通信原理
    • 2. qt提供的通信模型
      • (1. 代码实现
      • (2. 自制的TCP服务器

一、事件处理机制

1. 什么是事件

事件是由窗口系统或者自身产生的,用以响应所发生的各类事情,比如用户按下并释放了键盘或者鼠标、窗口因暴露而需要重绘、定时器到时而应有所动作,等等从某种意义上讲,事件比信号更原始,甚至可以认为大多数信号其实都是由事件产生的。比如一个下压式按钮首先感受到的是鼠标事件在进行必要的处理以产生按钮下沉继而弹起的视觉效果之后,才会发射 clicked()信号

2. 如何处理事件

mywnd(自定义类) -继承-> Qwidget -继承-> Qobject

(1. 当事件发生时

当事件发生时,首先被调用的是oobject类中的虚函数event()
其 OEvent型参数标识了具体的事件类型

bool QObject:: event (QEvent* e)
       {
           if (e == mouseEvent)
           {
               void QWidget::mousePressEvent (QMouseEvent* e)
               void QWidget:: mouseReleaseEvent (QMouseEvent* e)
           }
           if(e == keyEvent){
               void QWidget::keyPressEvent (QMouseEvent* e)
               void QWidget:: keyReleaseEvent (QMouseEvent* e)
           }
       }

(2. QObject类的子类

作为QObject类的子类, QWidget类覆盖了其基类中的
   event()虚函数,并根据具体事件调用具体事件处理函数
       void QWidget::mousePressEvent (QMouseEvent* e)
       void QWidget::mouseReleaseEvent (QMouseEvent* e)
       void QWidget::keyPressEvent (QMouseEvent* e)
       void QWidget:: keyReleaseEvent (QMouseEvent* e)
       void QWidget::paintEvent (QPaintEvent* e):

而这些事件处理函数同样也是虚函数,也可以被 QWidget类
的子类覆盖,以提供针对不同窗口部件类型的事件处理

组件的使用者所关心的往往是定义什么样的槽处理什么样的信号,
而组件的实现者更关心覆盖哪些事件处理函数

3. 事件处理函数由来

QObject类 提供了那些可以重写的虚函数
    [virtual] bool QObject::event(QEvent *e) 
            // 参数:事件的类型

QWidgets类, 提供了那些可以重写的虚函数
    [override virtual protected] bool QWidget::event(QEvent *event)
    
    [virtual protected] void QWidget::keyPressEvent(QKeyEvent *event)
    [virtual protected] void QWidget::keyReleaseEvent(QKeyEvent *event)
    [virtual protected] void QWidget::mouseMoveEvent(QMouseEvent *event)
    [virtual protected] void QWidget::mousePressEvent(QMouseEvent *event)
    [virtual protected] void QWidget::mouseReleaseEvent(QMouseEvent *event)
    [virtual protected] void QWidget::mouseDoubleClickEvent(QMouseEvent *event)
    [virtual protected] void QObject::timerEvent(QTimerEvent *event)

QPainter类 ---> 画家类
     void SimpleExampleWidget::paintEvent(QPaintEvent *)
     {
         QPainter painter(this);
         painter.setPen(Qt::blue);
         painter.setFont(QFont("Arial", 30));
         painter.drawText(rect(), Qt::AlignCenter, "Qt");
     }

4. 鼠标和键盘事件

    [virtual protected] void QWidget::keyPressEvent(QKeyEvent *event)
    [virtual protected] void QWidget::keyReleaseEvent(QKeyEvent *event)
    [virtual protected] void QWidget::mouseMoveEvent(QMouseEvent *event)
    [virtual protected] void QWidget::mousePressEvent(QMouseEvent *event)
    [virtual protected] void QWidget::mouseReleaseEvent(QMouseEvent *event)
    [virtual protected] void QWidget::mouseDoubleClickEvent(QMouseEvent *event)
Qt 键值键盘按键
Qt::Key_Return回车键
Qt::Key_Enter换行键
Qt::Key_Enter制表符键
Qt::Key_EscapeEsc键
Qt::Key_Space空格键
Qt::Key_Delete删除键
Qt::Key_Backspace退格键
Qt::Key_Up向上箭头键
Qt::Key_Down向下箭头键
Qt::Key_Left向左箭头键
Qt::Key_Right向右箭头键
Qt::Key_RightF1至F35键

5. 键盘按键示例

头文件中:
class login : public QMainWindow
{
    Q_OBJECT

private slots:

public:
    login(QWidget *parent = nullptr);
    ~login();
    /*定义键盘按下时的处理函数*/
    void keyPressEvent(QKeyEvent* event);

private:
    Ui::login *ui;
};
==================================================
.cpp文件中
/*函数声明*/
void login::keyPressEvent(QKeyEvent* event)
{
    switch(event->key())
    {
        case Qt::Key_Return :{
            当按下回车时执行的代码块
        }break;
        case 'A' :{
            当按下A时执行的代码块
        }break;
    }
}

二、定时器

1. 定时器事件

在qt中,定时器能够实现,让系统每隔给定的时间,自动去调用某个函数
定时器的实现有两种方式:分别是基于对象版和基于事件处理版本
基于对象版本的定时器(QTimer)
基于事件处理函数

1、使用QTimer类实例化一个定时器对象
2、调用该对象的成员函数start(sec),启动时给定超时时间
3、如果定时器给定的时间到位,那么该定时器,就会自动发射一个timeout的信号
4、将该信号与自定义的槽函数绑定在一起,以后会每隔sec时间后,系统会自动调用自定义的槽函数
5、当执行到成员函数stop函数时,才会关闭该定时器
====================================================
基于事件处理函数:
1、无需实例化对象,直接调用自己类中的startTimer(msec),启动一个定时器,并返回该定时器的id
2、系统会每隔msec时间后,自动调用自己类中的timerEvent函数,该函数是虚函数,需要自己进行重写,在该函数中可以使用timerId函数来确定是哪个定时器到位
3、调用自己的killTimer函数来终止一个定时器

2. 代码实现

==================头文件
class Widget : public QWidget
{
    Q_OBJECT
public:
    Widget(QWidget *parent = nullptr);
    ~Widget();
    //重写定时器事件处理函数
    void timerEvent(QTimerEvent *e);
private slots:
    void on_objStartBtn_clicked();
    void timeout_slot();           //自定义处理timeout的信号函数的槽函数
    void on_eventBtn_clicked();
private:
    Ui::Widget *ui;
    //定义一个定时器变量,当做成员变量,因为有多个按钮会用到
    QTimer *obj_timer;
    //定义一个定时器的id
    int event_timer;
};
======================源文件
Widget::Widget(QWidget *parent)
    : QWidget(parent)
    , ui(new Ui::Widget)
{
    ui->setupUi(this);
    //给定时器实例化对象
    obj_timer = new QTimer(this);
    //将定时器发射的timeout信号与自定义的槽函数进行连接
    connect(obj_timer, &QTimer::timeout, this, &Widget::timeout_slot);
}
Widget::~Widget()
{
    delete ui;
}
//对象按钮对应的槽函数
void Widget::on_objStartBtn_clicked()
{
    if(ui->objStartBtn->text() == "启动")
    {
        //执行启动一个定时器
        obj_timer->start(1000);    //启动定时器,每隔1000毫秒后,该定时器会自动发射timeout的信号
        //将按钮文本内容改为"关闭"
        ui->objStartBtn->setText("关闭");
    }else
    {
        //执行关闭一个定时器
        obj_timer->stop();
        //将按钮文本内容改为"启动"
        ui->objStartBtn->setText("启动");
    }
}

//处理timeout信号的槽函数的定义
void Widget::timeout_slot()
{
    //设置文本对齐方式
    ui->objLab->setAlignment(Qt::AlignHCenter | Qt::AlignVCenter;);
    //调用事件类中的静态成员函数获取当前的系统时间
    QTime sys_time = QTime::currentTime();
    //调用成员函数,将时间转换为字符串
    QString t = sys_time.toString("hh:mm:ss");
    //将时间展示到ui界面的lab上
    ui->objLab->setText(t);
}

3. 自制文本闹钟

如有需要在本文顶部获取(含源码)
在这里插入图片描述

三、绘制事件(QPaintEvent)

  1. 绘制事件是qt提供的二维图形引擎,能够让用户绘制各种图形,例如:适量文字、绘制图形、图像。。。
  2. 绘制事件处理函数触发情况:窗口第一次展示、窗口最小化、最大化、窗口从覆盖状态显示出来、手动拖动窗口调大小、调用update函数
  3. 绘制事件,依赖于画家类(QPainter)实现相关绘制工作
    所需头文件:<QWidget> <QPainter>

1. 代码实现

头文件======================
#ifndef WIDGET_H
#define WIDGET_H
#include <QWidget>
#include<QPainter>           //画家类
QT_BEGIN_NAMESPACE
namespace Ui { class Widget; }
QT_END_NAMESPACE
class Widget : public QWidget
{
    Q_OBJECT
public:
    Widget(QWidget *parent = nullptr);
    ~Widget();
    //重写绘制事件
    void paintEvent(QPaintEvent *event) override;
private:
    Ui::Widget *ui;
};
#endif // WIDGET_H
源文件======================
#include "widget.h"
#include "ui_widget.h"
#include<QDebug>
Widget::Widget(QWidget *parent)
    : QWidget(parent)
    , ui(new Ui::Widget)
{
    ui->setupUi(this);
}
Widget::~Widget()
{
    delete ui;
}
//绘制事件处理函数的定义
void Widget::paintEvent(QPaintEvent *event)
{
    //实例化一个画家
    QPainter p(this);
    //给画家安排画笔
    p.setPen(QColor("pink"));
    //给画家安排字体
    p.setFont(QFont("隶书", 40, 10));
    //使用画家绘制文本内容
    p.drawText(this->rect(), Qt::AlignCenter, "好好学习,天天向上");
    //定义一个画笔
    QPen pen(Qt::DashDotDotLine);
    pen.setWidth(15);
    pen.setColor(QColor("blue"));
    p.setPen(pen);          //给画家换一支画笔
    p.setBrush(QBrush(QColor("yellow")));
    //设置 画家的起笔坐标
    //p.translate(this->width()/2, this->height()/2);
    //设置画家的坐标系偏移角度
    //p.rotate(45);
    //用画笔画一个椭圆
    p.drawEllipse(QPoint(0,0), 200,300);
    //绘制图片
    p.drawPixmap(this->rect(), QPixmap("D:/23041QT/day4/04paintEvent/duck.png"));
}

四、基于QT的TCP服务器

1. 基于tcp的通信原理

在这里插入图片描述

2. qt提供的通信模型

在这里插入图片描述

(1. 代码实现

所需头文件: <QTcpServer> <QTcpSocket> <QVector>
需要在obj文件加上 network 如下
在这里插入图片描述

QTcpServer *ser;    //定义服务器指针
QVector<QTcpSocket *> clisok;//定义客户端容器,将连接上来的客户端套接字储存
/*定义服务器*/
ser = new QTcpServer(this);
/*从文本中获取端口号并转化为 无符号整形*/
quint16 port = set_port->text().toUInt();
/*连接服务器*/
if(ser->listen(QHostAddress::Any,port))
{
    QMessageBox::information(this,"成功","打开服务器成功");
}
else
{
    QMessageBox::information(this,"失败","打开服务器失败");
}
/*因为连接上服务器后会发送一个连接的信号,所以将该信号与处理该信号的自定义槽函数连接*/
信号:&QTcpServer::newConnection
connect(ser,&QTcpServer::newConnection,this,&Tcpserver::newconnection_slots);
自定义槽函数:
/*当有新客户端连接*/
void Tcpserver::newconnection_slots()
{
    //获取最新连接的套接字
    QTcpSocket *newfd = ser->nextPendingConnection();
    //把该套接字放入到套接字容器中,append追加,push_back尾插
    clisok.push_back(newfd);
    //一个服务器和多个客户端已经建立连接,如果有客户端向服务器发来数据,
    //那么该客户端就会自动发射一个readyRead的信号
    //我们可以将该信号连接到自定义的槽函数中处理相关逻辑
    当接收到客户端信息时触发信号:&QTcpSocket::readyRead
    connect(newfd,&QTcpSocket::readyRead,this,&Tcpserver::readyRead_slots);
}
//处理readyRead信号对应的槽函数
void Tcpserver::readyRead_slots()
{
    //删除无效的客户端:比如断开的,但是套接字却保存着
    for(int i=0;i<clisok.size();i++)
    {
        //clisok[i]表示任意一个客户端
        if(clisok[i]->state() == 0)
        {
            //等于0,无效连接,删除
            clisok.removeAt(i);     //将当前客户端移除该容器
        }
    }

    //判断是那个客户端发来的数据
    for(int i=0;i<clisok.size();i++)
    {
        //判断发来的套接字中是否有数据待读
        if(clisok[i]->bytesAvailable() != 0)
        {
            //读取当前套接字中的数据
            QByteArray msg = clisok[i]->readAll();

            //把读取的数据放到ui界面上
            text->addItem(QString::fromLocal8Bit(msg));

            //把获取的数据广播给所有客户端
            for(int j=0;j<clisok.size();j++)
            {
                clisok[j]->write(msg);
            }
        }
    }
}

(2. 自制的TCP服务器

如有需要在本文顶部获取(含源码)
在这里插入图片描述

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

Centos7离线模式安装Redis6.2.13详细步骤(rpm方式)

本篇文章主要介绍在CentOS7服务器中安装Redis6.2.13&#xff0c;前提是需要有gcc的环境&#xff0c;那么在此我也会向大家介绍gcc的详细安装过程&#xff0c;参考了很多其它相关博客&#xff0c;但有些博主的文章可能是搬运的&#xff0c;导致我在实操时出现报错&#xff0c;那…

CVE-2023-23752-Joomla权限绕过漏洞研判分析

CVE-2023-23752-Joomla权限绕过漏洞分析 简介 Joomla是一个开源免费的内容管理系统&#xff08;CMS&#xff09;&#xff0c;基于PHP开发。 在其4.0.0版本到4.2.7版本中&#xff0c;存在一处属性覆盖漏洞&#xff0c;导致攻击者可以通过恶意请求绕过权限检查&#xff0c;访问…

Go轻量级线程Goroutine

文章目录 Goroutinegoroutine的创建GPM介绍goroutine调度 道阻且长&#xff0c;行则将至&#xff0c;行而不辍&#xff0c;未来可期&#x1f31f;。人生是一条且漫长且充满荆棘的道路&#xff0c;一路上充斥着各种欲望与诱惑&#xff0c;不断学习&#xff0c;不断修炼&#xff…

第二十一章:用户与权限管理

第二十一章&#xff1a;用户与权限管理 21.1&#xff1a;用户管理 登录MySQL服务器 # 语法 mysql -h hostname|hostIP -P port -u username -p DatabaseName -e "SQL语句"; # -h参数 后面接主机名或者主机IP&#xff0c;hostname为主机&#xff0c;hostIP为主机IP。…

请求响应-简单参数的接受

请求响应 请求&#xff08;HttpServletRequest&#xff09;&#xff1a;获取请求数据响应&#xff08;HttpServletResponse&#xff09;&#xff1a;设置响应数据BS架构&#xff1a;Browser/Server&#xff0c;浏览器/服务器架构。客户端只需要浏览器&#xff0c;应用程序的逻…

BCD码与二进制码的区别与联系

二进制数是整串二进制编码表示一个整数&#xff0c;BCD码是用二进制码逐一表示0&#xff5e;9的整数。 (本笔记适合对整数进制编码有一定了解&#xff0c;熟悉二进制数编码的编程爱好的 coder 翻阅) 【学习的细节是欢悦的历程】 Python 官网&#xff1a;https://www.python.org…

【python】制作一个串口工具(下)!

上一章节我们说了UI界面的设计&#xff0c;这一节来说下怎样实现其功能。 一.实例演示 1.创建一个.py文件&#xff0c;以下代码用来实现获取所有的串口信息&#xff1a; import serial import serial.tools.list_portsfrom PyQt5.QtWidgets import QComboBoxclass My_ComBoBo…

使用Feign进行微服务之间的接口调用:Spring Cloud Alibaba中的声明式服务调用

一、Feign介绍 Feign是一个声明式的HTTP客户端框架&#xff0c;用于简化微服务架构中服务之间的通信。它是Spring Cloud框架的一部分&#xff0c;旨在提供一种优雅且易于使用的方式来定义和调用HTTP请求。 Feign的设计目标是让服务之间的通信变得更加简单和直观。通常情况下&am…

EmEditor自定义快捷键之下一个标签页上一个标签页

EmEditor自定义快捷键 有好几种叫法 下一个标签页上一个标签页 下一个选项卡上一个选项卡 在这里个软件它叫’右侧文档’ ‘左侧文档’ 工具 - 所有配置的属性 - 键盘 - 窗口 - 类别: 选’窗口’ - 依次选 ‘右边的文档’ ‘左边的文档’ 按下新的快捷键 - 是每次只按一个键(不…

简单的复习下与 CSS Flex 布局相关的几个关键属性

揭开align-content、justify-content、align-items和justify-items的神秘面纱&#xff0c;解释它们各自的功能以及在不同的情境下如何使用。 在过去几年中&#xff0c;由于弹性盒子和网格布局的演变&#xff0c;CSS布局设计的艺术发生了重大变化。而这一变革的核心&#xff0c;…

CS231N assignment3 RNN

对作业进行一些形象的解释 首先是def rnn_step_forward&#xff1a; 这里的t时刻其实就是一个句子里面的单词数&#xff0c;为了方便会统一到一个最长长度&#xff0c;对于比这个长度短的部分用null进行填充&#xff0c;并且在方法内部会让Null不进行传播和梯度计算。 我们最…

AIGC的发展史:从模仿到创造,AI的创造性探索

在 AI时代&#xff0c;人工智能不再是简单的机器&#xff0c;而是一个具有无限创造力的创造者。AIGC的诞生是人工智能从模仿到创造的一种进步&#xff0c;也是对人类创造力的一种新探索。 而这种由AI生成的内容究竟是如何发展而来的呢&#xff1f;在本文中&#xff0c;我们将探…

QT检测USB HID设备的拔插

网上的参考代码很多&#xff0c;比如下面这个&#xff1a; QT 检测hid设备拔插打印设备信息_qt hid打印机_研知电子的博客-CSDN博客 但是&#xff0c;参考了很多人的代码&#xff0c;写出来的发现检测不到USB HID设备的拔插。 明明其他人都可以正常使用&#xff0c;那问题应…

java内存区 || 并发

目录 什么是线程&#xff1f; 线程的创建和上下文切换&#xff1a; 线程的入栈和出栈&#xff1a; 堆栈的作用&#xff1a; CPU核心数概念 线程的start状态 就绪队列 操作系统的时间片 线程中代码执行顺序 实际中内存图 什么是线程&#xff1f; 线程的创建和上下文切换…

【android12】给第三方应用APK添加系统签名

一、背景 自己或者客户的第三方apk需要用到很多系统权限&#xff0c;所以要内置到系统目录下&#xff0c;变成系统自带的APP&#xff0c;如果不用系统文件生成的签名安装&#xff0c;会导致APP远程更新失败提示签名错误。 二、环境准备 1.Ubuntu系统&#xff08;推荐1804版本及…

Invalid name=“org.apache.dubbo.config.ApplicationConfig#0“

上一篇文章是springboot 集成 dubbo&#xff1a; spring boot 集成dubbo_Demonor_的博客-CSDN博客 在集成的时候出现了一些异常&#xff0c;在这里记录一下&#xff0c;并排查出原因 异常信息1&#xff1a; [2m2023-07-11 20:38:39.387[0;39m [32m INFO[0;39m [35m21492[0;…

92.qt qml-日期/日期时间/时间选择器(日历选择器)

截图如下所示: 效果图如下所示: 1.前言 QML日历组件我们之前移植过: 67.qt quick-qml自定义日历组件(支持竖屏和横屏)_qml日历_诺谦的博客-CSDN博客 但是该组件内部代码比较坑的就是全部使用自定义对象,导致性能不行,动画卡顿,并且不好加时间选择,所以本章我们重新学…

Mysql 实现批量插入对已存在数据忽略或更新

Mysql 实现批量插入对已存在数据忽略/更新 文章目录 Mysql 实现批量插入对已存在数据忽略/更新一. 表的准备二. 实现2.1 实现原理2.2 批量插入对已存在数据忽略 一. 表的准备 CREATE TABLE demo (id int NOT NULL AUTO_INCREMENT COMMENT 主键id,name varchar(10) DEFAULT NUL…

重磅IntelliJ IDEA 2023.2 新版本即将发布,拥抱 AI

IntelliJ IDEA 近期连续发布多个EAP版本&#xff0c;官方在对用户体验不断优化的同时&#xff0c;也新增了一些不错的功能&#xff0c;尤其是人工智能助手补充&#xff0c;AI Assistant&#xff0c;相信在后续IDEA使用中&#xff0c;会对开发者工作效率带来不错的提升。 以下是…

基于A*的二维多无人机航线规划

Matlab航迹规划仿真——A*算法_航迹起始算法 matlab_致守的博客-CSDN博客 matlab2016及以上可以运行 astar.m function [] astar(Spoint,Epoint,Matrix,m,n,h1,h2) %%寻路 Matrix(Spoint(1),Spoint(2))0; Matrix(Epoint(1),Epoint(2))inf; GMatrix; FMatrix; openlistMatri…