一、案例1创建ui界面文件1.直接创建含ui界面文件的类:2.一个不含ui界面文件的类如何与一个新建的ui界面文件(举例form.ui)关联起来第一步:先添加一个界面文件第二步在类(举例MainWindow).h文件中做出如下修改#ifndef MAINWINDOW_H #define MAINWINDOW_H #include QMainWindow namespace Ui { class abc; }//新加代码 class MainWindow : public QMainWindow { Q_OBJECT public: MainWindow(QWidget *parent nullptr); ~MainWindow(); private: Ui::abc *ui;//新加代码 }; #endif // MAINWINDOW_H第三步 在类(举例MainWindow).cpp文件中做出如下修改#include mainwindow.h #include ui_form.h// 新加代码与ui文件名有关 MainWindow::MainWindow(QWidget *parent) : QMainWindow(parent) , ui(new Ui::abc) // 新加代码 { ui-setupUi(this);// 新加代码 } MainWindow::~MainWindow() { delete ui;// 新加代码 }注意事项abc均为对象的名称不要写成ui文件名了。二、案例2自定义封装控件目标微调框与水平滑块封装在一起任意模块改变数值另一个模块的数值也会发生相应的变化点击“获取当前值”按钮会将当前值以一个消息框的形式弹出。1.控件封装详细步骤2.ui界面文件3.测试代码在CostomWidget.cpp中写入如下代码CostomWidget::CostomWidget(QWidget *parent) : QWidget(parent) , ui(new Ui::CostomWidget) { ui-setupUi(this); connect(ui-spinBox,QSpinBox::valueChanged,ui-horizontalSlider,QSlider::setValue);//数字设定框发生变化时进度条也发生变化 connect(ui-horizontalSlider,QSlider::valueChanged,ui-spinBox,QSpinBox::setValue); } void CostomWidget::setnum(int num) { ui-spinBox-setValue(num); } int CostomWidget::getnum() { return ui-spinBox-value(); } CostomWidget::~CostomWidget() { delete ui; }在CostomWidget.h的类中写入如下代码void setnum(int num); int getnum();在MainWidget.cpp的构造函数中写入如下代码connect(ui-btn1,QPushButton::clicked,this,[](){ QString str QString(当前值为%1).arg(ui-widget-getnum()); QMessageBox::information(this,info,str); }); connect(ui-btn2,QPushButton::clicked,this,[](){ ui-widget-setnum(50); });三、案例3定时器的使用方法目标标签中的数字从1开始递增每过500毫秒数字的值1点击“暂停”按钮停止递增。在MainWidget.cpp的构造函数中写入如下代码QTimer *tim1 new QTimer(this); tim1-start(500); connect(tim1,QTimer::timeout,ui-label,[](){ static int i 1; ui-label-setText(QString::number(i)); }); connect(ui-btn3,QPushButton::clicked,tim1,QTimer::stop);或者可以这样写QTimer::singleShot(500, this,[](){ static int i 1; ui-label-setText(QString::number(i)); }); connect(ui-btn3,QPushButton::clicked,tim1,QTimer::stop);四、案例4将一个 控件 与 类 关联起来目标将一个QLabel控件与MyLabel类绑定并且实现相应鼠标事件的检测。1.先写好MyLabel类①MyLabel.h代码class MyLabel : public QLabel { Q_OBJECT public: explicit MyLabel(QWidget *parent nullptr); void enterEvent(QEnterEvent *event)override;//鼠标进入事件 void leaveEvent(QEvent *event)override;//鼠标离开事件 void mouseMoveEvent(QMouseEvent *ev)override; void mousePressEvent(QMouseEvent *ev) override; void mouseReleaseEvent(QMouseEvent *ev) override; signals: };②MyLabel.cpp代码MyLabel::MyLabel(QWidget *parent) : QLabel{parent} { setMouseTracking(1);//在QWidget中//设置鼠标追踪状态//加上这行代码这后不管有没有鼠标按下mouseMoveEvent函数都会触发//否则只有当鼠标按下时才会触发mouseMoveEvent } void MyLabel::enterEvent(QEnterEvent *event) { qDebug() 鼠标进入了; } void MyLabel::leaveEvent(QEvent *event) { qDebug() 鼠标离开了; } void MyLabel::mouseMoveEvent(QMouseEvent *ev) { //if(ev-buttons() Qt::LeftButton)//鼠标按钮处于稳态触发要用buttons函数//即鼠标按下之后移动才会触发mouseMoveEvent事件 { QString str QString(鼠标移动了 x %1 y %2 glabolx %3 glaboly %4).arg(ev-pos().x()).arg(ev-pos().y()).arg(ev-globalPosition().x()).arg(ev-globalPosition().y());//.arg() 是 Qt 的 QString 类的字符串格式化方法。它用于将参数插入到字符串的占位符中。 qDebug() str; } } void MyLabel::mousePressEvent(QMouseEvent *ev) { if(ev-button() Qt::LeftButton)//若不加这一行代码这不管鼠标那一个按键按下都会执行函数中的代码 { QString str QString(鼠标按下了 x %1 y %2 glabolx %3 glaboly %4).arg(ev-pos().x()).arg(ev-pos().y()).arg(ev-globalPosition().x()).arg(ev-globalPosition().y());//.arg() 是 Qt 的 QString 类的字符串格式化方法。它用于将参数插入到字符串的占位符中。 qDebug() str; } } void MyLabel::mouseReleaseEvent(QMouseEvent *ev) { if(ev-button() Qt::LeftButton) { QString str QString(鼠标释放了 x %1 y %2 glabolx %3 glaboly %4).arg(ev-pos().x()).arg(ev-pos().y()).arg(ev-globalPosition().x()).arg(ev-globalPosition().y());//.arg() 是 Qt 的 QString 类的字符串格式化方法。它用于将参数插入到字符串的占位符中。 qDebug() str; } }2.在MainWidget.ui界面中添加一个新的Label控件---右键---找到如下窗口点击添加:再将该鼠标检测框---右键--提升为 MyLabel。3.事件分发器(event)与事件过滤器(eventfilter)①这两个事件返回值都是bool类型如果返回true表示用户要自己处理这个事情不向下分发事件。②以鼠标移动事件举例当鼠标移动时若目标(举例label)安装了事件过滤器则先通过事件过滤器检测若成功拦截则不再向下分发事件否则到达事件分发器若事件分发器成功拦截则不再向下分发事件否则到达mouseMoveEvent。代码测试①在mylabel.h类的声明中写入如下代码bool event(QEvent *e) override;//重写事件分发器②在mylabel.cpp中写入如下代码bool MyLabel::event(QEvent *e) { if(e-type() QEvent::MouseMove)//如果鼠标移动在event事件分发中做拦截操作 { QMouseEvent *ev dynamic_castQMouseEvent*(e);//此处涉及类型转换 QString str QString(event函数中鼠标移动了 x %1 y %2 glabolx %3 glaboly %4).arg(ev-pos().x()).arg(ev-pos().y()).arg(ev-globalPosition().x()).arg(ev-globalPosition().y());//.arg() 是 Qt 的 QString 类的字符串格式化方法。它用于将参数插入到字符串的占位符中。 qDebug() str; return true;//代表用户自己处理该事件不向下分发 } return QLabel::event(e);//其他事件交给父类 }③在mainwidget.h类的声明中写入如下代码bool eventFilter(QObject *object, QEvent *event) override;//重写事件过滤器④在mainwidget.cpp中写入如下代码#include mainwindow.h #include ui_mainwindow.h #include QMouseEvent MainWindow::MainWindow(QWidget *parent) : QMainWindow(parent) , ui(new Ui::MainWindow) { ui-setupUi(this); ui-label-installEventFilter(this); } //第二步重写事件过滤器 bool MainWindow::eventFilter(QObject *object, QEvent *event) { if(object ui-label) { if(event-type() QEvent::MouseMove) { QMouseEvent *ev dynamic_castQMouseEvent*(event); QString str QString(eventFilter函数中鼠标移动了 x %1 y %2 glabolx %3 glabolx %4).arg(ev-pos().x()).arg(ev-pos().y()).arg(ev-globalPosition().x()).arg(ev-globalPosition().y());//.arg() 是 Qt 的 QString 类的字符串格式化方法。它用于将参数插入到字符串的占位符中。 qDebug() str; return true; } } return QWidget::eventFilter(object,event); } MainWindow::~MainWindow() { delete ui; }结果分析①事件过滤器函数、事件分发器函数和鼠标移动事件函数同时存在的情况下事件过滤器函数发挥作用。②事件分发器函数和鼠标移动事件函数同时存在的情况下事件分发器函数发挥作用。五、查漏补缺1.格式化字符串的使用方法QString str QString(鼠标释放了 x %1 y %2 glabolx %3 glaboly %4).arg(ev-pos().x()).arg(ev-pos().y()).arg(ev-globalPosition().x()).arg(ev-globalPosition().y());2.类型转换//类型转换 基本类型转换 double d 3.14; int i static_castint(d); // i 3 类层次结构中的上行转换安全 class Base {}; class Derived : public Base {}; Derived derived; Base* basePtr static_castBase*(derived); // 安全派生类→基类 类层次结构中的下行转换 class Base { virtual void foo() {} }; // 必须有虚函数 class Derived : public Base {}; Base basePtr; Derived* derivedPtr dynamic_castDerived*(basePtr);