Qt第六章 多窗口编程

一、QMessageBox 消息对话框(掌握)

QMessageBox继承自QDialog,是一个Qt内置的用来展示信息或询问用户一个问题的模态对话框。

预设了四种类型:

像那些已经写好的窗口,这些现成的东西都会有一些特性,就是他们的对象都不需要new或者说他们就不需要拿到对象,他们为了方便我们使用会用一个静态成员函数就可以把弹窗显示出来。上面的四种类型想要显示就需要用对应的静态成员函数

四种弹窗的参数和返回值基本一致:

参数1:父窗口

参数2:标题文字

参数3:展示信息内容

返回值:用户点击的按钮,默认情况下只有question类型的弹窗有必要接收返回值

只要是预设的对话框他们想要拿数据他一定是通过返回值拿数据 静态成员函数的返回值

不是Q开头的大概路是枚举

我们这个对话框只有只有yes和no所以只有要判断返回值是yes还是no可以判断用户点击的是什么

示例代码下载链接:百度网盘 请输入提取码

提取码:hqyj

--来自百度网盘超级会员V6的分享

dialog.cpp

#include "dialog.h"
#include "ui_dialog.h"

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

    group = new QButtonGroup(this);
    group->addButton(ui->btnInfomation,1);
    group->addButton(ui->btnWarning,2);
    group->addButton(ui->btnCritical,3);
    group->addButton(ui->btnQuestion,4);
    group->addButton(ui->btnCustom,5);

    connect(group,SIGNAL(buttonClicked(int)),
            this,SLOT(btnsClickedSlot(int)));
}

Dialog::~Dialog()
{
    delete group;
    delete ui;
}

void Dialog::custom()
{
    // 创建自定义的QMessageBox对象
    QMessageBox* box = new QMessageBox(this);
    // 设置标题
    box->setWindowTitle("自定义QMessageBox");
    // 准备一个图片对象
    QPixmap pic(":/new/prefix1/new_year.png");
    // 设置图标
    box->setIconPixmap(pic);
    // 设置消息内容
    box->setText("2023年即将到来,你感到快乐吗?");
    // 创建两个按钮对象
    QPushButton* btn1 = new QPushButton("快乐",box);
    QPushButton* btn2 = new QPushButton("不快乐",box);
    // 添加按钮到弹窗的正确位置
    box->addButton(btn1,QMessageBox::YesRole);
    box->addButton(btn2,QMessageBox::NoRole);
    // 展示弹窗
    box->show();
}

void Dialog::btnsClickedSlot(int id)
{
    if(id == 1)
        QMessageBox::information(this,"information","网络已连接!");
    else if(id == 2)
        QMessageBox::warning(this,"warning","网络波动!");
    else if(id == 3)
        QMessageBox::critical(this,"critical","无法检测到网络!");
    else if(id == 4)
    {
        QMessageBox::StandardButton result = QMessageBox::question(this,"question","您是否没插网线?");
        if(result == QMessageBox::Yes)
            qDebug() << "我是无线我插什么网线?";
        else if(result == QMessageBox::No)
            qDebug() << "有线性能一定比无线好。";
    }
    else if(id == 5)
        custom();
}

二、常见的窗口类(掌握)

本次Qt学习到的窗口类之间的继承关系如下图所示。

  • QObject

        所有Qt类的基类,本身并不是窗口类。

  • QWidget

        如果创建时制定parent参数的值,此时QWidget对象会作为制定参数对应的窗口内部的组件;如果创建时不传入parent参数的值,此时QWidget对象会作为一个独立的窗口。

  • QMainWindow

        通常使用此类作为应用程序的主窗口,主窗口包含菜单栏、工具栏、中心组件与状态栏。因为使用相对复杂,所以一直讲课未用。

  • QDialog

        通常作为子窗口存在的对话框窗口,特点是组成简单。比较简单的程序可以使用此类型作为主窗口。

  • QMessageBox

        QDialog的一个派生类,主要用于消息展示和提问。

  • QFileDialog

        QDialog一个派生类,主要用于浏览本地磁盘的文件并选择。

所有的窗口类共有一些属性和函数,例如:

  • windowTitle : QString

所有窗口的标题,可以通过getter和setter进行读写。

void QWidget::setWindowState(Qt::WindowStates windowState)

