Qt-C++编程入门教程笔记-更新t-c++进阶1-获取本机网卡IP信息-2022/12/22

自学qt文章目录


更新内容:
1.Qt中Qdalog对话框的模态、非模态、半模态;
2.更新自定义信号和槽的第二种写法,SIGNAL和SLOT;
3.更新如何设置控件大小随界面大小变化。



前言

本笔记内容,通过自学总结得出。
第一章:按钮控件常用的API以及如果通过qt帮助文档查找API(函数接口)、qt中对象树和坐标系的规定、重要的信号和槽以及如何自定义信号和槽、MainWindows的使用(菜单栏、工具栏)如何加载资源文件和一些对话框的创建(静态和非静态的)、页面布局和一些控件的使用介绍。
第二章:qt事件,包括鼠标事件、定时器、还有过滤器的基本使用。
第三章:qt绘画
第四章:qt文件读写操作


qt自学笔记

一.按钮控件常用API

2022/9/3打卡

1. QPushButton按钮的创建

代码示例:

//创建第一个按钮
QPushButton *btn=new QPushButton;
//btn->show();//show以顶层方式弹出窗口控件
//让btn对象,依赖在myWidget窗口中
btn->setParent(this);

//显示文本
btn->setText("第一个按钮");

//创建第二个按钮 按照空间的大小创建窗口
QPushButton *btn2 = new QPushButton("第二个按钮",this);

//移动btn2按钮
btn2->move(100,200);

//重置窗口大小
resize(600.400);

//设置固定窗口大小
setFixdSize(600,400);

//设置窗口标题
setWindowTitle("第一个窗口");

2. 对象树

  • 当创建的对象在堆区时候,如果指定的父亲是QObject派生下来的类,或者QObect子类派生下来的类,可以不用管理释放的操作,将对象会放入到对象树中;
  • 一定程度上简化了没存回收机制。
//创建一个自己的按钮对象
MyPushButton *mybtn = new MyPushButton;
mybtn->setText("我自己的按钮");

mybtn->move(200,0);
mybtn->setParent(this);//设置到对象树

3. qt中的坐标系

左上角为原点。
请添加图片描述

4. 信号和槽

连接函数:connect

  1. 第一种写法
connct(btn,&QPushButton::click,this,&QWidget::close);

参数
参数1:信号的发送者
参数2:发送的信号(函数地址)
参数3:信号的接收者
参数4:处理的槽函数(函数的地址)

  1. 第二种写法:采用lamda表达式,可参考目录stackedWidget控件部分代码;
    connect(ui->btn_set,&QPushButton::clicked,[=](){
        ui->widget->setV(50);
    });
  1. 第三种写法:采用SIGNALSLOT,的方法来实现,可参考目录stackedWidget控件部分代码。
connect (ui->changeBtn,SIGNAL (clicked()), this,SLOT (slot_3() ) );

第二种写法(lamda表达式),可能低版本不支持,qt5.0以上的可以采用,低版本需要对pro工程文件进行相应的配置。

自定义信号和槽

5. MainWindows的使用

(1)菜单栏和工具栏

#include "mainwindow.h"
#include "ui_mainwindow.h"
#include <QMenuBar>

/*
1.菜单栏最多只能有一个
2.工具栏可以有多个
*/

MainWindow::MainWindow(QWidget *parent) :
    QMainWindow(parent),
    ui(new Ui::MainWindow)
{
    //重置窗口大小
    resize(600,400);
    //菜单栏创建
    QMenuBar *bar = menuBar();
    //将菜单栏放入窗口中
    setMenuBar(bar);

    //创建菜单
    QMenu *fileMenu = bar->addMenu("文件");
    QMenu *editMenu = bar->addMenu("编辑");

    //创建菜单项
    QAction* fileAction = fileMenu->addAction("新建");
    fileMenu->addAction("打开");
    fileMenu->addSeparator(); //菜单栏分割线
    fileMenu->addAction("关闭");

    //创建工具栏
    QToolBar *toolBar = new QToolBar(this);
    addToolBar(Qt::LeftToolBarArea,toolBar);

    //后期设置,设置左右停靠
    toolBar->setAllowedAreas(Qt::LeftToolBarArea | Qt::RightToolBarArea);

    //设置浮动
    toolBar->setFloatable(false);

    //设置移动总开关
    toolBar->setMovable(false);

    //添加工具栏中的内容
    toolBar->addAction(fileAction);

    //添加工具栏:按钮
    QPushButton *button=new QPushButton("按钮",this);
    toolBar->addWidget(button);

   // ui->setupUi(this);//指向自定义ui界面
}

MainWindow::~MainWindow()
{
    delete ui;
}

运行截图:
在这里插入图片描述

(2)状态栏、浮动窗口、核心部件

状态栏最多有一个;
浮动窗口可以有多个;
核心部件智能有一个;

