QT系统篇(5)(上)

一、事件

1.常见事件

2.了解事件和信号槽的区别

信号槽事件 都是建立某种关系。信号槽 是通过信号与槽函数之间 的连接实现对象间通信;事件 是通过重写事件处理函数 (即利用多态机制)来实现对特定事件的响应。

3.鼠标进入和离开代码实现

创建完模板,在创建一个C++ Class文件,下一步在创建对应那个QT类,然后在把对应控件的父类调整成我们创建的类,然后点击添加即可。

cpp 复制代码
//label.h
#ifndef LABEL_H
#define LABEL_H

#include <QWidget>
#include <QLabel>
#include <QDebug>
#include <QEvent>
class Label : public QLabel
{
	Q_OBJECT
public:
   Label(QWidget* parent);
   void enterEvent(QEvent* event);//重写进入
   void leaveEvent(QEvent* event);//重写退出
};

#endif 

//label.cpp


#include "label.h"
Label::Label(QWidget* parent)
	:QLabel(parent)//使用父类构造函数
{}

void Label::enterEvent(QEvent* event)
{
   (void) event;
   qDebug()<<"进入";
}

void Label::leaveEvent(QEvent* event)
{
   (void) event;
   qDebug()<<"退出";
}

1.1 鼠标事件

1.获取鼠标点击位置

cpp 复制代码
//label.h
#ifndef LINEEDIT_H
#define LINEEDIT_H

#include <QWidget>
#include <QDebug>
#include <QLabel>
#include <QMouseEvent>
class Label : public QLabel
{
	Q_OBJECT
public:
    Label(QWidget* parent);
    void mousePressEvent(QMouseEvent* event);
};

#endif // LINEEDIT_H

//label.cpp

#include "lineedit.h"

Label::Label(QWidget* parent)
	:QLabel(parent)
{}
void Label::mousePressEvent(QMouseEvent* event)
{
    if(event->button() == Qt::LeftButton)
    {
        qDebug()<<"按下左键";
    }
    else if(event->button() == Qt::RightButton)
    {
        qDebug()<<"按下右键";
    }
	qDebug()<< event->x() << "," << event->y();//获取x与y坐标
}

2.鼠标释放

cpp 复制代码
void Widget::mouseReleaseEvent(QMouseEvent* event)
{
    (void)event;//处理警告,就是变量如果不使用就会这样
    qDebug()<<"鼠标左键被释放";
}

3.鼠标双击事件

cpp 复制代码
void Widget::mouseDoubleClickEvent(QMouseEvent* event)
{
    (void)event;
    qDebug()<<"鼠标被双击";
}

重点: 鼠标双击事件 一定会触发鼠标单击事件,因为双击本身就包含两次快速的单击操作。

4.鼠标移动

cpp 复制代码
//把这个选项设置为true,才可以追踪,因为鼠标追踪会导致卡顿
this->setMouseTracking(true);
void Widget::mouseMoveEvent(QMouseEvent *event)
{
	qDebug()<<event->x() << event->y();
}

5.滚轮事件

cpp 复制代码
void Widget::wheelEvent(QWheelEvent *event)
{
	static int x = 0;//统计滚动距离

	x += event->delta(); //一次滚动120

    if(event->delta() > 0)
    {
       qDebug()<<"滚轮向前" << x;
    }
    else
    {
       qDebug()<<"滚轮向后" << x;
    }
}

1.2 键盘事件

1.键盘了解

Qt 中的按键事件 是通过 QKeyEvent 类来实现的。

2.单个按键

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

3.组合键

cpp 复制代码
//组合按键
void Widget::keyPressEvent(QKeyEvent *event)
{
   if(event->modifiers() == Qt::ControlModifier)//判断是否是ctrl键被按下
   if(event->key() == Qt::Key_A)
   {
       qDebug()<<"Ctrl + A被按下";
   }
}

1.3 定时器事件

1.了解