设置窗口状态,参数值如下:

  • windowFlags : Qt::WindowFlags

窗口标记,支持同时通过setter设定多个标记,多个标记之间使用|分割

常用的标记有:

dialog.cpp

#include "dialog.h"
#include "ui_dialog.h"

Dialog::Dialog(QWidget *parent) :
    QDialog(parent),
    ui(new Ui::Dialog)
{
    ui->setupUi(this);
    // 设置窗口
    setWindowTitle("哈哈哈哈哈哈哈哈");
    // 设置窗口状态(全屏)
//    setWindowState(Qt::WindowFullScreen);
    // 设置窗口标记     关闭缺省的标题窗口栏      创建无边框窗口
    setWindowFlags(Qt::WindowStaysOnTopHint|Qt::FramelessWindowHint);
}

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

 

三、QMainWindow 主窗口

QMainWindow非常适合作为程序的主窗口因为程序的各种功能可以设置到菜单栏和工具栏中,同时状态栏可以显示当前软件的信息。

QMainWindow主要由四部分组成:

这四个部分的初始化设置可以通过Designer完成,也可以在C++代码中完成

QMenuBar中的每个菜单对应类型是QMenuQMenu中可以放置各种触发效果,每个触发效果的类型是QAction

 

你加了这个新建以后它叫做QAction 每个触发效果的类型是 QAction

新建变成了二级菜单 只有最终能点击触发效果的才会变成QAction  

QAction的配置在Designer中通过专属的面板完成:

在上面的面板中找到要编辑的QAction对象,双击即可配置参数。

QAction有以下信号函数:

可以使用拖拽的方式把QAction编程工具栏中的按钮,最好给QAction提前设置好图标。

关于状态栏QStatusBar有两个常用的槽函数:

void QStatusBar::clearMessage() [slot]

清空状态栏信息显示

void QStatusBar::showMessage(const QString & message, 
                             int timeout = 0) [slot]

设置状态栏信息显示

参数1:显示的文字信息

参数2:显示的时长,单位毫秒,0表示持续显示

示例代码下载链接:https://pan.baidu.com/s/15DZlTkMDviC6J5_p0NTL4A 

提取码:hqyj

--来自百度网盘超级会员V6的分享

mainwindow.cpp

#include "mainwindow.h"
#include "ui_mainwindow.h"

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

    // 肉眼可见的对象都归ui指针管理
    connect(ui->actionNew,SIGNAL(triggered()),
            this,SLOT(triggeredSlot()));

    connect(ui->pushButtonShow,SIGNAL(clicked()),
            this,SLOT(btnShowClickedSlot()));
    connect(ui->pushButtonClear,SIGNAL(clicked()),
            this,SLOT(btnClearClickedSlot()));
}

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

void MainWindow::triggeredSlot()
{
    QMessageBox::information(this,"提示","已新建文件!!!!!!");
}

void MainWindow::btnShowClickedSlot()
{
    ui->statusBar->showMessage("哈哈哈哈哈哈哈",5000);
}

void MainWindow::btnClearClickedSlot()
{
    ui->statusBar->clearMessage();
}

mainwindow.h

#ifndef MAINWINDOW_H
#define MAINWINDOW_H

#include <QMainWindow>
#include <QMessageBox>

namespace Ui {
class MainWindow;
}

class MainWindow : public QMainWindow
{
    Q_OBJECT

public:
    explicit MainWindow(QWidget *parent = 0);
    ~MainWindow();

private:
    Ui::MainWindow *ui;

private slots:
//    与void triggered()信号连接
    void triggeredSlot();

    // 两个按钮点击的槽函数
    void btnShowClickedSlot();
    void btnClearClickedSlot();
};

#endif // MAINWINDOW_H

四、内存管理

Qt的内存管理机制与C++不同,几乎所有的Qt类的构造函数都有一个名为parent的参数,此参数表示设置当前对象的父对象父对象不仅仅表示子组件与父窗口之间的显示关系,更表示在内存回收上的依赖关系。

建议尽量给对象传入parent参数,以便于保持Qt的内存回收机制;如果不传入parent参数则需要留意内存回收的时机。

堆内存对象尽量传parent

示例代码下载链接:https://pan.baidu.com/s/1Ed7T4CzPSC6DJJXH-hfOCg 