//设置状态栏,最多有一个
QStatusBar * stBar = statusBar();
//设置到窗口中
setStatusBar(stBar);
//放置标签控件
QLabel * label = new QLable("提示信息",this);
stBar->addWidget(label);

QLabel * label2 = new QLable("右侧提示信息",this);
stBar->addPermanentWidget(label2);

//浮动窗口,只能有一个
QDockWidget * dockWidget = new QDockWidget("浮动窗口",this);
addDockWidget(Qt::BottomDockWidgetArea,dockWidget);
//设置后期停靠区域,只允许上下
dockWidget->setAllowedAreas(Qt::TopDockWidgetArea | Qt::BottomDockWidgetAreas);

//设置中心部件,只能有一个
QTextEdit * edit = new QTextEdit(this);
setCentralWidget(edit);

在这里插入图片描述

(3)添加资源文件

步骤:
1.把需要添加的资源文件拷贝到项目文件中
2.右键项目-》创建Qt Resource File-》命名res
在这里插入图片描述
3.res生成 res.qrc
4.open in editor 进入编辑资源
5.添加前缀、添加文件
在这里插入图片描述
6.使用代码用资源文件

//使用添加Qt资源  ": + 前缀名 + 文件名"
ui->actionNew->setIcon(QIcon(":/Image/Luffy.png")); //actionNew是菜单栏的一个新建

在这里插入图片描述

(4)对话框创建(静态、非静态)

静态创建:不可以对其它窗口进行操作
非静态创建:可以对其它窗口进行操作。

代码示例

#include "mainwindow.h"
#include "ui_mainwindow.h"
#include <QMenuBar>
#include <QLabel>
#include <QStatusBar>
#include <QPushButton>
#include <QDockWidget>
#include <QTextEdit>
#include <QDialog>

MainWindow::MainWindow(QWidget *parent) :
    QMainWindow(parent),
    ui(new Ui::MainWindow)
{
    ui->setupUi(this);//指向自定义ui界面
    ui->actionnew->setIcon(QIcon(":/image/j1.jpg")); //actionNew是菜单栏的一个新建
    //点击创建按钮  弹出一个对话框
    connect(ui->actionnew,&QAction::triggered,[=](){
        //对话框 分类
        //模态对话框:不可以对其它窗口进行操作 , 非模态对话框:可以对其它窗口进行操作。
        
//        //模态创建  阻塞
//        QDialog dlg(this);
//        dlg.resize(200,100);
//        dlg.exec();

        //非模态创建 ,创建堆区(防止一闪而过)
        QDialog * dlg2 = new QDialog(this);
        dlg2->setAttribute(Qt::WA_DeleteOnClose);//55号 属性
        dlg2->resize(200,100);
        dlg2->show();
    });
}

MainWindow::~MainWindow()
{
    delete ui;
}

运行截图:
在这里插入图片描述
拓展:
Qt中的模态、非模态、半模态的定义

  • Qt::NonModal (非静态对话框)—> show()方法,不会阻塞其他界面,后续代码正常运行;
  • Qt::WindowModal(半模态对话框)—> open()方法,即只会阻塞父窗口、父窗口的父窗口;
  • Qt::ApplicationModal(应用程序级模态对话框)—> exec()方法,即会阻塞整个应用程序的所有窗口。

(5)消息对话框

参数1:父亲,参数2:标题,参数3:提示内容,参数4:按键类型,参数5:默认关联回车按键。
其返回值类型是QMessageBox::StandardButton,所以可以使用QMessageBox::Save来判断其选择的选项。

#include "mainwindow.h"
#include "ui_mainwindow.h"
#include <QMenuBar>
#include <QLabel>
#include <QStatusBar>
#include <QPushButton>
#include <QDockWidget>
#include <QTextEdit>
#include <QDialog>
#include <QMessageBox>
#include <QDebug>

MainWindow::MainWindow(QWidget *parent) :
    QMainWindow(parent),
    ui(new Ui::MainWindow)
{
    ui->setupUi(this);//指向自定义ui界面
    ui->actionnew->setIcon(QIcon(":/image/j1.jpg")); //actionNew是菜单栏的一个新建

    //点击创建按钮  弹出一个对话框
    connect(ui->actionnew,&QAction::triggered,[=](){
  
        //消息对话框,QMessageBox静态函数实现
        //错误对话框
        QMessageBox::critical(this,"critical","错误");

        //信息对话框
        QMessageBox::information(this,"info","信息");

        //提问对话框
        //参数1:父亲,参数2:标题,参数3:提示内容,参数4:按键类型,参数5:默认关联回车按键。其返回值类型是QMessageBox::StandardButton,所以可以使用QMessageBox::Save来判断其选择的选项。
        if(QMessageBox::Save == QMessageBox::question(this,"question","提问",QMessageBox::Save | QMessageBox::Cancel))
        {
            qDebug()<<"点击了 save!";
        }
        else
        {
            qDebug()<<"点击了 cancel!";
        }
    });
}

