Qt day5 -- QmainWindow主窗口 事件 事件过滤器

一、QMainWindow

    QMenuBar:菜单栏

    QMenu: 菜单
    QAction: 动作

    QToolBar: 工具栏
    QStatusBar: 状态栏

//cpp文件(本程序只需要写cpp文件即可)

//1.创建新项目 选择MainWindow
#include "mainwindow.h"
#include <QMenuBar>  //菜单栏
#include <QMenu>     //菜单
#include <QAction>   //菜单项
#include <QToolBar>  //工具栏
#include <QDockWidget>  //浮动窗口
#include <QStatusBar>  //状态栏
#include <QTextEdit>    //文本编辑
#include <QLabel>       //标签
#include <QProgressBar> //进度条
#include <QFileDialog>  //打开文件对话框
#include <QMessageBox>  //消息提示框
#include <QFontDialog>  //字体大小种类设置框
#include <QColorDialog> //字体颜色设置框

MainWindow::MainWindow(QWidget *parent)
    : QMainWindow(parent)
{
    setWindowTitle("主窗口");
    setWindowIcon(QIcon(":/mw_images/title.png"));
    setFixedSize(1000, 800);

//2.唯一菜单栏(无图的是菜单,有图的是工具栏)
    QMenuBar *menubar = this->menuBar();

//3.增加菜单到菜单栏中
    QMenu *fileMenu = menubar->addMenu("文件");
    QMenu *editMenu = menubar->addMenu("编辑");
    QMenu *setMenu = menubar->addMenu("设置");

//4.addaction给每个菜单增加两个菜单项,并QAction *接收,后续connect拉姆达表达式绑定操作
    //addSeparator 视觉隔断
    QAction *actOpen = fileMenu->addAction(QIcon(":/mw_images/open.png"), "打开文件");
    fileMenu->addSeparator();
    QAction *actClose = fileMenu->addAction(QIcon(":/mw_images/close.png"), "关闭文件");

    QAction *actCopy = editMenu->addAction(QIcon(":/mw_images/copy.png"), "拷贝");
    editMenu->addSeparator();
    QAction *actPaste = editMenu->addAction(QIcon(":/mw_images/paste.png"), "粘贴");


    QAction *actFont = setMenu->addAction(QIcon(":/mw_images/font.png"), "设置字体");
    setMenu->addSeparator();
    QAction *actColor = setMenu->addAction(QIcon(":/mw_images/color.png"), "设置颜色");

//5.添加多个工具栏(右键可以查看工具栏名字和浮动窗口,并可设置是否可见)
    QToolBar *fileTool = this->addToolBar("打开和关闭文件");
    QToolBar *editTool = addToolBar("拷贝和粘贴");
    QToolBar *setTool = addToolBar("字体和颜色");

//6.给每个工具栏增加工具项(来自菜单的菜单项)
    fileTool->addAction(actOpen);
    fileTool->addSeparator();
    fileTool->addAction(actClose);
    fileTool->setAllowedAreas(Qt::TopToolBarArea | Qt::BottomToolBarArea);//设置上下停靠
    fileTool->setMovable(true);//设置可拖动
    fileTool->setFloatable(false);//设置不可浮动(不管拖到哪里,都会回到原位)

    editTool->addAction(actCopy);
    editTool->addSeparator();
    editTool->addAction(actPaste);//默认可拖动可浮动

    setTool->addAction(actFont);
    setTool->addSeparator();
    setTool->addAction(actColor);

//7.设置唯一中央部件(文本编辑器)
    QTextEdit *te = new QTextEdit(this);
    setCentralWidget(te);        //(this->setcentralwidget(te))

//8.设置多个浮动窗口(没详细讲干什么用的)(右键可选择是否可见 可选择脱离主窗口)
    QDockWidget *dw1 = new QDockWidget("浮动窗口", this);
    QDockWidget *dw2 = new QDockWidget("浮动窗口2", this);

//9.设置浮动窗口可停靠的区域,以及默认停靠区域
    dw1->setAllowedAreas(Qt::LeftDockWidgetArea | Qt::RightDockWidgetArea);
    this->addDockWidget(Qt::LeftDockWidgetArea, dw1);

    dw2->setAllowedAreas(Qt::TopDockWidgetArea | Qt::BottomDockWidgetArea | Qt::RightDockWidgetArea);
    this->addDockWidget(Qt::RightDockWidgetArea, dw2);

//10.设置唯一状态栏(主窗口下方的状态栏,添加一个label,一个progress进度条)
    QLabel *lb = new QLabel(this);
    lb->setText("没有文件被打开");
    QProgressBar *prgBar = new QProgressBar(this);//进度条
    prgBar->setValue(0);

    QStatusBar *staBar = this->statusBar();
    staBar->addWidget(lb);
    staBar->addWidget(prgBar);

//11.connect QAction *项(菜单项、工具项)和拉姆达表达式
//11.1打开文件(QFileDialog::getOpenFileName())
    connect(actOpen, &QAction::triggered, [=](){
        QString fileName = QFileDialog::getOpenFileName(this, "打开文本文件", ".", "文本文件 (*.h *.cpp *.txt)");            //打开文件的弹出框
        if (fileName.isEmpty())
        {
            QMessageBox::information(this, "文件选择错误", "没有文件被选中");
            return;
        }                         //选择文件为空的消息提示框

        te->setText(fileName);//中央部件(文本编辑器)内容更新
        lb->setText(fileName + "被打开");//状态栏更新
        prgBar->setValue(55);//设置进度条为55
    });

//11.2关闭文件(清除文本编辑器的内容,更新状态栏)
    connect(actClose, &QAction::triggered, [=](){
        te->clear();
        lb->setText("没有文件被打开");
        prgBar->setValue(0);
    });

//11.3 拷贝、粘贴内容
    connect(actCopy, &QAction::triggered, te, &QTextEdit::copy);
    connect(actPaste, &QAction::triggered, te, &QTextEdit::paste);

//    connect(actCopy, &QAction::triggered, [=](){
//        te->copy();
//    });
//    connect(actPaste, &QAction::triggered, [=](){
//        te->paste();
//    });

//11.4 设置字体大小和种类(打开字体选择框   缺点是只能全部设置为相同字体)
        connect(actFont, &QAction::triggered, [=](){
        bool isOk;
        QFont font = QFontDialog::getFont(&isOk);
        if (isOk)    //字体选择框的OK 表示确认
        {
            te->setFont(font);
        }
    });

//11.5  设置字体颜色
    connect(actColor, &QAction::triggered, [=](){
        QColor color = QColorDialog::getColor();
        te->setTextColor(color);
    });
}
    