提取码:hqyj

--来自百度网盘超级会员V6的分享

dialog.cpp

#include "dialog.h"
#include "ui_dialog.h"

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

    connect(ui->pushButtonYes,SIGNAL(clicked()),
            this,SLOT(btnYesClickedSlot()));
    connect(ui->pushButtonNo,SIGNAL(clicked()),
            this,SLOT(btnNoClickedSlot()));
}

Dialog::~Dialog()
{
    delete ui;
    qDebug() << "析构函数";
}

void Dialog::btnYesClickedSlot()
{
    // 创建一个子窗口对象并展示,使用parent参数
    Dialog* d = new Dialog(this);
    d->show();
}

void Dialog::btnNoClickedSlot()
{
    // 创建一个子窗口对象并展示,不使用parent参数
    Dialog* d = new Dialog;
    d->show();
}

dialog.h

#ifndef DIALOG_H
#define DIALOG_H

#include <QDialog>
#include <QDebug>

namespace Ui {
class Dialog;
}

class Dialog : public QDialog
{
    Q_OBJECT

public:
    explicit Dialog(QWidget *parent = 0);
    ~Dialog();

private:
    Ui::Dialog *ui;

private slots:
    void btnYesClickedSlot();
    void btnNoClickedSlot();
};

#endif // DIALOG_H

传入parent参数打开的窗口 后面的会依赖前面的哪一个如果前面的窗口关闭后面的也会关闭

不传入parent参数每个窗口都是独立的没有依赖关系  但是回收时需要手动回收 堆内存对象手动delete 栈内存对象无所谓  主要是针对堆内存  

加了parent就不用考虑手动回收了

五、自定义窗口类

下面手动创建一个自定义窗口类对象,操作步骤如下:

1. 选中项目名称,鼠标右键,点击“添加新文件”

2. 在弹出的窗口中,按照下图所示进行操作。

3. 在弹出的窗口中,先选择要创建的窗口类型,再点击“下一步”。

4. 在新弹出的窗口中,给类命名后,点击“下一步”。

5. 在项目管理界面,直接点击“完成”。可以看到项目中多了一个窗口类的头文件、源文件和界面文件。

示例代码下载链接:百度网盘 请输入提取码

提取码:hqyj

--来自百度网盘超级会员V6的分享

dialog.h

#ifndef DIALOG_H
#define DIALOG_H

#include <QDialog>
// 引入MyDialog类的头文件
#include "mydialog.h"

namespace Ui {
class Dialog;
}

class Dialog : public QDialog
{
    Q_OBJECT

public:
    explicit Dialog(QWidget *parent = 0);
    ~Dialog();

private:
    Ui::Dialog *ui;

private slots:
    // 点击按钮触发的槽函数
    void btnClickedSlot();
};

#endif // DIALOG_H

mydialog.h

#ifndef MYDIALOG_H
#define MYDIALOG_H

#include <QDialog>

namespace Ui {
class MyDialog;
}

class MyDialog : public QDialog
{
    Q_OBJECT

public:
    explicit MyDialog(QWidget *parent = 0);
    ~MyDialog();

private:
    Ui::MyDialog *ui;
};

#endif // MYDIALOG_H

dialog.cpp

#include "dialog.h"
#include "ui_dialog.h"

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

    connect(ui->pushButton,SIGNAL(clicked()),
            this,SLOT(btnClickedSlot()));
}

void Dialog::btnClickedSlot()
{
    // 创建MyDialog类对象
    MyDialog* md = new MyDialog(this);
    // 展示
    md->show();
}

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

上述功能为点击dialog界面的按钮会打开mydialog窗口

六、参数传递

6.1 成员函数传参

【例子】转动上面代码中的绿色QDial,橙色QDial跟随绿色QDial一起转动。

示例代码下载链接:https://pan.baidu.com/s/1OpgiIiyV6WjQFLhlBsF4pw 

提取码:hqyj

--来自百度网盘超级会员V6的分享

主窗口去主导 然后子窗口跟着动一般使用成员函数 或者构造函数

dialog.h

#ifndef DIALOG_H
#define DIALOG_H

#include <QDialog>
// 引入MyDialog类的头文件
#include "mydialog.h"

namespace Ui {
class Dialog;
}