MainWindow::~MainWindow()
{
    delete ui;
}

运行截图
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

(6)拓展对话框

  • 颜色对话框
  • 文件对话框
  • 字体对话框

实例代码


#include "mainwindow.h"
#include "ui_mainwindow.h"
#include <QMenuBar>
#include <QLabel>
#include <QStatusBar>
#include <QPushButton>
#include <QDockWidget>
#include <QTextEdit>
#include <QDialog>
#include <QMessageBox>
#include <QDebug>
#include <QColorDialog>
#include <QFileDialog>
#include <QFontDialog>

MainWindow::MainWindow(QWidget *parent) :
    QMainWindow(parent),
    ui(new Ui::MainWindow)
{

    ui->setupUi(this);//指向自定义ui界面
    ui->actionnew->setIcon(QIcon(":/image/j1.jpg")); 

        //颜色对话框
//        QColor color = QColorDialog::getColor(QColor(255,0,0));
//        qDebug()<<"red = "<<color.red()<<"green = "<<color.green()<<"blue = "<<color.blue();

        //文件对话框
//        QString url =  QFileDialog::getOpenFileName(this,"打开文件");
//        qDebug()<<"usrl = "<<url;

        //字体对话框
        bool flag;
        QFont font = QFontDialog::getFont(&flag,QFont("宋体",36));
        qDebug()<<"字体"<<font.family()<<"字号"<<font.pointSize();
    });
}

MainWindow::~MainWindow()
{
    delete ui;
}

6.页面布局

6.1 简单的登陆示例

1.实现登陆窗口;
在这里插入图片描述

2.利用布局方式将其美化;
3.使用widget进行布局,有水平布局垂直布局栅格布局(一般用于几行几列的布局);
4.默认窗口和控件之间有9间隙,可以调整如下图:
在这里插入图片描述
5.利用弹簧进行间隔布局,设置为fixed,目的是:widget占用太多的面积。
在这里插入图片描述
6.设置密码框为***类型不可见
在这里插入图片描述

最终运行截图:
在这里插入图片描述

6.2 自定义控件大小(sizePolicy)

控件的sizePolicy说明控件在布局管理中的缩放方式。Qt提供的控件都有一个合理的缺省sizePolicy,但是这个缺省值有时不能适合 所有的布局,开发人员经常需要改变窗体上的某些控件的sizePolicy。一个QSizePolicy的所有变量对水平方向和垂直方向都适用。下面列举 了一些最长用的值:

  • A. Fixed:控件不能放大或者缩小,控件的大小就是它的sizeHint。
  • B. Minimum:控件的sizeHint为控件的最小尺寸。控件不能小于这个sizeHint,但是可以放大。
  • C. Maximum:控件的sizeHint为控件的最大尺寸,控件不能放大,但是可以缩小到它的最小的允许尺寸。
  • D. Preferred:控件的sizeHint是它的sizeHint,但是可以放大或者缩小
  • E. Expandint:控件可以自行增大或者缩小

注:sizeHint(布局管理中的控件默认尺寸,如果控件不在布局管理中就为无效的值)

7.控件

(1)按件组

  1. QPushButton 常用按钮;
  2. QToolButton 工具按钮 用于显示图片,如图想显示文字,修改风格,toolButtonStyle,凸起风格autoRaise
  3. radioButton 单选按钮,设置默认 ui->BtnMan->setChecked(true);
  4. checkbox 多选按钮,监听状态,2选中 1半选 0未选中

(2)QListWidget 列表容器控件

ui设计里面,Item View(Model-Based):适用于有数据库的
代码实例:
先在ui界面上拖拽 List Widget 控件,如下:
在这里插入图片描述
第一种方式:

//利用ListWidget写诗
QListWidgetItem * item = new  QListWidgetItem("渭水一条流");//一行
//将一行诗放入到listWidget控件中
ui->listWidget->addItem(item);
//设置居中模式
item->setTextAlignment(Qt::AlignHCenter);

第二种方式:

QStringList list;
list << "渭水一条流" << "千山与万丘";
ui->listWidget->addItems(list);

在这里插入图片描述

(3)TreeWidget 树控件

代码实例:

//treeWidget树控件使用

//设置水平头
ui->treeWidget->setHeaderLabels(QStringList()<<"英雄"<<"英雄介绍");

QTreeWidgetItem * liItem = new QTreeWidgetItem(QString()<<"力量");
QTreeWidgetItem * MinliItem = new QTreeWidgetItem(QString()<<"敏捷");
QTreeWidgetItem * ZhiliItem2 = new QTreeWidgetItem(QString()<<"力量");