效果展示 

二、事件

两种虚函数:事件处理的统一入口bool event(QEvent *event)   特定事件处理入口
        bool event(QEvent *event);        //事件处理的统一的入口
        void mousePressEvent(QMouseEvent *e);  --- 鼠标按下事件   //特定事件处理器

widget.h:

#ifndef WIDGET_H
#define WIDGET_H

#include <QWidget>    
#include <QEvent>        //事件
#include <QMouseEvent>   //鼠标事件(左右点击、双击、滚动、移动...)
#include <QWheelEvent>   //滚轮滚动事件
#include <QKeyEvent>     //键盘事件
#include <QTimerEvent>   //定时器事件
#include <QPaintEvent>   //绘图事件(窗口大小改变 内容改变)

class Widget : public QWidget
{
    Q_OBJECT

public:
    Widget(QWidget *parent = 0);
    ~Widget();


    //事件的总入口    //重写事件处理器
    bool event(QEvent *event);


    //鼠标相关的特定事件    //重写特定的事件处理器
    void mousePressEvent(QMouseEvent *event); //鼠标点击按下事件
    void mouseReleaseEvent(QMouseEvent *event); //鼠标释放的事件
    void mouseMoveEvent(QMouseEvent *event); //鼠标移动的事件
    void mouseDoubleClickEvent(QMouseEvent *event); //鼠标双击的事件
    void wheelEvent(QWheelEvent *event); //滚轮的事件

    //键盘相关的特定事件
    void keyPressEvent(QKeyEvent *event);
    void keyReleaseEvent(QKeyEvent *event);

    //定时器事件
    void timerEvent(QTimerEvent *event);

    //绘图事件
    void paintEvent(QPaintEvent *event);

};

#endif // WIDGET_H

widget.cpp:

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

Widget::Widget(QWidget *parent)
    : QWidget(parent)
{   
    startTimer(3000);//QWidget类自带定时器
}

Widget::~Widget()
{

}

//重写事件函数的定义
//1.事件总入口
bool Widget::event(QEvent *event)
{
//举例在总入口处理几个事件
    if (event->type() == QEvent::MouseButtonPress)
    {
        qDebug() << "event(鼠标点击事件)";
        //return false;
    }
    else if (event->type() == QEvent::KeyPress)
    {
        qDebug() << "event(键盘按下事件)";
    }
    else if (event->type() == QEvent::Timer)
    {
        qDebug() << "event(定时器超时事件)";
    }

    //为了不影响原有的行为,需要调用基类的event()函数
    return QWidget::event(event);    //写了这个才能执行特殊事件处理,表示该怎么处理怎么处理
}
//2.特定的事件处理器
//2.1鼠标相关的特定事件
void Widget::mousePressEvent(QMouseEvent *event) //鼠标点击按下事件
{
    qDebug() << "mousePressEvent()";
    qDebug() << event->pos();    //表示在窗口中的位置
//    qDebug() << event->x();
//    qDebug() << event->y();
//    qDebug() << event->globalPos();    //表示在电脑屏幕中的位置
//    qDebug() << event->globalX();
//    qDebug() << event->globalY();
    if (event->button() == Qt::LeftButton)    //event的button事件  Qt的leftbutton事件
    {
        qDebug() << "左键";
    }
    else if (event->button() == Qt::RightButton)
    {
         qDebug() << "右键";
    }
    else if (event->button() == Qt::MiddleButton)
    {
         qDebug() << "中键";
    }
}