class Dialog : public QDialog
{
    Q_OBJECT

public:
    explicit Dialog(QWidget *parent = 0);
    ~Dialog();

private:
    Ui::Dialog *ui;
    MyDialog* md = NULL; // 子窗口对象 要写成成员的 局部的拿不到主窗口传的数值

private slots:
    // 点击按钮触发的槽函数
    void btnClickedSlot();
    // 检测绿色QDial转动的槽函数void	valueChanged(int value)
    void valueChangedSlot(int);
};

#endif // DIALOG_H

mydialog.h

#ifndef MYDIALOG_H
#define MYDIALOG_H

#include <QDialog>

namespace Ui {
class MyDialog;
}

class MyDialog : public QDialog
{
    Q_OBJECT

public:
    explicit MyDialog(QWidget *parent = 0,int value = 0);//构造函数传参 要遵循向右原则 第一个//参数赋值 后面的必须赋值 还要注意 声明定义在一个地方赋值就行
//保证两个的起始位置在一个地方, 第二个参数就是创建完盖子窗口时子窗口的初始位置
    ~MyDialog();
    // 公开一个函数可以设置橙色QDial的数值
    void setValue(int);
    //注意上面的成员函数不能写成私有的 因为写的这个函数要给主窗口里面去调用实在类外调用的

private:
    Ui::MyDialog *ui;
};

#endif // MYDIALOG_H

dialog.cpp

#include "dialog.h"
#include "ui_dialog.h"

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

    connect(ui->pushButton,SIGNAL(clicked()),
            this,SLOT(btnClickedSlot()));
    connect(ui->dial,SIGNAL(valueChanged(int)),
            this,SLOT(valueChangedSlot(int)));
}

void Dialog::btnClickedSlot()
{
    //因为主窗口可以拿到子窗口的一个对象 就可以很方便的去调用子窗口里面的任意一个函数
    // 创建MyDialog类对象 要写成成员的不然别的函数调用不了
    md = new MyDialog(this,ui->dial->value());
    // 展示
    md->show();
    // 屏蔽按钮  原因你只能操控一个子窗口多的操作不了
    ui->pushButton->setEnabled(false);
}

void Dialog::valueChangedSlot(int value)
{
    if(md != NULL)//防止没创建子窗口时就转导致的程序异常 因为你转的话会调用该槽函数 这里面的md没有创建出来  加了该代码就不会走下面的代码
        // 把参数值传递给第二个窗口对象
        md->setValue(value);
}

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

mydialog.cpp

#include "mydialog.h"
#include "ui_mydialog.h"

MyDialog::MyDialog(QWidget *parent,int value) ://因为在声明处赋予初始值了 这里就不用再写了
    QDialog(parent),
    ui(new Ui::MyDialog)
{
    ui->setupUi(this);
    // 初始化QDial的数值
    ui->dial->setValue(value);//构造函数传参
}

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

void MyDialog::setValue(int value)
{
    // 设置显示的数值
    ui->dial->setValue(value);
}

6.2 信号槽传参

【例子】转动上面代码中的橙色QDial,绿色QDial跟随橙色QDial一起转动。

就是右边的东西发送到左边来

链接:https://pan.baidu.com/s/1owM93_UPSQpAqQ7NRqZafA 

提取码:hqyj

--来自百度网盘超级会员V6的分享

dialog.h

#ifndef DIALOG_H
#define DIALOG_H

#include <QDialog>
// 引入MyDialog类的头文件
#include "mydialog.h"
#include <QDebug>

namespace Ui {
class Dialog;
}

class Dialog : public QDialog
{
    Q_OBJECT

public:
    explicit Dialog(QWidget *parent = 0);
    ~Dialog();

private:
    Ui::Dialog *ui;
    MyDialog* md = NULL; // 子窗口对象

private slots:
    // 点击按钮触发的槽函数
    void btnClickedSlot();
    // 检测绿色QDial转动的槽函数void	valueChanged(int value)
    void valueChangedSlot(int);
    // 接收子窗口发来的信号的槽函数
    void valueSlot(int);
};

#endif // DIALOG_H

mydialog.h

#ifndef MYDIALOG_H
#define MYDIALOG_H

#include <QDialog>

namespace Ui {
class MyDialog;
}