//加载顶层的节点
ui->treeWidget->addTopLevelItem(liItem);
ui->treeWidget->addTopLevelItem(liItem);
ui->treeWidget->addTopLevelItem(liItem);

//追加子节点
QStringList heroL1;
heroL1<<"骑士"<<"攻防兼备!";
QTreeWidgetItem * ll = new QTreeWidgetItem(heroL1);
liItem->addChild(ll);

在这里插入图片描述

(4)TableWidget 控件

//TableWidget控件
//设置列数
ui->tableWidget->setColumnCount(3);

//设置水平表头
ui->tableWidget->setHorizontalHeaderLabels(QStringList()<<"姓名"<<"性别"<<"年龄");

//设置行数
ui->tableWidget->setRowCount(3);

//设置正文

//第一种方式
//ui->tableWidget->setItem(0,0,new QTableWidgetItem("小李"));

//第二种方式
QStringList nameList;
nameList<<"小李"<<"大李"<<"老李";

QList<QString> sexall;
sexall<<"男"<<"男"<<"男";
for(int i=0;i<2;i++)
{
	int column = 0 ;
	ui->tableWidget->setItem(i,column++,new QTableWidgetItem(nameList[i]));
	ui->tableWidget->setItem(i,column++,new QTableWidgetItem(sexall.at[i]));
//int 转 QString
	ui->tableWidget->setItem(i,column++,new QTableWidgetItem(QString::number(i+18)));
}

在这里插入图片描述

(5)其它常用控件介绍

(1)Tool Box

类似于qq分组
在这里插入图片描述

(2)Tab Widget

类似于网页
在这里插入图片描述

(3)Stack Widget

设计ui界面:切换页,可以把不同的控件加入进去。
在这里插入图片描述

设计栈控件的使用

实例代码:
ui设计界面,如图:
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

#include "widget.h"
#include "ui_widget.h"
#include <QStackedWidget>

Widget::Widget(QWidget *parent) :
    QWidget(parent),
    ui(new Ui::Widget)
{
    ui->setupUi(this);
    //栈控件使用
    //设置默认定位
    ui->stackedWidget->setCurrentIndex(0);
    //信号槽:tool box
    connect(ui->toolareaBtn,&QPushButton::clicked,[=](){
        ui->stackedWidget->setCurrentIndex(0);
    });
    //信号槽:tab widget
    connect(ui->tabwidgetBtn,&QPushButton::clicked,[=](){
        ui->stackedWidget->setCurrentIndex(1);
    });
    //信号槽:scroll box
    connect(ui->scrollboxBtn,&QPushButton::clicked,[=](){
        ui->stackedWidget->setCurrentIndex(2);
    });
}

Widget::~Widget()
{
    delete ui;
}

运行截图:
在这里插入图片描述
拓展:

这里展示conncet的另一种使用:SIGNAL和SLOT的方式。自定义信号和槽
功能实现。点击切换按钮,实现stackedWidget进行界面切换,分别显示不同的按钮,当超过索引值后,会重新从0开始。
1.首先拖拽stackedwidget到ui设计界面上
在这里插入图片描述
2.增加3个item成员,按钮1、按钮2、按钮3
在这里插入图片描述

在widget.h添加如下:

public :
int index;
public slots:
void slot_3();

在widget.cpptian添加如下:

//构造函数里面添加
index=0;
ui->stackedwidget->setCurrentIndex (index) ;
connect (ui->changeBtn,SIGNAL (clicked()), this,SLOT (slot_3() ) );

//实现函数
void Widget::slot_3()
{
index+=1;
if (index >= ui->stackedwidget->count ())
{
index = 0;
}
ui->stackedwidget->setCurrentIndex (index) ;
}

(4)comboBox控件的使用

在这里插入图片描述
设置一个按钮来自动选择“游侠”

 //combox控件
    QStringList slist;
    slist<<"骑士"<<"游侠"<<"法师"<<"牧师";
    ui->comboBox->addItems(slist);
    ui->comboBox->setCurrentIndex(0);
    connect(ui->pushButton,&QPushButton::clicked,[=](){
        ui->comboBox->setCurrentIndex(1);
    });
    

(5)label控件的使用

1.添加图片

    //使用label控件添加图片
      QPixmap* map=new QPixmap(":/image/j1.jpg");
      ui->label_pto->setPixmap(*map);

2.添加gif

   //使用label控件添加动图gif
    ui->label_pto->setMovie(new QMovie(":/image/g1.gif"));
    ui->label_pto->movie()->start();

(6)自定义控件封装

实例测试:
1.新建文件:
在这里插入图片描述
2.选择模板Widget
在这里插入图片描述
3.新建文件
在这里插入图片描述

4.添加QSpinbox控件和QSlider控件。