//2.2鼠标释放和鼠标移动
void Widget::mouseReleaseEvent(QMouseEvent *event) //鼠标释放的事件
{
    qDebug() << "mouseReleaseEvent()";
    qDebug() << event->pos();
}
void Widget::mouseMoveEvent(QMouseEvent *event) //鼠标移动的事件
{
    qDebug() << "mouseMoveEvent()";
    qDebug() << event->pos();
}

//2.3鼠标双击
void Widget::mouseDoubleClickEvent(QMouseEvent *event)//鼠标双击的事件
{
    qDebug() << "mouseDoubleClickEvent()";
    qDebug() << event->pos();
    if (event->button() == Qt::LeftButton)
    {
        qDebug() << "左键双击";
    }
    else if (event->button() == Qt::RightButton)
    {
         qDebug() << "右键双击";
    }
    else if (event->button() == Qt::MiddleButton)
    {
         qDebug() << "中键双击";
    }
}

//2.4滚轮
void Widget::wheelEvent(QWheelEvent *event) //滚轮的事件
{
    qDebug() << "wheelEvent()";
    qDebug() << event->pos();
    qDebug() << event->delta();
}

//2.5键盘
void Widget::keyPressEvent(QKeyEvent *event)
{
    qDebug() << "keyPressEvent";
    qDebug() << (char)event->key();
}
void Widget::keyReleaseEvent(QKeyEvent *event)
{
    qDebug() << "keyReleaseEvent";
    qDebug() << (char)event->key();
}

//2.6 定时器
void Widget::timerEvent(QTimerEvent *event)
{
    qDebug() << "timerEvent";
}

//2.7 绘图
void Widget::paintEvent(QPaintEvent *event)
{
    static int i = 0;
    qDebug() << "paintEvent" << i++;
}

效果展示

三、事件过滤器

    1) 安装事件过滤器
        le->installEventFilter(this);  //从QObject继承出来的对象,可以注册一个事件过滤器,所有的事件先交给事件过滤器处理

    2) 重写事件过滤器

 bool eventFilter(QObject *watched, QEvent *event);

    /*
    参数: 
        watched: 对象
        event: 事件
    返回值:
        true: 事件已处理
        false: 事件未处理
    */

widget.h:

        public里多加一个bool eventFilter(QObject *watched, QEvent *event);

widget.cpp:

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

Widget::Widget(QWidget *parent) :
    QWidget(parent),
    ui(new Ui::Widget)
{
    ui->setupUi(this);
    setWindowTitle("事件过滤器");

    //1.使用事件过滤器的第一步:给le_input安装事件过滤器,凡是到达te_input的事件,都先委托给主窗口先去处理
    //te_input是委托方;主窗口是被委托方
    ui->te_input->installEventFilter(this);

    //2.事件过滤器使用的第二步,重新被委托方的事件过滤器
    //true 表示对该事件的处理完毕,false 表示对该事件处理没有完
bool Widget::eventFilter(QObject *watched, QEvent *event)
{
    if (event->type() == QEvent::KeyPress)    //event->type()判断事件类型是否为键盘
    {
        QKeyEvent *tmp = static_cast<QKeyEvent*>(event);    //强转(大转小),方便后续判断
        if (tmp->key() <= Qt::Key_9 && tmp->key() >= Qt::Key_0)
        {
            QString s1 = ui->te_output_1->toPlainText();
            s1 += QString(tmp->key());        //QString的+=使用
            ui->te_output_1->setText(s1);     //ui指针别忘了加
            //return true;                    //是否return表示是否不把字符打印在过滤前文本
        }
        else if (tmp->key() <= Qt::Key_Z && tmp->key() >= Qt::Key_A)
        {
            QString s1 = ui->te_output_2->toPlainText();
            s1 += QString(tmp->key());
            ui->te_output_2->setText(s1);
            return true;
        }
        else if (tmp->key() == Qt::Key_Tab)
        {
            ui->te_output_1->clear();
            return true;
        }
        else if (tmp->key() == Qt::Key_Shift)
        {
            ui->te_output_2->clear();
            return true;
        }
    }

    //对于不感兴趣的事件,继续调用基类的事件过滤器,维持原有的行为
    QWidget::eventFilter(watched, event);
}

  • 9
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值