class MyDialog : public QDialog
{
    Q_OBJECT

public:
    explicit MyDialog(QWidget *parent = 0,int value = 0);
    ~MyDialog();
    // 公开一个函数可以设置橙色QDial的数值
    void setValue(int);

private:
    Ui::MyDialog *ui;

private slots:
    // 接收橙色QDial数值变化的槽函数
    void valueChangedSlot(int);

signals:
    // 发射橙色QDial数值的信号函数(声明完就可以用) 什么时候发射每一次橙色数值变化的时候就发射
    void valueSignal(int);
};

#endif // MYDIALOG_H

dialog.cpp

#include "dialog.h"
#include "ui_dialog.h"

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

    connect(ui->pushButton,SIGNAL(clicked()),
            this,SLOT(btnClickedSlot()));
    connect(ui->dial,SIGNAL(valueChanged(int)),
            this,SLOT(valueChangedSlot(int)));
}

void Dialog::btnClickedSlot()
{
    // 创建MyDialog类对象  为啥后面是ui->dial->value()是因为通过定义是的默认参数value=0 这个就是获得那个默认参数
    md = new MyDialog(this,ui->dial->value());
    // 建立两个窗口间通信的信号槽连接
    connect(md,SIGNAL(valueSignal(int)),
            this,SLOT(valueSlot(int)));

    // 展示
    md->show();
    // 屏蔽按钮
    ui->pushButton->setEnabled(false);
}

void Dialog::valueChangedSlot(int value)
{
    if(md != NULL)
        // 把参数值传递给第二个窗口对象
        md->setValue(value);
}

void Dialog::valueSlot(int value)
{
    // 更新显示
    ui->dial->setValue(value);
}

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

mydialog.cpp

#include "mydialog.h"
#include "ui_mydialog.h"

MyDialog::MyDialog(QWidget *parent,int value) :
    QDialog(parent),
    ui(new Ui::MyDialog)
{
    ui->setupUi(this);
    // 初始化QDial的数值
    ui->dial->setValue(value);
    // 连接QDial数值监听的信号槽  发送出去然后第一个界面来接收
    connect(ui->dial,SIGNAL(valueChanged(int)),
            this,SLOT(valueChangedSlot(int)));
}

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

void MyDialog::setValue(int value)
{
    // 设置显示的数值
    ui->dial->setValue(value);
}

void MyDialog::valueChangedSlot(int value)
{
    // 发射自定义信号
    emit valueSignal(value);
}

七、事件机制

7.1 事件机制原理

事件机制是Qt的核心逻辑,事件是程序运行的过程中的某些操作,这些操作会在操作系统与应用程序中逐层传递。

上图表示的是从用户操作到操作系统,再到应用程序的传递过程,对于Qt开发的应用程序而言,事件也会在应用程序内部逐层传递,如下所示。