在这里插入图片描述
之后在widget.ui界面拖拽一个widget控件(因为progressbar.ui就是一个widget控件),右键把拖拽的widget控件提升为,即可。
在这里插入图片描述

在这里插入图片描述

代码实例

设置两个按钮:
按钮一:点击后可以获取进度条的值
按钮二:点击后可以把进度条的值设置为50

progressbar.h

    //通过按钮设置进度条进度
    void setV(int number);
    //通过按钮获取进度条的值
    int getV();
    

progreebar.cpp

//实现接口:通过按钮设置进度条进度
void Progressbar::setV(int number){
    ui->spinBox->setValue(number);
}

//实现接口:通过按钮获取进度条的值
int Progressbar::getV(){
    int number = ui->spinBox->value();
    return number;
}
//这里缺少Qspinbox控件和QSlider控件的互联代码:

函数指针和指针函数的使用:
函数指针:函数为一个指针,void (*hanshuzhizhen)(int);,括号的优先级大于*
指针函数:返回值为一个指针,void * zhizhenhanshu (int);

widget.cpp

实现两个控件相互连接,达到改变其中一个值,另一个也会跟着改变。

   //connect:获取值
    connect(ui->btn_get,&QPushButton::clicked,[=](){
       qDebug()<< ui->widget->getV();
    });

    //conncet:设置值
    connect(ui->btn_set,&QPushButton::clicked,[=](){
        ui->widget->setV(50);
    });

控件总结:
从过去的9月14日~9月24日,完成了qt常用控件的使用:
学习方式:记笔记、实例代码等。

二、qt事件

1.鼠标事件自定义

在这里插入图片描述

2.QpushButton自带的点击信号

首先分析QPushButton的点击信号,QPushButton有三个常用的信号:

  • pressed() :当鼠标在button上并点击左键的时候发射,最先执行;
  • released() :当鼠标左键被释放的时候
  • clicked() :当鼠标首先按下pressed,然后释放,最后执行;
  • toggled() :按下之后状态发生变化,触发toggled;

pressed和clicked的区别
首先,这两个信号都是从QAbstractButton继承来的,也就是对AbstractButton的所有子类都适用。
按键长按事件的原理就是鼠标按下 “一定” 时间后会启动一个多次触发的TimerEvent(定时器),由timeOut再次触发click槽。

实例(自定义):
项目:
在这里插入图片描述

(1)自动控件封装,只不过这次创建的是c++ class
在这里插入图片描述

(2)在widget.ui上拖拽一个;QLable控件,将其提升·为cmouse
在这里插入图片描述

这里需要注意,cmouse的父类必须和要封装的控件(Qlable)是一样的,例如:
comouse.h
class cmouse : public QLabel
cmouse.cpp
cmouse::cmouse(QWidget *parent) : QLabel(parent)

(3)代码示例
cmouse.h

**#ifndef CMOUSE_H
#define CMOUSE_H

#include <QWidget>
#include <QLabel>

class cmouse : public QLabel
{
    Q_OBJECT
public:
    explicit cmouse(QWidget *parent = nullptr);
    //鼠标进入
    void enterEvent(QEvent *event);
    //鼠标离开
    void leaveEvent(QEvent *event);
    //鼠标移动
    void mouseMoveEvent(QMouseEvent *ev);
    //鼠标按下
    void  mousePressEvent(QMouseEvent *ev);
    //鼠标释放
    void  mouseReleaseEvent(QMouseEvent *ev);
signals:
public slots:
};

#endif // CMOUSE_H
**

cmouse.cpp

#include "cmouse.h"
#include <QDebug>
#include <QString>
#include <QMouseEvent>

cmouse::cmouse(QWidget *parent) : QLabel(parent)
{
    //设置鼠标追踪状态
    //setMouseTracking(false);//鼠标不需要按键就可以追踪识别
}
//鼠标进入
void cmouse::enterEvent(QEvent *event)
{
    qDebug()<<"鼠标进入";
}
//鼠标离开
void cmouse::leaveEvent(QEvent *event)
{
    qDebug()<<"鼠标离开";
}
//鼠标移动
void cmouse::mouseMoveEvent(QMouseEvent *ev)
{
    //鼠标左键按下移动,重点。。。
//    //错误方式,待理解。。。
//    if(ev->button() == Qt::LeftButton)
//    {
//            qDebug()<<"鼠标移动";
//    }
    //正确方式
    if(ev->buttons() & Qt::LeftButton)
    {
        QString st = QString("鼠标的位置 x = %1  ,  y = %2 ").arg(ev->x()).arg(ev->y());
        qDebug()<<"鼠标移动:"<<st;
    }
}
//鼠标按下
void cmouse::mousePressEvent(QMouseEvent *ev)
{
    //鼠标左键按下

    if(ev->button() == Qt::LeftButton)
    {
        QString st = QString("鼠标的位置 x = %1  ,  y = %2 ").arg(ev->x()).arg(ev->y());
        qDebug()<<"鼠标按下:"<<st;
    }
}
//鼠标释放
void cmouse::mouseReleaseEvent(QMouseEvent *ev)
{
    qDebug()<<"鼠标释放";
}