QTimerEvent 类用来描述一个定时器事件 。在使用时需要通过 startTimer() 函数来开启一个定时器,这个函数需要输入一个以毫秒为单位的整数作为参数来设定时间 ,它返回的整型值代表这个定时器的编号 。当定时器溢出时(即定时时间到达),就可以在 timerEvent() 函数中获取该定时器的编号来进行相关操作。

2.方法

timerId

cpp 复制代码
int QObject::timerId() const;

// 功能:
// 返回当前活动定时器的 ID(如果该对象有一个活动的定时器),否则返回 0

// 参数说明:
// 无参数

// 返回值:
// int:
// - 若该对象当前有一个活动的定时器(通过 startTimer() 启动),则返回该定时器的 ID
// - 若没有活动的定时器,则返回 0

3.代码

cpp 复制代码
//启动定时器
timer_id1 = startTimer(1000);//一秒一次
timer_id2 = startTimer(2000);//两秒一次

void Widget::timerEvent(QTimerEvent *event)
{
    if(event->timerId() == timer_id1)
    {
       static int num1 = 1;

       //num1每隔一秒加一次
       ui->label->setText(QString::number(num1++));
    }
    if(event->timerId() == timer_id2)
    {
       static int num2 = 1;

       //num2每隔两秒加一次
       ui->label_2->setText(QString::number(num2++));
    }
}

4.重点

QTimer和QTimerEvent的区别

  • QTimer 不需要管理 timerId ,而 QTimerEvent 需要管理 timerId,因此 QTimerEvent 使用得比较少。

1.4 窗口事件

1.窗口移动事件

cpp 复制代码
void Widget::moveEvent(QMoveEvent *event)
{
    (void)event;
    qDebug()<<"窗口移动";
}

2.窗口大小改变事件

cpp 复制代码
void Widget::resizeEvent(QResizeEvent *event)
{
    (void)event;
    qDebug()<<"窗口大小改变";
}

二、文件系统

1.介绍

1.介绍文件系统

在 Qt 中,文件读写的类为 QFileQFile 的父类为 QFileDevice ,QFileDevice 提供了文件交互操作的底层功能。QFileDevice 的父类是 QIODevice ,QIODevice 的父类为 QObject

QIODevice 是 Qt 中所有输入输出设备(input/output device,简称 I/O 设备)的基础类。I/O 设备就是能进行数据输入和输出的设备,例如文件是一种 I/O 设备,网络通信中的 socket 是 I/O 设备,串口、蓝牙等通信接口也是 I/O 设备,所以它们也是从 QIODevice 继承来的。Qt 中主要的一些 I/O 设备类的继承关系如下图所示。

  • QFile 是用于文件操作和文件数据读写的类,使用 QFile 可以读写任意格式的文件。

  • QSaveFile 是用于安全保存文件的类。使用 QSaveFile 保存文件时,它会先把数据写入一个临时文件 ,成功提交后才将数据写入最终的文件。如果保存过程中出现错误,临时文件里的数据不会被写入最终文件,这样就能确保最终文件中不会丢失数据或被写入部分数据。在保存比较大的文件或复杂格式的文件时可以使用这个类,例如从网络上下载文件等。

  • QTemporaryFile 是用于创建临时文件的类。使用函数 QTemporaryFile::open() 就能创建一个文件名唯一的临时文件,在 QTemporaryFile 对象被删除时,临时文件被自动删除

  • QTcpSocketQUdpSocket 是分别实现了 TCPUDP 的类。

  • QSerialPort 是实现了串口通信的类,通过这个类可以实现计算机与串口设备的通信。

  • QBluetoothSocket 是用于蓝牙通信 的类。手机和平板计算机等移动设备有蓝牙通信模块,笔记本电脑一般也有蓝牙通信模块。通过 QBluetoothSocket 类,就可以编写蓝牙通信程序,如编程实现笔记本电脑与手机的蓝牙通信。

  • QProcess 类用于启动外部程序,并且可以给程序传递参数。

  • QBuffer 以一个 QByteArray 对象作为数据缓冲区 ,将 QByteArray 对象当作一个 I/O 设备来读写。