操作系统发送给应用程序的大管家 再发给当前正在获取焦点的子组件 最后把事件给父组件(比如按钮子组件 处理完事情后给最后给窗口 窗口时父组件

7.2 事件函数

本次授课在事件传递的最后一个环节,即父窗口中使用事件函数检测事件传递。

所有事件函数的用法基本相同,常用的事件函数如下:

// 绘制
void QWidget::paintEvent(QPaintEvent * event) [virtual protected] 
// 大小改变
void QWidget::resizeEvent(QResizeEvent * 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 QWidget::mouseMoveEvent(QMouseEvent * event) [virtual protected]
// 组件本身移动
void QWidget::moveEvent(QMoveEvent * event) [virtual protected]
// 按键按压
void QWidget::keyPressEvent(QKeyEvent * event) [virtual protected]
// 按键释放
void QWidget::keyReleaseEvent(QKeyEvent * event) [virtual protected]
// 获取焦点
void QWidget::focusInEvent(QFocusEvent * event) [virtual protected]
// 失去焦点
void QWidget::focusOutEvent(QFocusEvent * event) [virtual protected]
// 关闭
void QWidget::closeEvent(QCloseEvent * event) [virtual protected]
// 鼠标进入
void QWidget::enterEvent(QEvent * event) [virtual protected]
// 鼠标离开
void QWidget::leaveEvent(QEvent * event) [virtual protected]

QPainter是画家类,可以在QPaintDevice的派生类上绘制各种各种的图形,QPaintDevice是QWidget的基类,即QWidget及其所有派生类都可以被QPainter对象进行绘制。

QPainter::QPainter(QPaintDevice * device)

QPainter的构造函数,参数是在哪个对象上作画。

void QPainter::drawPixmap(int x, int y, int width, int height, const QPixmap & pixmap)

绘制QPixmap的内容。

参数1:绘制内容的横坐标,定位点是绘制内容的左上角

参数2:绘制内容的纵坐标,定位点是绘制内容的左上角

参数3:绘制内容的宽度

参数4:绘制内容的高度

参数5:绘制的内容

示例代码下载链接:百度网盘 请输入提取码

提取码:hqyj

--来自百度网盘超级会员V6的分享

dialog.h

#ifndef DIALOG_H
#define DIALOG_H

#include <QDialog>
// 头文件
#include <QDebug>
#include <QPixmap>    //图片类
#include <QPainter> // 画家类
#include <QKeyEvent> // 按键事件类
#include <QMessageBox> //信息弹窗类

namespace Ui {
class Dialog;
}

class Dialog : public QDialog
{
    Q_OBJECT

public:
    explicit Dialog(QWidget *parent = 0);
    ~Dialog();

    // 声明事件函数,为了覆盖事件函数  因为他们是虚函数
protected:
    void paintEvent(QPaintEvent*);//绘制事件
    void keyPressEvent(QKeyEvent*);//键盘按下事件

private:
    Ui::Dialog *ui;
};

#endif // DIALOG_H

dialog.cpp

#include "dialog.h"
#include "ui_dialog.h"

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

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

/**
 * @brief Dialog::paintEvent
 * 1. 组件从无到有,从有到无会触发
 * 2. 大小改变会触发,移动不会触发
 */
void Dialog::paintEvent(QPaintEvent *)
{
    qDebug() << width() << "*" << height(); //打印窗口的宽高
    qDebug() << x() << "," << y();           //打印窗口坐标
    QPixmap map(":/new/prefix1/yuandan.jpg");
    QPainter painter(this); // 一个在窗口上绘制的画家对象
    // 开始绘制
    /*
    参数1:绘制内容的横坐标,定位点是绘制内容的左上角
    参数2:绘制内容的纵坐标,定位点是绘制内容的左上角    
    参数3:绘制内容的宽度
    参数4:绘制内容的高度
    参数5:绘制的内容
*/
    painter.drawPixmap(0,0,width(),height(),map);
}

/**
 * @brief Dialog::keyPressEvent
 * @param event 包含当前事件的相关信息,QKeyEvent包含按键编码
 */
void Dialog::keyPressEvent(QKeyEvent * event)
{
    if(Qt::Key_A == event->key()) // 如果是A键
    {
        // 获得进度条当前数值
        int value = ui->progressBar->value();
        if(value == 0)
        {
            QMessageBox::information(this,"提示","拒绝emo");
            return;
        }
        ui->progressBar->setValue(--value);
    }else if(Qt::Key_D == event->key())
    {
        // 获得进度条当前数值
        int value = ui->progressBar->value();
        if(value == 100)
        {
            QMessageBox::information(this,"提示","快乐无边!");
            return;
        }
        ui->progressBar->setValue(++value);
    }
}

7.3 事件过滤器

事件过滤器可以在父组件对象中检测子组件对象传递的事件。

使用事件过滤器需要给监控的子组件注册事件过滤器后,在父组件对象中覆盖下面的函数。

bool QObject::eventFilter(QObject * watched, QEvent * event) [virtual protected]

参数1:被观察的子组件对象

参数2:当前检测的事件对象

返回值:是否拦截事件的传递,建议初学者不要写固定值,此处调用原基类被覆盖的函数返回值。

d9b1f0af01f5c21257cd260c12ec80a0.png

22ebabfe60f6eda2463bb6d7c605d7f3.png

Type QEvent::type() const

返回当前事件的类型

示例代码下载链接:百度网盘 请输入提取码

提取码:hqyj

--来自百度网盘超级会员V6的分享

dialog.cpp

#include "dialog.h"
#include "ui_dialog.h"

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

    // 给第一个输入框注册事件过滤器  installEventFilter安装注册使用
    ui->lineEdit->installEventFilter(this);
}

Dialog::~Dialog()
{
    delete ui;
}
//参数1:被观察的子组件对象
//参数2:当前检测的事件对象

bool Dialog::eventFilter(QObject * watched, QEvent * event)
{
    // 先判断是哪个组件,再判断当前组件的事件类型  FocusIn 获取焦点   event->type()返回当前事件的类型
    if(watched == ui->lineEdit && QEvent::FocusIn == event->type())
    {
        qDebug() << "第一个输入框获取了焦点!";
        //FocusOut 失去焦点              这个事件类型去第一个图片找
    }else if(watched == ui->lineEdit && QEvent::FocusOut == event->type())
    {
        qDebug() << "第一个输入框失去了焦点!";
    }

    // 调用基类覆盖的函数  这个函数有返回值
    return QDialog::eventFilter(watched,event);
}

dialog.h  

#ifndef DIALOG_H
#define DIALOG_H

#include <QDialog>
#include <QDebug>

namespace Ui {
class Dialog;
}

class Dialog : public QDialog
{
    Q_OBJECT

public:
    explicit Dialog(QWidget *parent = 0);
    ~Dialog();

protected:
    // 声明事件过滤器函数 bool QObject::eventFilter(QObject * watched, QEvent * event) [virtual protected]
    bool eventFilter(QObject *, QEvent *);

private:
    Ui::Dialog *ui;
};

#endif // DIALOG_H

  • 8
    点赞
  • 10
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
### 回答1: C++ GUI编程是一种通过使用C++编程语言来设计和开发图形用户界面(GUI)的技术。Qt是一个跨平台的C++图形用户界面应用程序开发框架,它提供了丰富的函数库和组件,使开发者能够快速构建出现代化的GUI应用程序。Qt 4是Qt框架的第四个版本,它拥有许多强大的特性和功能。 使用Qt 4进行C++ GUI编程可以带来许多好处。首先,Qt 4提供了丰富的界面控件和布局管理器,使开发者能够轻松地设计和布置GUI界面。其次,Qt 4支持多平台开发开发者可以使用相同的代码库在不同的操作系统上构建应用程序,如Windows、Mac和Linux等。 另外,Qt 4提供了强大的信号和槽机制,这是一种事件驱动的编程模型,通过信号和槽的连接,不同的组件之间可以实现相互的通信和交互。而且,Qt 4还提供了一套丰富的API,包括网络编程、数据库访问、图形绘制、国际化支持等功能,使开发者能够更加便捷地完成复杂的应用程序开发。 总的来说,C++ GUI编程是使用C++编程语言开发图形用户界面的技术,而Qt 4是一个优秀的C++ GUI应用程序开发框架。使用Qt 4进行C++ GUI编程可以提供丰富的控件和功能,支持多平台开发,并且具有强大的信号和槽机制,大大简化了GUI应用程序的开发过程。 ### 回答2: C++ GUI Qt 4编程(英文版)是一个面向C++语言开发者的编程指南,主要介绍了使用Qt框架进行图形用户界面(GUI)应用程序开发的方法和技巧。 Qt是一个跨平台的C++应用程序开发框架,其最新版本为Qt 6,而Qt 4是一个较老但仍广泛使用的版本。Qt提供了一套丰富的工具和类库,使开发者能够以较低的工作量创建高质量的GUI应用程序。 C++ GUI Qt 4编程(英文版)详细介绍了Qt框架的各个方面,包括窗口、对话框、按钮、标签、文本框等常见GUI元素的创建和使用。同时,它还阐述了事件处理、布局管理、国际化、数据存储等高级主题。 这本书的优势之一是它使用了英文版,因此更适合那些通过英文文档来学习编程的读者。书中提供了大量实例代码和示意图,使读者能够更好地理解和应用所学内容。 通过学习C++ GUI Qt 4编程(英文版),读者将能够掌握Qt框架的核心概念和使用方法,能够开发出效果出色、功能完善的GUI应用程序。无论是新手还是有经验的开发者,都可以从这本书中获得宝贵的知识和经验。 总的来说,C++ GUI Qt 4编程(英文版)是一本详细介绍Qt框架的编程指南,适合想要学习并能够流畅阅读英文文档的C++开发者。它为读者提供了全面的知识和实例,帮助他们掌握Qt框架并开发出高质量的GUI应用程序。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值