运行截图
在这里插入图片描述

2.定时器

(1) 定时器的第1种方式

示例:
目录结构
在这里插入图片描述

首先:在widget界面拖拽两个Label控件,ObjectName分别是label和label_2。
在这里插入图片描述
代码示例:
widget.h

#ifndef WIDGET_H
#define WIDGET_H

#include <QWidget>

namespace Ui {
class Widget;
}

class Widget : public QWidget
{
    Q_OBJECT

public:
    explicit Widget(QWidget *parent = nullptr);

    //设置定时器id标识
    int st1;
    int st2;

    //设置定时器
    void timerEvent(QTimerEvent *event);


    ~Widget();

private:
    Ui::Widget *ui;
};

#endif // WIDGET_H

widget.cpp

#include "widget.h"
#include "ui_widget.h"
#include <QDebug>

Widget::Widget(QWidget *parent) :
    QWidget(parent),
    ui(new Ui::Widget)
{
    ui->setupUi(this);
    
    //记录每个timerid,便于后面标识
    st1 = startTimer(1000);
    st2 = startTimer(2000);
    qDebug() << "st1-id : "<<st1<<endl;
    qDebug() << "st2-id : "<<st2;
}

Widget::~Widget()
{
    delete ui;
}

//设置定时器
void Widget::timerEvent(QTimerEvent *event)
{
    if(event->timerId() ==  st1)
    {
        //定时器1:1秒的增加
        static int number1 = 1;
        ui->label->setText(QString::number(number1++));//QString::number(int),函数的作用:把参数int型转换成 QString类型
    }
    if(event->timerId() == st2)
    {
        //定时器2:2秒的增加
        static int number2 = 1;
        ui->label_2->setText(QString::number(number2++));
    }
}

这里用到一个QString::number(int)的函数;
函数的作用:把参数int型转换成 QString类型。

运行截图
在这里插入图片描述

(2) 定时器的第2种方式

代码示例:

    //定时器第2种方式
    QTimer *timer1 = new QTimer(this);
    timer1->start(500);
    
    connect(timer1,&QTimer::timeout,[=](){
        static int number3 = 1;
        ui->label_3->setText(QString::number(number3++));//QString::number(int),函数的作用:把参数int型转换成 QString类型
    });

    connect(ui->pushButton,&QPushButton::clicked,[=](){
        timer1->stop();
        delete timer1;
    });

运行截图:
在这里插入图片描述
今日打卡!2022/9/27

3.event事件分发器

用途:用于事件分发
可以做拦截操作,不建议
返回值如果是true,则代表用户处理这个事件,不向下分发了。
在这里插入图片描述
代码示例:

这里代码接着1.鼠标事件,代码。

cmouse.h

    //事件的分发
    bool event(QEvent* e);

cmouse.cpp

bool cmouse::event(QEvent *e)
{
    //判断事件,通过type()函数
    if(e->type() == QEvent::MouseButtonPress)
    {
        //把QEvent转换为QMouseButton,知识点
        QMouseEvent * ev = static_cast<QMouseEvent *>(e);
        //打印鼠标位置信息
        QString st = QString("event 捕捉的:  鼠标的位置 x = %1  ,  y = %2 ").arg(ev->x()).arg(ev->y());
        qDebug()<<"鼠标移动:"<<st;
        //代表用户自己处理
        return true;
    }
    //其它事件交给父类处理  默认处理
    return QLabel::event(e);
}

运行截图:
在这里插入图片描述

4.事件过滤器

在这里插入图片描述
项目结构

与qt鼠标事件统一项目

在这里插入图片描述

代码示例:
widget.h

    //事件过滤器
    bool eventFilter(QObject *watched, QEvent *e);

wifget.cpp

#include "widget.h"
#include "ui_widget.h"
#include <QDebug>
#include <QEvent>
#include <QMouseEvent>

Widget::Widget(QWidget *parent) :
    QWidget(parent),
    ui(new Ui::Widget)
{
    ui->setupUi(this);
    //给label安装事件过滤器
    //步骤1:安装事件过滤器
    ui->label->installEventFilter(this);
}