2.1 文件读写类

1.了解

QFile 类中提供了一些用来读写文件的方法。对于文件的操作主要有:

  • 读数据QFile 类中提供了多个方法用于读取文件内容,如 read()(想读多少读多少)readAll()(读取所有)readLine()(每次读一行) 等。
  • 写数据QFile 类中提供了多个方法用于往文件中写内容,如 write() 等。
  • 关闭文件 :文件使用结束后必须用函数 close() 关闭文件。

2.文件打开方式

3.代码

cpp 复制代码
//.h
#include <QMenuBar>
#include <QMenu>
#include <QAction>
#include <QPlainTextEdit>
#include <QFile>
#include <QFileDialog>
#include <QStatusBar>
private slots:
void HandleAction1();
void HandleAction2();
private:
QPlainTextEdit* edit;

//.cpp
//获取菜单栏
QMenuBar* menuBar = this->menuBar();
//添加菜单
QMenu* menu = new QMenu("文件");
menuBar->addMenu(menu);
//添加菜单项
QAction* action1 = new QAction("打开");
QAction* action2 = new QAction("保存");
menu->addAction(action1);
menu->addAction(action2);

//指定一个输入框
edit = new QPlainTextEdit();
QFont font;
font.setPixelSize(20);
edit->setFont(font);
this->setCentralWidget(edit);

//连接QAction信号槽
connect(action1,&QAction::triggered,this,&MainWindow::HandleAction1);
connect(action2,&QAction::triggered,this,&MainWindow::HandleAction2);

//打开文件
void MainWindow::HandleAction1()
{
    //1.先弹出"打开文件"对话框,让用户选择打开那个文件
    QString path = QFileDialog::getOpenFileName(this);
    
    //2.把文件名显示到状态栏里面
    QStatusBar* statuBar = this->statusBar();
    statusBar()->showMessage(path);
    
    //3.根据用户选择的路径,构建一个QFile对象,并打开
    QFile file(path);
    bool ret = file.open(QFile::ReadOnly);//以只读方式打开
    if(!ret)
    {
       //打开文件失败
       statuBar->showMessage(path + "文件打开失败");
       return;
    }
    
    //4.读取文件(读取所有)
    QString text = file.readAll();
    
    //5.关闭文件
    file.close();
    
    //6.读取到的内容设置到输入框中
    edit->setPlainText(text);
}
//保存文件
void MainWindow::HandleAction2()
{
    //1.先弹出"保存文件"对话框
    QString path = QFileDialog::getSaveFileName(this);
    
    //2.把文件名显示到状态栏里面
    QStatusBar* statuBar = this->statusBar();
    statusBar()->showMessage(path);
    
    //3.根据用户选择的路径,构建一个QFile对象,并打开
    QFile file(path);
    bool ret = file.open(QFile::WriteOnly);//以只写方式打开
    if(!ret)
    {
       //打开文件失败
       statuBar->showMessage(path + "文件打开失败");
       return;
    }
    
    //4.写文件
    const QString& text = edit->toPlainText();
    file.write(text.toUtf8());
    
    //5.关闭文件
    file.close();
}

2.2 文件和目录信息类

1.了解

QFileInfo 是 Qt 提供的一个用于获取文件和目录信息 的类,如获取文件名、文件大小、文件修改日期等。QFileInfo 类中提供了很多的方法,常用的有:

  • isDir():检查该文件是否是目录;

  • isExecutable():检查该文件是否是可执行文件;

  • fileName():获得文件名(含后缀);

  • completeBaseName():获取完整的基础文件名(不含后缀);

  • suffix():获取文件后缀名;

  • completeSuffix():获取完整的文件后缀(如".tar.gz");

  • size():获取文件大小(字节);

  • isFile():判断是否为文件;

  • fileTime():获取文件的创建时间、修改时间、最近访问时间等。