Widget::~Widget()
{
    delete ui;
}
//步骤2:重写eventfilter事件
bool Widget::eventFilter(QObject *watched, QEvent *e)
{
    if(watched == ui->label)
    {
        //判断事件,通过type()函数
        if(e->type() == QEvent::MouseButtonPress)
        {
            //把QEvent转换为QMouseButton
            QMouseEvent * ev = static_cast<QMouseEvent *>(e);
            //打印鼠标位置信息
            QString st = QString("eventfilter 捕捉的:  鼠标的位置 x = %1  ,  y = %2 ").arg(ev->x()).arg(ev->y());
            qDebug()<<"鼠标移动:"<<st;
            //代表用户自己处理
            return true;
        }
    }
    //其它事件交给父类处理  默认处理
    return Widget::eventFilter(watched,e);
}

三、qt绘画

(1) 基础绘画

目录结构
在这里插入图片描述

代码示例:
widget.h

    //绘画事件
    void paintEvent(QPaintEvent*);

widget.cpp

#include "widget.h"
#include "ui_widget.h"
#include <QPen>
#include <QBrush>

Widget::Widget(QWidget *parent) :
    QWidget(parent),
    ui(new Ui::Widget)
{
    ui->setupUi(this);
}

//绘画事件
void Widget::paintEvent(QPaintEvent*)
{
    //创建实例画家对象,this指的是绘图的设备
    QPainter paint(this);

    //设置画笔
    QPen pen(QColor(255,0,0));
    //设置宽度
    pen.setWidth(2);
    //设置风格
    pen.setStyle(Qt::DotLine);

    //设置画刷
    QBrush brush(Qt::cyan);
    //设置画刷风格
    brush.setStyle(Qt::Dense2Pattern);
    //让画家使用画刷
    paint.setBrush(brush);

    //画线
    paint.drawLine(QPoint(20,20),QPoint(80,80));
    //画圆,椭圆
    paint.drawEllipse(QPoint(100,100),80,80);
    //画矩形
    paint.drawRect(20,20,100,80);
    //画文字
    paint.drawText(QRect(20,20,100,100),"给我笑~");
}

Widget::~Widget()
{
    delete ui;
}

运行截图:
在这里插入图片描述

(2) 高级绘画

代码实例:
1.添加抗锯齿效果

//绘画事件
void Widget::paintEvent(QPaintEvent*)
{
	QPainter painter(this);
	painter.drawEllipse(QPoint(100,40),60,60);
	//设置抗锯齿效果
	painter.drawEllipse(QPainter::Antialiasing);
	painter.drawEllipse(QPoint(200,40),60,60);
}	

2.画家操作
移动画家、保存画家、还原画家等操作。

其实就是改变开始绘图的其实位置,刚开始默认的是原点 ( 0 , 0 )。

//绘画事件
void Widget::paintEvent(QPaintEvent*)
{
//画矩形
panter.drawRect(QRect(20,20,50,50));
//移动画家
painter.translate(100,0);
//保存画家状态
painter.save();

painter.drawRect(QRect(20,20,50,50));
painter.translate(100,0)

//还原画家保存状态
painter.restore();
painter.drawRect(QRect(20,20,50,50));
}

3.手动调用绘图事件
代码实例:

添加一个按钮,点击按钮会使乳图片向右移动,当距离超过一定范围,会从原点开始移动。

widget.h

//添加一个=公共变量。
public :
int posX = 0;

widget.cpp


#include "widget.h"
#include "ui_widget.h"

Widget::Widget(QWidget *parent) :
    QWidget(parent),
    ui(new Ui::Widget)
{
    ui->setupUi(this);
    connect(ui->pushbutton,&QPushButton::clicked,[=](){
	posX+=20;
	//如果需要手动调用绘图事件  用update
	update();
});
    
}
//绘画事件
void Widget::paintEvent(QPaintEvent*)
{
if(posX > ui.width())
{
posX = 0;
}
//利用绘图事件绘画图片
QPainter painter(this);
painter.drawPixmap(posX,0,QPixmap(":/Image/.png"));
}

四、qt文件读写操作

代码实例


//点击选取文件按钮,弹出文件对话框
connect(ui->pushbutton,&QPushButton::clicked,[=](){
QString path = QFileDialog::getOpenFileName(this,"打开文件","C:\\Users\\Desktop");
//将路径放到lineEdit中
ui->linetext->setText(path);

//读取内容放入到editText中
//QFile读写的文件格式默认为utf-8
QFile qfile(path);//参数就是路径
//设置编码格式类
QTextCodec * codec = QTextCodec::codecForName("gbk");
//设置打开方式
file.open(QIODevice::ReadOnly);

QByteArray array = qfile.readAll();

//将读取到的数据放入到textEdit控件中
ui->textedit->setText(codec->toUnicode(array));
//对文件进行关闭
qfile.close();

//对文件进行写操作
qfile.open(QIODevice::Append);//采用追加方式进行写
qfile.write("新添加的内容......");
qfile.close();
});

qfile.readLine() //读取文件行
可通过while(!qfile->atEnd())来实现读取整个文件的内容。
在这里插入图片描述


五、qt-c++进阶1-获取本机网卡IP信息

本章主要是通过qt-c++实现获取本机电脑的网卡信息或者是IP信息

获取windows本地所有网关IP的方法
获取本地指定网卡名的IP的方法。

1.1 获取ip地址

  1. QHostAddress解析获取本机IPV4地址
  2. QNetworkInterface解析获取所有网关信息(IP地址(IPV4和IPV6)子网掩码广播地址);
  3. 根据上面的方法,总结出,根据本机网卡名去获取相应的IPV4地址

1.2 代码实例

提供3个函数在widget.h中,在widget.cpp分别对其实现,具体如下:

void getHostIP(); //获取本机ipv4地址
void getAllIP(); //获取本机所有网卡信息
void getDesignateIP(); //获取本机的制定ip信息

目录结构
在这里插入图片描述

代码示例:

widget.h

#ifndef WIDGET_H
#define WIDGET_H

#include <QWidget>

namespace Ui {
class Widget;
}

class Widget : public QWidget
{
    Q_OBJECT

public:
    explicit Widget(QWidget *parent = nullptr);
    
    void getHostIP();//获取本机ipv4地址
    void getAllIP();//获取本机所有网卡信息
    void getDesignateIP();//获取本机的制定ip信息

    ~Widget();

private:
    Ui::Widget *ui;
};

#endif // WIDGET_H

widget.cpp

#include "widget.h"
#include "ui_widget.h"
#include <QList>
#include <QNetworkInterface>
#include <QDebug>

Widget::Widget(QWidget *parent) :
    QWidget(parent),
    ui(new Ui::Widget)
{
    ui->setupUi(this);
    getHostIP();
    getAllIP();
}

Widget::~Widget()
{
    delete ui;
}

void Widget::getDesignateIP()
{
    QList<QNetworkInterface> list = QNetworkInterface::allInterfaces();
    //获取所有网络接口的列表
    foreach(QNetworkInterface interface,list)
    {
        QList<QNetworkAddressEntry> entryList = interface.addressEntries();
        //获取IP地址条目列表,每个条目中包含一个IP地址,一个子网掩码和一个广播地址
        if(interface.humanReadableName() == "VMware Network Adapter VMnet8")
        {
            foreach(QNetworkAddressEntry entry,entryList)
            {
                if(entry.ip()!=QHostAddress::LocalHost && entry.ip().toIPv4Address())
                {
                    //设备名
                    qDebug() << "Device: "<<interface.name();
                    qDebug() << "Device: "<<interface.humanReadableName();
                    //IP信息
                    qDebug()<<"IP Address: "<<entry.ip().toString();              
                }
            }
        }
    }
}

void Widget::getHostIP()
{
    QList<QHostAddress> list = QNetworkInterface::allAddresses();
    foreach (QHostAddress address, list)
    {
        if(address.protocol() == QAbstractSocket::IPv4Protocol)
            //我们使用IPv4地址
            qDebug()<<address.toString();
    }
     qDebug()<<endl;
}

void Widget::getAllIP()
{
    QList<QNetworkInterface> list = QNetworkInterface::allInterfaces();
    //获取所有网络接口的列表
    foreach(QNetworkInterface interface,list)
    {  //遍历每一个网络接口
        qDebug() << "Device: "<<interface.name();
        //设备名
        qDebug() << "HardwareAddress: "<<interface.hardwareAddress();
        //硬件地址
        QList<QNetworkAddressEntry> entryList = interface.addressEntries();
        //获取IP地址条目列表,每个条目中包含一个IP地址,一个子网掩码和一个广播地址
        foreach(QNetworkAddressEntry entry,entryList)
        {//遍历每一个IP地址条目
            qDebug()<<"IP Address: "<<entry.ip().toString();
            //IP地址
            qDebug()<<"Netmask: "<<entry.netmask().toString();
            //子网掩码
            qDebug()<<"Broadcast: "<<entry.broadcast().toString();
            //广播地址
        }
        qDebug()<<endl;
    }
}

运行截图:
在这里插入图片描述

参考链接:https://www.cnblogs.com/liushui-sky/p/6479110.html


总结:

从10月1日,到现在一直没有怎么去写文章,一直在休息。很喜欢的两句话:
“今天无论是开心还是难过,一天都会过去,看你自己是苦苦的等待,还是挺起身来坚持努力度过。”
“成长很大一部分是接受,接受分道扬镳、接受世事无常、接受孤独挫败、接受突如其来的无力感、接受自己的缺点、然后发自内心的改变,天黑开盏灯、下雨带把伞。难过先难过,但不作死,天亮以后,满血复活”。加油~
新的规划:
1.qt复习,找一个项目根学(打牢基础);
2.java网络编程(主要是TCP和UDP);
3.计算机网络-网络边缘和网络核心。

  • 1
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

暴躁茹

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值